#![allow(dead_code)]
use std::collections::{HashMap, HashSet};
use std::sync::Arc;
use parking_lot::RwLock;
use crate::index::{SequenceNumber, VersionPointer};
#[derive(Clone, Default)]
pub struct RoaringBitmapSidecar {
inner: Arc<RwLock<HashMap<String, HashMap<Vec<u8>, VersionPointer>>>>,
}
impl RoaringBitmapSidecar {
pub fn new() -> Self {
Self {
inner: Arc::new(RwLock::new(HashMap::new())),
}
}
pub fn add(&self, tag: impl Into<String>, key: Vec<u8>, pointer: VersionPointer) {
let tag = tag.into();
let mut guard = self.inner.write();
let entry = guard.entry(tag).or_default();
match entry.get_mut(&key) {
Some(existing) if existing.sequence >= pointer.sequence => return,
Some(existing) => *existing = pointer,
None => {
entry.insert(key, pointer);
}
}
}
pub fn intersect_keys(&self, tags: &[String], snapshot: SequenceNumber) -> Vec<Vec<u8>> {
if tags.is_empty() {
return Vec::new();
}
let guard = self.inner.read();
let mut iter = tags.iter();
let first = match iter.next() {
Some(tag) => guard.get(tag.as_str()).cloned().unwrap_or_default(),
None => return Vec::new(),
};
let mut keys: HashSet<Vec<u8>> = first
.into_iter()
.filter(|(_, pointer)| pointer.is_visible_at(snapshot))
.map(|(key, _)| key)
.collect();
for tag in iter {
if let Some(mapping) = guard.get(tag.as_str()) {
let tag_keys: HashSet<Vec<u8>> = mapping
.iter()
.filter(|(_, pointer)| pointer.is_visible_at(snapshot))
.map(|(key, _)| key.clone())
.collect();
keys = keys
.intersection(&tag_keys)
.cloned()
.collect::<HashSet<_>>();
} else {
return Vec::new();
}
}
keys.into_iter().collect()
}
}