From 060332c704a7ed5284028154e1bd61ecbd9fb839 Mon Sep 17 00:00:00 2001 From: behzad nouri Date: Mon, 24 May 2021 13:35:01 +0000 Subject: [PATCH] indexes crds votes by insert order (#17340) Crds::get_votes is scanning over all votes in the crds table only to return those inserted since the given cursor: https://github.com/solana-labs/solana/blob/2ae57c172/core/src/crds.rs#L250-L266 Having votes indexed by insert order avoids the table scan and will be more efficient. --- core/src/crds.rs | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/core/src/crds.rs b/core/src/crds.rs index c5e231ae30..480c953a81 100644 --- a/core/src/crds.rs +++ b/core/src/crds.rs @@ -48,7 +48,8 @@ pub struct Crds { cursor: Cursor, // Next insert ordinal location. shards: CrdsShards, nodes: IndexSet, // Indices of nodes' ContactInfo. - votes: IndexSet, // Indices of Vote crds values. + // Indices of Votes keyed by insert order. + votes: BTreeMap, // Indices of EpochSlots keyed by insert order. epoch_slots: BTreeMap, // Indices of all crds values associated with a node. @@ -111,7 +112,7 @@ impl Default for Crds { cursor: Cursor::default(), shards: CrdsShards::new(CRDS_SHARDS_BITS), nodes: IndexSet::default(), - votes: IndexSet::default(), + votes: BTreeMap::default(), epoch_slots: BTreeMap::default(), records: HashMap::default(), entries: BTreeMap::default(), @@ -172,7 +173,7 @@ impl Crds { self.nodes.insert(entry_index); } CrdsData::Vote(_, _) => { - self.votes.insert(entry_index); + self.votes.insert(value.ordinal, entry_index); } CrdsData::EpochSlots(_, _) => { self.epoch_slots.insert(value.ordinal, entry_index); @@ -189,9 +190,16 @@ impl Crds { let entry_index = entry.index(); self.shards.remove(entry_index, entry.get()); self.shards.insert(entry_index, &value); - if let CrdsData::EpochSlots(_, _) = value.value.data { - self.epoch_slots.remove(&entry.get().ordinal); - self.epoch_slots.insert(value.ordinal, entry_index); + match value.value.data { + CrdsData::Vote(_, _) => { + self.votes.remove(&entry.get().ordinal); + self.votes.insert(value.ordinal, entry_index); + } + CrdsData::EpochSlots(_, _) => { + self.epoch_slots.remove(&entry.get().ordinal); + self.epoch_slots.insert(value.ordinal, entry_index); + } + _ => (), } self.entries.remove(&entry.get().ordinal); self.entries.insert(value.ordinal, entry_index); @@ -253,15 +261,10 @@ impl Crds { &'a self, cursor: &'a mut Cursor, ) -> impl Iterator { - let since = cursor.ordinal(); - self.votes.iter().filter_map(move |i| { - let entry = self.table.index(*i); - if entry.ordinal >= since { - cursor.consume(entry.ordinal); - Some(entry) - } else { - None - } + let range = (Bound::Included(cursor.ordinal()), Bound::Unbounded); + self.votes.range(range).map(move |(ordinal, index)| { + cursor.consume(*ordinal); + self.table.index(*index) }) } @@ -407,7 +410,7 @@ impl Crds { self.nodes.swap_remove(&index); } CrdsData::Vote(_, _) => { - self.votes.swap_remove(&index); + self.votes.remove(&value.ordinal); } CrdsData::EpochSlots(_, _) => { self.epoch_slots.remove(&value.ordinal); @@ -441,8 +444,7 @@ impl Crds { self.nodes.insert(index); } CrdsData::Vote(_, _) => { - self.votes.swap_remove(&size); - self.votes.insert(index); + self.votes.insert(value.ordinal, index); } CrdsData::EpochSlots(_, _) => { self.epoch_slots.insert(value.ordinal, index);