use std::sync::Arc;
use crate::{NIL, Treap};
struct Inner<K, V> {
data: Vec<(K, V)>,
}
pub struct TreapSnapshot<K, V> {
inner: Arc<Inner<K, V>>,
}
impl<K: Ord + Clone, V: Clone> TreapSnapshot<K, V> {
pub fn from_treap(treap: &Treap<K, V>) -> Self {
let mut data = Vec::with_capacity(treap.len());
collect(treap, treap.root, &mut data);
Self {
inner: Arc::new(Inner { data }),
}
}
pub fn len(&self) -> usize {
self.inner.data.len()
}
pub fn is_empty(&self) -> bool {
self.inner.data.is_empty()
}
pub fn get(&self, key: &K) -> Option<&V> {
match self.inner.data.binary_search_by(|(k, _)| k.cmp(key)) {
Ok(idx) => Some(&self.inner.data[idx].1),
Err(_) => None,
}
}
pub fn iter(&self) -> std::slice::Iter<'_, (K, V)> {
self.inner.data.iter()
}
pub fn range(&self, from: &K, to: &K) -> std::slice::Iter<'_, (K, V)> {
let lo = self.inner.data.partition_point(|(k, _)| k < from);
let hi = self.inner.data.partition_point(|(k, _)| k <= to);
self.inner.data[lo..hi].iter()
}
}
impl<K, V> Clone for TreapSnapshot<K, V> {
fn clone(&self) -> Self {
Self {
inner: Arc::clone(&self.inner),
}
}
}
fn collect<K: Clone, V: Clone>(treap: &Treap<K, V>, idx: u32, out: &mut Vec<(K, V)>) {
if idx == NIL {
return;
}
let node = &treap.nodes[idx as usize];
collect(treap, node.left, out);
out.push(((*node.key).clone(), (*node.value).clone()));
collect(treap, node.right, out);
}
#[cfg(test)]
#[path = "concurrent_reads_tests.rs"]
mod tests;