Skip to content

Commit a9c19ee

Browse files
authored
interface: Optimize the StakeHistory::get function (#81)
`StakeHistory::get` was performing a binary search for every requested epoch. Given that the stake history is contigous and ordered starting from the latest epochs, we don't to binary search. We can derive the index by looking up the latest element's epoch and subtracting the requested epoch from it.
1 parent 0d5ab1d commit a9c19ee

File tree

1 file changed

+19
-13
lines changed

1 file changed

+19
-13
lines changed

interface/src/stake_history.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,15 @@ impl std::ops::Add for StakeHistoryEntry {
6666
pub struct StakeHistory(Vec<(Epoch, StakeHistoryEntry)>);
6767

6868
impl StakeHistory {
69+
#[inline]
70+
fn latest_epoch(&self) -> Option<&Epoch> {
71+
self.first().map(|(epoch, _)| epoch)
72+
}
73+
6974
pub fn get(&self, epoch: Epoch) -> Option<&StakeHistoryEntry> {
70-
self.binary_search_by(|probe| epoch.cmp(&probe.0))
71-
.ok()
72-
.map(|index| &self[index].1)
75+
self.latest_epoch()
76+
.and_then(|latest| latest.checked_sub(epoch))
77+
.and_then(|index| self.0.get(index as usize).map(|(_, entry)| entry))
7378
}
7479

7580
pub fn add(&mut self, epoch: Epoch, entry: StakeHistoryEntry) {
@@ -94,9 +99,7 @@ pub trait StakeHistoryGetEntry {
9499

95100
impl StakeHistoryGetEntry for StakeHistory {
96101
fn get_entry(&self, epoch: Epoch) -> Option<StakeHistoryEntry> {
97-
self.binary_search_by(|probe| epoch.cmp(&probe.0))
98-
.ok()
99-
.map(|index| self[index].1.clone())
102+
self.get(epoch).map(|entry| entry.to_owned())
100103
}
101104
}
102105

@@ -120,13 +123,16 @@ mod tests {
120123
assert_eq!(stake_history.len(), MAX_ENTRIES);
121124
assert_eq!(stake_history.iter().map(|entry| entry.0).min().unwrap(), 1);
122125
assert_eq!(stake_history.get(0), None);
123-
assert_eq!(
124-
stake_history.get(1),
125-
Some(&StakeHistoryEntry {
126-
activating: 1,
127-
..StakeHistoryEntry::default()
128-
})
129-
);
126+
for i in 0..MAX_ENTRIES {
127+
let epoch = (i + 1) as u64;
128+
assert_eq!(
129+
stake_history.get(epoch),
130+
Some(&StakeHistoryEntry {
131+
activating: epoch,
132+
..StakeHistoryEntry::default()
133+
})
134+
);
135+
}
130136
}
131137

132138
#[test]

0 commit comments

Comments
 (0)