use std::sync::Arc;
use crate::persistent_artrie::block_storage::BlockStorage;
use crate::persistent_artrie::error::{PersistentARTrieError, Result};
use crate::persistent_artrie_core::key_encoding::CharKey;
use crate::persistent_artrie_core::overlay::flip::LockFreeOverlay;
use crate::sync_compat::RwLock;
use crate::value::DictionaryValue;
use super::nodes::persistent_node::PersistentCharNode;
impl<V: DictionaryValue, S: BlockStorage> super::PersistentARTrieChar<V, S> {
pub(crate) fn load_root_immutable(
&mut self,
buffer_manager: &Arc<RwLock<crate::persistent_artrie::buffer_manager::BufferManager<S>>>,
root_ptr: u64,
) -> Result<(usize, bool)> {
let (overlay_root, term_count, image_loaded) =
self.load_overlay_char_root_compressed(buffer_manager, root_ptr)?;
if !self.install_prebuilt_overlay_root(overlay_root) {
return Err(PersistentARTrieError::internal(
"F5 load_root_immutable: install_prebuilt_overlay_root did not engage \
(WAL not Overlay-regime, or ineligible V)",
));
}
self.len.store(0, std::sync::atomic::Ordering::Release);
Ok((term_count, image_loaded))
}
pub(crate) fn load_overlay_char_root_compressed(
&self,
buffer_manager: &Arc<RwLock<crate::persistent_artrie::buffer_manager::BufferManager<S>>>,
root_ptr: u64,
) -> Result<(Arc<PersistentCharNode<V>>, usize, bool)> {
use crate::persistent_artrie_core::overlay::f5_build::build_overlay_root_from_terms;
if root_ptr == 0 {
let empty = build_overlay_root_from_terms::<CharKey, V, _>(
std::collections::BTreeMap::new(),
None,
);
return Ok((empty, 0, false));
}
match self.enumerate_char_terms_from_disk(buffer_manager, root_ptr) {
Ok((terms, empty_term, term_count)) => {
let root = build_overlay_root_from_terms::<CharKey, V, _>(terms, empty_term);
Ok((root, term_count as usize, true))
}
Err(e) => {
log::warn!(
"L3.1 char codec loader: dense image load failed ({:?}); falling back to an \
EMPTY image + WAL drain (corrupt-image parity)",
e
);
let empty = build_overlay_root_from_terms::<CharKey, V, _>(
std::collections::BTreeMap::new(),
None,
);
Ok((empty, 0, false))
}
}
}
}
#[cfg(test)]
mod deep_term_converter_tests {
use crate::persistent_artrie_core::key_encoding::CharKey;
use crate::persistent_artrie_core::overlay::f5_build::build_overlay_root_from_terms;
#[test]
fn build_overlay_root_from_terms_work_stack_safe_at_100k_char() {
const DEPTH: usize = 100_000;
const EDGE: u32 = 'a' as u32;
let units: Vec<u32> = std::iter::repeat(EDGE).take(DEPTH).collect();
let root =
build_overlay_root_from_terms::<CharKey, u64, _>(vec![(units, Some(42u64))], None);
let mut cur = root.clone();
let mut depth = 0usize;
while let Some(child) = cur.find_child(EDGE).and_then(|c| c.as_in_mem()).cloned() {
depth += 1;
cur = child;
}
assert_eq!(depth, DEPTH, "converted overlay spine has the full depth");
assert!(cur.is_final(), "deep leaf is final");
assert_eq!(cur.get_value(), Some(42), "deep leaf value round-tripped");
drop(cur);
drop(root);
}
}