use std::sync::Arc;
use crate::persistent_artrie_core::key_encoding::KeyEncoding;
use crate::persistent_artrie_core::overlay::node::{Child, OverlayNode};
use crate::persistent_artrie_core::overlay::OverlayFaulter;
use crate::value::DictionaryValue;
use crate::{DictionaryNode, MappedDictionaryNode};
#[derive(Clone)]
pub struct OverlayDictionaryNode<K: KeyEncoding, V: DictionaryValue = ()> {
overlay: Option<Arc<OverlayNode<K, V>>>,
overlay_faulter: Option<Arc<dyn OverlayFaulter<K, V>>>,
}
impl<K: KeyEncoding, V: DictionaryValue> std::fmt::Debug for OverlayDictionaryNode<K, V> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("OverlayDictionaryNode")
.field("overlay", &self.overlay)
.field("has_faulter", &self.overlay_faulter.is_some())
.finish()
}
}
impl<K: KeyEncoding, V: DictionaryValue> OverlayDictionaryNode<K, V> {
pub(crate) fn from_overlay_root(
node: Arc<OverlayNode<K, V>>,
overlay_faulter: Option<Arc<dyn OverlayFaulter<K, V>>>,
) -> Self {
Self {
overlay: Some(node),
overlay_faulter,
}
}
pub(crate) fn from_overlay_node(
node: Arc<OverlayNode<K, V>>,
overlay_faulter: Option<Arc<dyn OverlayFaulter<K, V>>>,
) -> Self {
Self {
overlay: Some(node),
overlay_faulter,
}
}
pub(crate) fn overlay_child_node(
child: &Child<K, V>,
overlay_faulter: &Option<Arc<dyn OverlayFaulter<K, V>>>,
) -> Option<Self> {
if let Some(child_arc) = child.as_in_mem() {
return Some(Self::from_overlay_node(
Arc::clone(child_arc),
overlay_faulter.clone(),
));
}
if let Some(on_disk) = child.as_on_disk() {
if !on_disk.is_null() {
let loaded = overlay_faulter.as_ref()?.fault_overlay_slot(on_disk)?;
return Some(Self::from_overlay_node(loaded, overlay_faulter.clone()));
}
}
None
}
}
impl<K: KeyEncoding, V: DictionaryValue> DictionaryNode for OverlayDictionaryNode<K, V> {
type Unit = K::Token;
fn is_final(&self) -> bool {
match &self.overlay {
Some(node) => node.is_final(),
None => false,
}
}
fn transition(&self, label: K::Token) -> Option<Self> {
let node = self.overlay.as_ref()?;
let child = node.find_child(K::token_to_unit(label))?;
Self::overlay_child_node(child, &self.overlay_faulter)
}
fn edges(&self) -> Box<dyn Iterator<Item = (K::Token, Self)> + '_> {
let Some(node) = &self.overlay else {
return Box::new(std::iter::empty());
};
let mut edges = Vec::with_capacity(node.num_children());
for (&unit, child) in node.iter_children() {
let Some(token) = K::unit_to_token(unit) else {
continue;
};
if let Some(child_node) = Self::overlay_child_node(child, &self.overlay_faulter) {
edges.push((token, child_node));
}
}
Box::new(edges.into_iter())
}
fn edge_count(&self) -> Option<usize> {
self.overlay.as_ref().map(|node| node.num_children())
}
}
impl<K: KeyEncoding, V: DictionaryValue> MappedDictionaryNode for OverlayDictionaryNode<K, V> {
type Value = V;
fn value(&self) -> Option<V> {
self.overlay.as_ref().and_then(|node| node.get_value())
}
}
#[allow(dead_code)]
fn _assert_overlay_dictionary_node_send_sync() {
fn assert_send_sync<T: Send + Sync>() {}
use crate::persistent_artrie_core::key_encoding::{ByteKey, CharKey};
assert_send_sync::<OverlayDictionaryNode<ByteKey, ()>>();
assert_send_sync::<OverlayDictionaryNode<ByteKey, u64>>();
assert_send_sync::<OverlayDictionaryNode<CharKey, ()>>();
assert_send_sync::<OverlayDictionaryNode<CharKey, u64>>();
}