use std::collections::HashSet;
use super::{Interface, Key, Value};
pub struct Iter<'a, A: Interface, B: Interface> {
inner: &'a Composite<A, B>,
}
impl<'a, A: Interface, B: Interface> Iterator for Iter<'a, A, B> {
type Item = (&'a [u8], &'a [u8]);
fn next(&mut self) -> Option<Self::Item> {
todo!()
}
}
impl<'a, A: Interface, B: Interface> DoubleEndedIterator for Iter<'a, A, B> {
fn next_back(&mut self) -> Option<Self::Item> {
todo!()
}
}
#[derive(Default, Clone)]
pub struct Composite<A: Interface, B: Interface> {
a: A,
b: B,
tombstones: HashSet<Vec<u8>>,
merge_threshold: usize,
}
impl<A: Interface, B: Interface> Composite<A, B> {
pub fn new(merge_threshold: usize) -> Composite<A, B> {
Composite {
a: A::default(),
b: B::default(),
tombstones: HashSet::default(),
merge_threshold,
}
}
pub fn len(&self) -> usize {
self.a.len() + self.b.len() - self.tombstones.len()
}
pub fn contains(&self, key: Key) -> bool {
self.a.contains(key) || (!self.tombstones.contains(key) && self.b.contains(key))
}
pub fn get(&self, key: Key) -> Option<Value> {
if let Some(v) = self.a.get(key) {
Some(v)
} else if self.tombstones.contains(key) {
None
} else {
self.b.get(key)
}
}
#[must_use]
pub fn batch<'a, I: IntoIterator<Item = (&'a [u8], Option<&'a [u8]>)>>(
&self,
iter: I,
) -> Composite<A, B> {
let mut ret = todo!();
for (key, value) in iter {
self.assert_key_in_bounds(key);
todo!()
}
ret
}
#[must_use]
pub fn split(&self, split_key: Key) -> (Composite<A, B>, Composite<A, B>) {
self.assert_key_in_bounds(split_key);
todo!()
}
#[must_use]
pub fn merge(&self, rhs: &Composite<A, B>) -> Composite<A, B> {
todo!()
}
fn range<'a>(
&'a self,
start: std::ops::Bound<&[u8]>,
end: std::ops::Bound<&[u8]>,
) -> Iter<'a, A, B> {
todo!()
}
fn assert_key_in_bounds(&self, key: Key) {
todo!()
}
}