use std::collections::BTreeMap;
use std::ops::Bound;
#[derive(Debug, Default, Clone)]
pub struct MemStore {
data: BTreeMap<Vec<u8>, Option<Vec<u8>>>,
}
impl MemStore {
pub fn new() -> Self {
Self {
data: BTreeMap::new(),
}
}
pub fn insert(&mut self, key: Vec<u8>, value: Option<Vec<u8>>) {
self.data.insert(key, value);
}
pub fn delete(&mut self, key: &[u8]) -> bool {
self.data.remove(key).is_some()
}
pub fn get(&self, key: &[u8]) -> Option<&Option<Vec<u8>>> {
self.data.get(key)
}
pub fn range_scan(&self, low: &[u8], high: &[u8]) -> Vec<(Vec<u8>, Option<Vec<u8>>)> {
self.data
.range((Bound::Included(low.to_vec()), Bound::Included(high.to_vec())))
.map(|(k, v)| (k.clone(), v.clone()))
.collect()
}
pub fn iter(&self) -> impl Iterator<Item = (Vec<u8>, Option<Vec<u8>>)> + '_ {
self.data.iter().map(|(k, v)| (k.clone(), v.clone()))
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn clear(&mut self) {
self.data.clear();
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_insert_get_delete() {
let mut s = MemStore::new();
s.insert(b"a".to_vec(), Some(b"1".to_vec()));
assert_eq!(s.get(b"a"), Some(&Some(b"1".to_vec())));
s.insert(b"a".to_vec(), None);
assert_eq!(s.get(b"a"), Some(&None));
assert!(s.delete(b"a"));
assert_eq!(s.get(b"a"), None);
}
#[test]
fn test_range_scan_order() {
let mut s = MemStore::new();
s.insert(b"a\x00\x00\x00\x00\x00\x00\x00\x01".to_vec(), Some(b"v1".to_vec()));
s.insert(b"a\x00\x00\x00\x00\x00\x00\x00\x02".to_vec(), Some(b"v2".to_vec()));
s.insert(b"b\x00\x00\x00\x00\x00\x00\x00\x01".to_vec(), Some(b"x".to_vec()));
let low = b"a\x00\x00\x00\x00\x00\x00\x00\x00".to_vec();
let high = b"a\xff\xff\xff\xff\xff\xff\xff\xff".to_vec();
let rows = s.range_scan(&low, &high);
assert_eq!(rows.len(), 2);
assert_eq!(rows[0].1, Some(b"v1".to_vec()));
assert_eq!(rows[1].1, Some(b"v2".to_vec()));
}
}