Skip to content

Commit 1b64360

Browse files
committed
interface: Optimize the StakeHistory::get function
`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 68217e1 commit 1b64360

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

interface/src/stake_history.rs

Lines changed: 18 additions & 10 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) {
@@ -120,12 +125,15 @@ mod tests {
120125
assert_eq!(stake_history.len(), MAX_ENTRIES);
121126
assert_eq!(stake_history.iter().map(|entry| entry.0).min().unwrap(), 1);
122127
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-
);
128+
for i in 0..MAX_ENTRIES {
129+
let epoch = (i + 1) as u64;
130+
assert_eq!(
131+
stake_history.get(epoch),
132+
Some(&StakeHistoryEntry {
133+
activating: epoch,
134+
..StakeHistoryEntry::default()
135+
})
136+
);
137+
}
130138
}
131139
}

0 commit comments

Comments
 (0)