SortedStorages holds HashMap instead of Vec (#29632)
* SortedStorages holds HashMap instead of Vec * add comment
This commit is contained in:
parent
4b93fa85c2
commit
0e19b9c849
|
@ -3,17 +3,20 @@ use {
|
||||||
log::*,
|
log::*,
|
||||||
solana_measure::measure::Measure,
|
solana_measure::measure::Measure,
|
||||||
solana_sdk::clock::Slot,
|
solana_sdk::clock::Slot,
|
||||||
std::ops::{Bound, Range, RangeBounds},
|
std::{
|
||||||
|
collections::HashMap,
|
||||||
|
ops::{Bound, Range, RangeBounds},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Provide access to SnapshotStorages sorted by slot
|
/// Provide access to SnapshotStorageOnes sorted by slot
|
||||||
pub struct SortedStorages<'a> {
|
pub struct SortedStorages<'a> {
|
||||||
/// range of slots where storages exist (likely sparse)
|
/// range of slots where storages exist (likely sparse)
|
||||||
range: Range<Slot>,
|
range: Range<Slot>,
|
||||||
/// the actual storages. index is (slot - range.start)
|
/// the actual storages
|
||||||
storages: Vec<Option<&'a SnapshotStorageOne>>,
|
/// A HashMap allows sparse storage and fast lookup of Slot -> Storage.
|
||||||
slot_count: usize,
|
/// We expect ~432k slots.
|
||||||
storage_count: usize,
|
storages: HashMap<Slot, &'a SnapshotStorageOne>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> SortedStorages<'a> {
|
impl<'a> SortedStorages<'a> {
|
||||||
|
@ -21,9 +24,7 @@ impl<'a> SortedStorages<'a> {
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
SortedStorages {
|
SortedStorages {
|
||||||
range: Range::default(),
|
range: Range::default(),
|
||||||
storages: Vec::default(),
|
storages: HashMap::default(),
|
||||||
slot_count: 0,
|
|
||||||
storage_count: 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,12 +37,7 @@ impl<'a> SortedStorages<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get(&self, slot: Slot) -> Option<&SnapshotStorageOne> {
|
fn get(&self, slot: Slot) -> Option<&SnapshotStorageOne> {
|
||||||
if !self.range.contains(&slot) {
|
self.storages.get(&slot).copied()
|
||||||
None
|
|
||||||
} else {
|
|
||||||
let index = (slot - self.range.start) as usize;
|
|
||||||
self.storages[index]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn range_width(&self) -> Slot {
|
pub fn range_width(&self) -> Slot {
|
||||||
|
@ -57,11 +53,11 @@ impl<'a> SortedStorages<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn slot_count(&self) -> usize {
|
pub fn slot_count(&self) -> usize {
|
||||||
self.slot_count
|
self.storages.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn storage_count(&self) -> usize {
|
pub fn storage_count(&self) -> usize {
|
||||||
self.storage_count
|
self.storages.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
// assumptions:
|
// assumptions:
|
||||||
|
@ -113,31 +109,24 @@ impl<'a> SortedStorages<'a> {
|
||||||
time.stop();
|
time.stop();
|
||||||
let mut time2 = Measure::start("sort");
|
let mut time2 = Measure::start("sort");
|
||||||
let range;
|
let range;
|
||||||
let mut storages;
|
let mut storages = HashMap::default();
|
||||||
if min > max {
|
if min > max {
|
||||||
range = Range::default();
|
range = Range::default();
|
||||||
storages = vec![];
|
|
||||||
} else {
|
} else {
|
||||||
range = Range {
|
range = Range {
|
||||||
start: min,
|
start: min,
|
||||||
end: max,
|
end: max,
|
||||||
};
|
};
|
||||||
let len = max - min;
|
|
||||||
storages = vec![None; len as usize];
|
|
||||||
source.for_each(|(original_storages, slot)| {
|
source.for_each(|(original_storages, slot)| {
|
||||||
let index = (slot - min) as usize;
|
assert!(
|
||||||
assert!(storages[index].is_none(), "slots are not unique"); // we should not encounter the same slot twice
|
storages.insert(slot, original_storages).is_none(),
|
||||||
storages[index] = Some(original_storages);
|
"slots are not unique"
|
||||||
|
); // we should not encounter the same slot twice
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
time2.stop();
|
time2.stop();
|
||||||
debug!("SortedStorages, times: {}, {}", time.as_us(), time2.as_us());
|
debug!("SortedStorages, times: {}, {}", time.as_us(), time2.as_us());
|
||||||
Self {
|
Self { range, storages }
|
||||||
range,
|
|
||||||
storages,
|
|
||||||
slot_count,
|
|
||||||
storage_count,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,22 +202,16 @@ pub mod tests {
|
||||||
};
|
};
|
||||||
impl<'a> SortedStorages<'a> {
|
impl<'a> SortedStorages<'a> {
|
||||||
pub fn new_debug(source: &[(&'a SnapshotStorageOne, Slot)], min: Slot, len: usize) -> Self {
|
pub fn new_debug(source: &[(&'a SnapshotStorageOne, Slot)], min: Slot, len: usize) -> Self {
|
||||||
let mut storages = vec![None; len];
|
let mut storages = HashMap::default();
|
||||||
let range = Range {
|
let range = Range {
|
||||||
start: min,
|
start: min,
|
||||||
end: min + len as Slot,
|
end: min + len as Slot,
|
||||||
};
|
};
|
||||||
let slot_count = source.len();
|
|
||||||
for (storage, slot) in source {
|
for (storage, slot) in source {
|
||||||
storages[*slot as usize] = Some(*storage);
|
storages.insert(*slot, *storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self { range, storages }
|
||||||
range,
|
|
||||||
storages,
|
|
||||||
slot_count,
|
|
||||||
storage_count: 0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_for_tests(storages: &[&'a SnapshotStorageOne], slots: &[Slot]) -> Self {
|
pub fn new_for_tests(storages: &[&'a SnapshotStorageOne], slots: &[Slot]) -> Self {
|
||||||
|
@ -350,7 +333,7 @@ pub mod tests {
|
||||||
fn test_sorted_storages_none() {
|
fn test_sorted_storages_none() {
|
||||||
let result = SortedStorages::empty();
|
let result = SortedStorages::empty();
|
||||||
assert_eq!(result.range, Range::default());
|
assert_eq!(result.range, Range::default());
|
||||||
assert_eq!(result.slot_count, 0);
|
assert_eq!(result.slot_count(), 0);
|
||||||
assert_eq!(result.storages.len(), 0);
|
assert_eq!(result.storages.len(), 0);
|
||||||
assert!(result.get(0).is_none());
|
assert!(result.get(0).is_none());
|
||||||
}
|
}
|
||||||
|
@ -368,7 +351,7 @@ pub mod tests {
|
||||||
end: slot + 1
|
end: slot + 1
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
assert_eq!(result.slot_count, 1);
|
assert_eq!(result.slot_count(), 1);
|
||||||
assert_eq!(result.storages.len(), 1);
|
assert_eq!(result.storages.len(), 1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.get(slot).unwrap().append_vec_id(),
|
result.get(slot).unwrap().append_vec_id(),
|
||||||
|
@ -402,8 +385,8 @@ pub mod tests {
|
||||||
end: slots[1] + 1,
|
end: slots[1] + 1,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
assert_eq!(result.slot_count, 2);
|
assert_eq!(result.slot_count(), 2);
|
||||||
assert_eq!(result.storages.len() as Slot, slots[1] - slots[0] + 1);
|
assert_eq!(result.storages.len(), 2);
|
||||||
assert!(result.get(0).is_none());
|
assert!(result.get(0).is_none());
|
||||||
assert!(result.get(3).is_none());
|
assert!(result.get(3).is_none());
|
||||||
assert!(result.get(5).is_none());
|
assert!(result.get(5).is_none());
|
||||||
|
|
Loading…
Reference in New Issue