sim_kernel/
datum_store.rs1use std::collections::BTreeMap;
7
8use crate::{datum::Datum, error::Result, ref_id::ContentId};
9
10pub trait DatumStore {
15 fn intern(&mut self, datum: Datum) -> Result<ContentId>;
18 fn get(&self, id: &ContentId) -> Result<Option<&Datum>>;
20 fn contains(&self, id: &ContentId) -> bool;
22}
23
24#[derive(Clone, Debug, Default)]
26pub struct BTreeDatumStore {
27 data: BTreeMap<ContentId, Datum>,
28}
29
30impl BTreeDatumStore {
31 pub fn new() -> Self {
33 Self::default()
34 }
35
36 pub(crate) fn insert_known(&mut self, id: ContentId, datum: Datum) -> Option<Datum> {
37 self.data.insert(id, datum)
38 }
39
40 pub fn len(&self) -> usize {
42 self.data.len()
43 }
44
45 pub fn is_empty(&self) -> bool {
47 self.data.is_empty()
48 }
49}
50
51impl DatumStore for BTreeDatumStore {
52 fn intern(&mut self, datum: Datum) -> Result<ContentId> {
53 let id = datum.content_id()?;
54 self.data.entry(id.clone()).or_insert(datum);
55 Ok(id)
56 }
57
58 fn get(&self, id: &ContentId) -> Result<Option<&Datum>> {
59 Ok(self.data.get(id))
60 }
61
62 fn contains(&self, id: &ContentId) -> bool {
63 self.data.contains_key(id)
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use crate::{Datum, Symbol, datum_content_algorithm};
70
71 use super::*;
72
73 #[test]
74 fn datum_store_intern_followed_by_get_returns_original_datum() {
75 let mut store = BTreeDatumStore::new();
76 let datum = Datum::String("stored".to_owned());
77
78 let id = store.intern(datum.clone()).unwrap();
79
80 assert_eq!(store.get(&id).unwrap(), Some(&datum));
81 assert!(store.contains(&id));
82 }
83
84 #[test]
85 fn datum_store_unresolved_external_content_ids_return_none() {
86 let store = BTreeDatumStore::new();
87 let id = ContentId::from_bytes(datum_content_algorithm(), [9; 32]);
88
89 assert_eq!(store.get(&id).unwrap(), None);
90 assert!(!store.contains(&id));
91 }
92
93 #[test]
94 fn datum_store_intern_reuses_equal_content_id() {
95 let mut store = BTreeDatumStore::new();
96 let left = Datum::Symbol(Symbol::new("same"));
97 let right = Datum::Symbol(Symbol::new("same"));
98
99 let left_id = store.intern(left).unwrap();
100 let right_id = store.intern(right).unwrap();
101
102 assert_eq!(left_id, right_id);
103 assert_eq!(store.len(), 1);
104 }
105}