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.
This commit is contained in:
parent
8aec50a275
commit
060332c704
|
@ -48,7 +48,8 @@ pub struct Crds {
|
||||||
cursor: Cursor, // Next insert ordinal location.
|
cursor: Cursor, // Next insert ordinal location.
|
||||||
shards: CrdsShards,
|
shards: CrdsShards,
|
||||||
nodes: IndexSet<usize>, // Indices of nodes' ContactInfo.
|
nodes: IndexSet<usize>, // Indices of nodes' ContactInfo.
|
||||||
votes: IndexSet<usize>, // Indices of Vote crds values.
|
// Indices of Votes keyed by insert order.
|
||||||
|
votes: BTreeMap<u64 /*insert order*/, usize /*index*/>,
|
||||||
// Indices of EpochSlots keyed by insert order.
|
// Indices of EpochSlots keyed by insert order.
|
||||||
epoch_slots: BTreeMap<u64 /*insert order*/, usize /*index*/>,
|
epoch_slots: BTreeMap<u64 /*insert order*/, usize /*index*/>,
|
||||||
// Indices of all crds values associated with a node.
|
// Indices of all crds values associated with a node.
|
||||||
|
@ -111,7 +112,7 @@ impl Default for Crds {
|
||||||
cursor: Cursor::default(),
|
cursor: Cursor::default(),
|
||||||
shards: CrdsShards::new(CRDS_SHARDS_BITS),
|
shards: CrdsShards::new(CRDS_SHARDS_BITS),
|
||||||
nodes: IndexSet::default(),
|
nodes: IndexSet::default(),
|
||||||
votes: IndexSet::default(),
|
votes: BTreeMap::default(),
|
||||||
epoch_slots: BTreeMap::default(),
|
epoch_slots: BTreeMap::default(),
|
||||||
records: HashMap::default(),
|
records: HashMap::default(),
|
||||||
entries: BTreeMap::default(),
|
entries: BTreeMap::default(),
|
||||||
|
@ -172,7 +173,7 @@ impl Crds {
|
||||||
self.nodes.insert(entry_index);
|
self.nodes.insert(entry_index);
|
||||||
}
|
}
|
||||||
CrdsData::Vote(_, _) => {
|
CrdsData::Vote(_, _) => {
|
||||||
self.votes.insert(entry_index);
|
self.votes.insert(value.ordinal, entry_index);
|
||||||
}
|
}
|
||||||
CrdsData::EpochSlots(_, _) => {
|
CrdsData::EpochSlots(_, _) => {
|
||||||
self.epoch_slots.insert(value.ordinal, entry_index);
|
self.epoch_slots.insert(value.ordinal, entry_index);
|
||||||
|
@ -189,10 +190,17 @@ impl Crds {
|
||||||
let entry_index = entry.index();
|
let entry_index = entry.index();
|
||||||
self.shards.remove(entry_index, entry.get());
|
self.shards.remove(entry_index, entry.get());
|
||||||
self.shards.insert(entry_index, &value);
|
self.shards.insert(entry_index, &value);
|
||||||
if let CrdsData::EpochSlots(_, _) = value.value.data {
|
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.remove(&entry.get().ordinal);
|
||||||
self.epoch_slots.insert(value.ordinal, entry_index);
|
self.epoch_slots.insert(value.ordinal, entry_index);
|
||||||
}
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
self.entries.remove(&entry.get().ordinal);
|
self.entries.remove(&entry.get().ordinal);
|
||||||
self.entries.insert(value.ordinal, entry_index);
|
self.entries.insert(value.ordinal, entry_index);
|
||||||
// As long as the pubkey does not change, self.records
|
// As long as the pubkey does not change, self.records
|
||||||
|
@ -253,15 +261,10 @@ impl Crds {
|
||||||
&'a self,
|
&'a self,
|
||||||
cursor: &'a mut Cursor,
|
cursor: &'a mut Cursor,
|
||||||
) -> impl Iterator<Item = &'a VersionedCrdsValue> {
|
) -> impl Iterator<Item = &'a VersionedCrdsValue> {
|
||||||
let since = cursor.ordinal();
|
let range = (Bound::Included(cursor.ordinal()), Bound::Unbounded);
|
||||||
self.votes.iter().filter_map(move |i| {
|
self.votes.range(range).map(move |(ordinal, index)| {
|
||||||
let entry = self.table.index(*i);
|
cursor.consume(*ordinal);
|
||||||
if entry.ordinal >= since {
|
self.table.index(*index)
|
||||||
cursor.consume(entry.ordinal);
|
|
||||||
Some(entry)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,7 +410,7 @@ impl Crds {
|
||||||
self.nodes.swap_remove(&index);
|
self.nodes.swap_remove(&index);
|
||||||
}
|
}
|
||||||
CrdsData::Vote(_, _) => {
|
CrdsData::Vote(_, _) => {
|
||||||
self.votes.swap_remove(&index);
|
self.votes.remove(&value.ordinal);
|
||||||
}
|
}
|
||||||
CrdsData::EpochSlots(_, _) => {
|
CrdsData::EpochSlots(_, _) => {
|
||||||
self.epoch_slots.remove(&value.ordinal);
|
self.epoch_slots.remove(&value.ordinal);
|
||||||
|
@ -441,8 +444,7 @@ impl Crds {
|
||||||
self.nodes.insert(index);
|
self.nodes.insert(index);
|
||||||
}
|
}
|
||||||
CrdsData::Vote(_, _) => {
|
CrdsData::Vote(_, _) => {
|
||||||
self.votes.swap_remove(&size);
|
self.votes.insert(value.ordinal, index);
|
||||||
self.votes.insert(index);
|
|
||||||
}
|
}
|
||||||
CrdsData::EpochSlots(_, _) => {
|
CrdsData::EpochSlots(_, _) => {
|
||||||
self.epoch_slots.insert(value.ordinal, index);
|
self.epoch_slots.insert(value.ordinal, index);
|
||||||
|
|
Loading…
Reference in New Issue