use std::collections::BTreeMap;
use super::{Key, Value};
pub struct Iter<'a> {
inner: std::collections::btree_map::Range<'a, Vec<u8>, Vec<u8>>,
}
impl<'a> Iterator for Iter<'a> {
type Item = (&'a [u8], &'a [u8]);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(k, v)| (&**k, &**v))
}
}
impl<'a> DoubleEndedIterator for Iter<'a> {
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back().map(|(k, v)| (&**k, &**v))
}
}
#[derive(Default, Clone)]
pub struct Petal {
lo: Vec<u8>,
hi: Option<Vec<u8>>,
storage: BTreeMap<Vec<u8>, Vec<u8>>,
}
impl Petal {
pub fn new() -> Box<Petal> {
Box::default()
}
pub fn len(&self) -> usize {
self.storage.len()
}
pub fn contains(&self, key: Key) -> bool {
self.storage.contains_key(key)
}
pub fn get(&self, key: Key) -> Option<Value> {
self.storage.get(key).map(|v| &**v)
}
pub fn range<'a>(
&'a self,
start: std::ops::Bound<&[u8]>,
end: std::ops::Bound<&[u8]>,
) -> Iter<'a> {
Iter {
inner: self.storage.range::<[u8], _>((start, end)),
}
}
#[must_use]
pub fn batch<'a, I: IntoIterator<Item = (&'a [u8], Option<&'a [u8]>)>>(
&self,
iter: I,
) -> Box<Petal> {
let mut ret = Box::new(Petal {
hi: self.hi.clone(),
lo: self.lo.clone(),
storage: self.storage.clone(),
});
for (key, value_opt) in iter {
self.assert_key_in_bounds(key);
if let Some(value) = value_opt {
ret.storage.insert(key.to_vec(), value.to_vec());
}
}
ret
}
#[must_use]
pub fn split(&self, split_key: Key) -> (Box<Petal>, Box<Petal>) {
self.assert_key_in_bounds(split_key);
let mut lhs_storage = BTreeMap::default();
let mut rhs_storage = BTreeMap::default();
for (k, v) in &self.storage {
if &**k < split_key {
lhs_storage.insert(k.clone(), v.clone());
} else {
rhs_storage.insert(k.clone(), v.clone());
}
}
let lhs = Box::new(Petal {
lo: self.lo.clone(),
hi: Some(split_key.to_vec()),
storage: lhs_storage,
});
let rhs = Box::new(Petal {
lo: split_key.to_vec(),
hi: self.hi.clone(),
storage: rhs_storage,
});
(lhs, rhs)
}
#[must_use]
pub fn merge(&self, rhs: &Petal) -> Box<Petal> {
assert_eq!(self.hi.as_ref().unwrap(), &*rhs.lo);
let storage = self
.storage
.iter()
.chain(rhs.storage.iter())
.map(|(k, v)| (k.clone(), v.clone()))
.collect();
Box::new(Petal {
lo: self.lo.clone(),
hi: rhs.hi.clone(),
storage,
})
}
fn assert_key_in_bounds(&self, key: Key) {
assert!(key >= &self.lo);
if let Some(hi) = &self.hi {
assert!(key < &hi);
}
}
}