#![allow(dead_code)]
use std::collections::HashMap;
use std::sync::Arc;
use parking_lot::RwLock;
use serde_json::Value;
use crate::index::{SequenceNumber, VersionPointer};
#[derive(Clone, Default)]
pub struct JsonTrieSidecar {
inner: Arc<RwLock<HashMap<(String, String), HashMap<Vec<u8>, VersionPointer>>>>,
}
impl JsonTrieSidecar {
pub fn new() -> Self {
Self {
inner: Arc::new(RwLock::new(HashMap::new())),
}
}
pub fn index_value(
&self,
path: impl Into<String>,
value: &Value,
key: Vec<u8>,
pointer: VersionPointer,
) {
let path = path.into();
let value_repr = JsonTrieSidecar::stringify(value);
let mut guard = self.inner.write();
let entry = guard.entry((path, value_repr)).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 query_equals(
&self,
path: &str,
value: &Value,
snapshot: SequenceNumber,
) -> Vec<Vec<u8>> {
let guard = self.inner.read();
guard
.get(&(path.to_string(), JsonTrieSidecar::stringify(value)))
.map(|mapping| {
mapping
.iter()
.filter(|(_, pointer)| pointer.is_visible_at(snapshot))
.map(|(key, _)| key.clone())
.collect()
})
.unwrap_or_default()
}
fn stringify(value: &Value) -> String {
match value {
Value::String(s) => s.clone(),
Value::Bool(b) => b.to_string(),
Value::Number(n) => n.to_string(),
Value::Null => "null".to_string(),
Value::Array(_) | Value::Object(_) => value.to_string(),
}
}
}