cometbft_light_client/store/
memory.rs1use std::collections::{btree_map::Entry::*, BTreeMap};
4
5use crate::{
6 store::{LightStore, Status},
7 verifier::types::{Height, LightBlock},
8};
9
10#[derive(Clone, Debug, PartialEq)]
12struct StoreEntry {
13 light_block: LightBlock,
14 status: Status,
15}
16
17impl StoreEntry {
18 fn new(light_block: LightBlock, status: Status) -> Self {
19 Self {
20 light_block,
21 status,
22 }
23 }
24}
25
26#[derive(Debug, Clone, Default)]
28pub struct MemoryStore {
29 store: BTreeMap<Height, StoreEntry>,
30}
31
32impl MemoryStore {
33 pub fn new() -> Self {
35 Self {
36 store: BTreeMap::new(),
37 }
38 }
39}
40
41impl LightStore for MemoryStore {
42 fn get(&self, height: Height, status: Status) -> Option<LightBlock> {
43 self.store
44 .get(&height)
45 .filter(|e| e.status == status)
46 .cloned()
47 .map(|e| e.light_block)
48 }
49
50 fn insert(&mut self, light_block: LightBlock, status: Status) {
51 self.store
52 .insert(light_block.height(), StoreEntry::new(light_block, status));
53 }
54
55 fn remove(&mut self, height: Height, status: Status) {
56 if let Occupied(e) = self.store.entry(height) {
57 if e.get().status == status {
58 e.remove_entry();
59 }
60 }
61 }
62
63 fn update(&mut self, light_block: &LightBlock, status: Status) {
64 self.insert(light_block.clone(), status);
65 }
66
67 fn highest(&self, status: Status) -> Option<LightBlock> {
68 self.store
69 .iter()
70 .filter(|(_, e)| e.status == status)
71 .max_by_key(|(&height, _)| height)
72 .map(|(_, e)| e.light_block.clone())
73 }
74
75 fn highest_before(&self, height: Height, status: Status) -> Option<LightBlock> {
76 self.store
77 .iter()
78 .filter(|(_, e)| e.status == status)
79 .filter(|(h, _)| h <= &&height)
80 .max_by_key(|(&height, _)| height)
81 .map(|(_, e)| e.light_block.clone())
82 }
83
84 fn lowest(&self, status: Status) -> Option<LightBlock> {
85 self.store
86 .iter()
87 .filter(|(_, e)| e.status == status)
88 .min_by_key(|(&height, _)| height)
89 .map(|(_, e)| e.light_block.clone())
90 }
91
92 #[allow(clippy::needless_collect)]
93 fn all(&self, status: Status) -> Box<dyn Iterator<Item = LightBlock>> {
94 let light_blocks: Vec<_> = self
95 .store
96 .iter()
97 .filter(|(_, e)| e.status == status)
98 .map(|(_, e)| e.light_block.clone())
99 .collect();
100
101 Box::new(light_blocks.into_iter())
102 }
103}