Design Reference: docs/design/slice3-l33c-execution-plan-2026-06-09.md §1a, §2-§6
Execution: Single atomic commit (C2, after C1 BLOCKER#4 fallback-port).
src/persistent_artrie/mutation_core.rs (448 lines)STATUS: DELETE as entire cluster (self-referential, entangled with TrieRoot field/type)
| Symbol | Lines | Verdict | Reason |
|---|---|---|---|
pub(super) fn insert_impl | 44–79 | DELETE | WAL-logged insert wrapper; owned-only, dead post-step-1 collapse |
pub(super) fn insert_impl_core | 88–105 | DELETE | Core insert against TrieRoot::*; mutation only under inner OR lock |
fn insert_into_root | 111–254 | DELETE | Reentrancy-safe insert into &mut TrieRoot; bucket→ART conversion recursion |
pub(super) fn remove_impl | 259–274 | DELETE | WAL-logged remove wrapper; owned-only, dead post-step-1 collapse |
pub(super) fn remove_impl_core | 280–296 | DELETE | Core remove against TrieRoot::*; mutation only under inner OR lock |
fn remove_from_root | 299–376 | DELETE | Reentrancy-safe remove from &mut TrieRoot; recursive descent |
fn convert_root_bucket_to_art | 380–413 | DELETE | Bucket→ART promotion for root; called only from insert_into_root |
pub(super) fn insert_impl_no_wal | 420–423 | DELETE (Step 2) | Recovery replay insert; deletes in step 2 when owned loaders gone |
pub(super) fn remove_impl_no_wal | 429–433 | DELETE (Step 2) | Recovery replay remove; marked #[allow(dead_code)], deletes in step 2 |
pub(super) fn upsert_impl_no_wal | 441–446 | DELETE (Step 2) | Recovery replay upsert; deletes in step 2 when owned loaders gone |
src/persistent_artrie/transitions.rs (~900 lines)STATUS: DELETE owned-write/transition surface; KEEP decode surface + ChildNode overlay variants
| Symbol | Lines | Verdict | Reason |
|---|---|---|---|
pub struct BucketToArtResult | 48–57 | DELETE | Only returned by bucket_to_art_node; unused after |
pub struct ArtToBucketResult | 61–64 | DELETE | Only returned by art_node_to_bucket; unused after |
pub enum TransitionError + impl | 68–102 | DELETE | Only used by deleted transition functions |
pub fn should_convert_bucket_to_art | 109–117 | DELETE | Called only from bucket_to_art_node |
pub fn bucket_to_art_node | 125–237 | DELETE | Called only from convert_root_bucket_to_art + ChildNode::insert_key/insert_with_value (both deleted) |
pub fn should_merge_art_to_bucket | 243–246 | DELETE | ART→bucket merge; no caller in owned delete scope |
pub fn art_node_to_bucket | 252–294 | DELETE | ART→bucket merge result; unused after owned deletion |
pub fn insert_key (ChildNode method) | 503–566 | DELETE | Owned-only recursive insert into child; used only in bucket_to_art_node + insert_into_root paths |
pub fn insert_with_value (ChildNode method) | 586–659 | DELETE | Owned-only recursive insert with value; same caller paths |
pub fn remove_key (ChildNode method) | 679–715 | DELETE | Owned-only recursive remove; no caller in overlay path |
pub fn contains_key (ChildNode method) | 735–761 | DELETE | Owned-only recursive contains check; unused post-step-1 |
KEEP: All ChildNode helper methods + overlay-only variants:
is_bucket(), is_disk_ref(), as_disk_ref(), needs_persistence(), mark_has_dirty_descendants(), clear_dirty_flags(), mark_dirty(), as_bucket(), as_bucket_mut(), as_art_node(), as_art_node_mut() — KEEP (used by overlay + disk-backed paths)Bucket(StringBucket), ArtNode { ... }, DiskRef { ptr: SwizzledPtr } — KEEPsrc/persistent_artrie/node_impl.rs (~400 lines)STATUS: DELETE owned NodeInner variants + constructors; KEEP Overlay + PersistentARTrieNode struct
| Symbol | Lines | Verdict | Reason |
|---|---|---|---|
pub struct PersistentARTrieNode<V> | 35–40 | KEEP | Root node wrapper for DictionaryNode trait |
struct BucketPosition | 43–51 | DELETE | Only used by owned Bucket/Root match arms |
enum NodeInner::ArtNode { ... } | 60–75 | DELETE | Owned variant; replaced by Overlay |
enum NodeInner::Bucket { ... } | 77–80 | DELETE | Owned variant; replaced by Overlay |
enum NodeInner::Root { ... } | 82–91 | DELETE | Owned root variant; replaced by Overlay |
enum NodeInner::Empty | 93 | DELETE | Owned empty marker; Overlay handles all paths |
enum NodeInner::Overlay { ... } | 101–111 | KEEP | Lock-free overlay; sole forward path |
pub fn new_root() | 146–156 | DELETE | Creates Root variant; no owned construction post-flip |
pub fn new_root_with_children() | 159–174 | DELETE | Creates Root variant with children; used only by get_root_node() (deleting) |
pub fn new_art_node() | 179–189 | DELETE | Creates ArtNode variant; no owned construction |
pub fn new_art_node_with_children() | 192–207 | DELETE | Creates ArtNode with children; used only by internal owned paths |
pub fn new_bucket() | 210–215 | DELETE | Creates Bucket variant; no owned construction |
pub(crate) fn new_overlay() | 221–229 | KEEP | Creates Overlay variant; sole forward constructor |
fn overlay_child_node() | 236–250 | KEEP | Resolves Overlay child slots; used by Overlay traversal |
| (All other overlay-specific methods) | 251+ | KEEP | Overlay traversal + DictionaryNode trait impl for overlay |
Remaining Deletions in node_impl.rs: All match NodeInner::ArtNode/Bucket/Root/Empty arms throughout file; all owned impl DictionaryNode specializations for owned variants.
src/persistent_artrie/dict_impl.rs (~2000 lines)STATUS: DELETE TrieRoot enum + root field + dirty_prefixes field (LAST step, field dies last)
| Symbol | Lines | Verdict | Reason |
|---|---|---|---|
pub(crate) enum TrieRoot<V> | 464–479 | DELETE | Owned root union type; replaced by overlay-only state |
pub(crate) root: RwLock<TrieRoot<V>> field | 280 | DELETE | Inner RwLock; the "OR-lock" itself — field deletion = lock deletion |
pub(crate) dirty_prefixes: std::sync::Mutex<HashSet<Vec<u8>>> field | 345 | DELETE | Owned dirty-tracking cache; no longer needed post-overlay-only |
pub(super) fn get_root_node() | 505–520 | DELETE | Sole owned root constructor; reads from self.root under held guard, returns PersistentARTrieNode::new_root_with_children() |
| Owned-specific dirty-tracking reader block | 1874–1970+ | DELETE | Tests + internal checkpoint readers that access dict.dirty_prefixes |
fn bytes_le(...) | ~106 | DELETE (if orphaned) | u32 serializer; check if any caller remains post-serialize_impl cleanup |
src/persistent_artrie/dirty_tracking.rs (158 lines)STATUS: DELETE entire module OR convert to stubs (all functions marked with F4 = owned-only)
| Symbol | Lines | Verdict | Reason |
|---|---|---|---|
pub(super) fn record_dirty_path() | 42–53 | DELETE | Records paths to dirty_prefixes Mutex; owned-only mutation tracking |
pub(super) fn path_needs_persistence() | 57–62 | DELETE | Checks if path in dirty_prefixes; owned-only read |
pub(super) fn propagate_dirty_to_root() | 74–78 | DELETE | Sets HAS_DIRTY_DESCENDANTS on root; marked #[allow(dead_code)], used only in owned hot paths |
pub(super) fn cache_disk_location() | 82–86 | DELETE | Caches disk locations for clean-subtree skip; owned-only optimization |
pub(super) fn get_cached_disk_location() | 90–101 | DELETE | Retrieves cached disk location; owned-only |
pub(super) fn resolve_and_cache_disk_location() | 105–115 | DELETE | Resolves DiskRef + caches; marked #[allow(dead_code)], owned-only |
pub(super) fn clear_dirty_tracking_state() | 122–128 | DELETE | Clears dirty_prefixes Mutex + OR flags; owned-only post-checkpoint |
fn clear_dirty_flags_recursive() | 133–143 | DELETE | Recursive dirty-flag clear; owned-only mutation |
fn clear_child_dirty_flags_recursive() | 146–157 | DELETE | Child flag clear; owned-only helper |
Consideration: Entire module can be deleted, OR individual functions can be commented out with #[deprecated] stubs if inline dirty_tracking remains. The current approach: DELETE entire file (no callers remain post-step-1 collapse in dict_impl + overlay checkpoint).
src/persistent_artrie/disk_load.rs (1164 lines)STATUS: DELETE owned loaders; KEEP enumerate_terms_from_disk + decode surface
| Symbol | Lines | Verdict | Reason |
|---|---|---|---|
fn load_root_from_disk() | 89–219 | DELETE | Loads owned root from disk; dead post-step-1 |
pub(super) fn load_root_from_disk_with_arena() | 333–506 | DELETE | Loads owned root + recurses through children; pre-flip eager loader |
fn load_art_node_with_children() | 220–253 | DELETE | Helper for owned ART node load |
fn load_child_from_disk() | 254–332 | DELETE | Helper for owned child load |
fn load_art_node_with_children_from_arena() | 711–758 | DELETE | Owned ART child loader with arena; called only by load_root_from_disk_with_arena |
fn load_child_from_disk_with_arena() | 759–846 | DELETE | Owned child loader with arena; called only by owned paths |
fn load_single_art_node_data() | 847–892 | DELETE (if orphaned) | Loads single ART node data; check if enumerate_terms_from_disk uses it |
fn load_single_child_data() | 893–965 | DELETE (if orphaned) | Loads single child data; check if enumerate_terms_from_disk uses it |
fn load_art_node_with_children_from_arena_iterative() | 966+ | DELETE (if orphaned) | Iterative variant; check callers |
KEEP: These are SOLE reopen path post-C2:
pub(super) fn enumerate_terms_from_disk() | 507–710 | KEEP | Sole reopen path; loads all terms from disk-resident bucket data (no TrieRoot construction) |pub struct SingleChildData | (embedded in file) | KEEP | Data structure for enum_terms_from_disk |from_bytes(), len(), get_entry(), get_suffix(), get_value(), search(), contains(), iter(), as_bytes(), header(), etc. — KEEP (used by enumerate_terms_from_disk + overlay load path)src/persistent_artrie/bucket.rs (~500 lines)STATUS: KEEP decode surface (used by enumerate_terms_from_disk + overlay); DELETE write/split only when compiler confirms orphan
| Symbol | Lines | Verdict | Reason |
|---|---|---|---|
impl StringBucket { insert(...) } | (multiple) | DELETE (if orphaned) | Write surface; called by insert_into_root + bucket_to_art_node (both deleting) |
impl StringBucket { insert_key(...) } | (multiple) | DELETE (if orphaned) | Write surface; called by insert_into_root + ChildNode::insert_key (both deleting) |
impl StringBucket { split(...) } | (multiple) | DELETE (if orphaned) | Split logic; called only by owned paths |
impl StringBucket { split_by_first_byte(...) } | (multiple) | DELETE (if orphaned) | Split helper; called by bucket_to_art_node (deleting) |
KEEP decode surface: from_bytes(), len(), get_entry(), get_suffix(), get_value(), search(), contains(), iter(), as_bytes(), header(), remove() | (multiple) | KEEP | Used by enumerate_terms_from_disk, overlay load, overlay traversal |
pub struct StringEntry | (definition) | KEEP | Used by decode surface |
pub struct BucketHeader | (definition) | KEEP | Used by all StringBucket operations |
Compiler check: After deleting insert_impl/bucket_to_art_node/ChildNode insert methods, cargo check will flag any remaining write-surface callers. Delete them when confirmed orphaned.
src/persistent_artrie/path_compression.rsSTATUS: VERIFY via compiler; KEEP if CX codec (task #43) uses them
| Symbol | Verdict | Reason |
|---|---|---|
pub fn common_prefix_len(...) -> usize | VERIFY | Check if CX codec (overlay encoding) calls this |
pub fn make_common_prefix(...) -> Vec<u8> | VERIFY | Check if CX codec calls this |
If CX codec (compact_encoding.rs) calls these, KEEP. If not, DELETE.
src/persistent_artrie/serialize_impl.rsSTATUS: DELETE no-value wrapper; KEEP value-len variant
| Symbol | Lines | Verdict | Reason |
|---|---|---|---|
pub(super) fn serialize_node_to_disk(...) -> Result<usize> | ~57 | DELETE | No-value wrapper; dead per design §0.5 |
pub(super) fn serialize_node_to_disk_with_value_len(...) -> Result<usize> | ~956, ~997 | KEEP | LIVE caller at overlay_checkpoint.rs:956, 997 |
src/persistent_artrie/persistence_api.rsSTATUS: DELETE owned WAL append
| Symbol | Lines | Verdict | Reason |
|---|---|---|---|
pub(super) fn append_batch_mutation_wal_record(...) | ~231 | DELETE | Batch WAL append; dead post-step-1 (overlay uses singleton WAL appends) |
src/persistent_artrie/overlay_checkpoint.rsSTATUS: DELETE next_lsn_at_capture field (BLOCKER#4 already uses committed watermark)
| Symbol | Lines | Verdict | Reason |
|---|---|---|---|
pub(crate) struct CheckpointSnapshot { next_lsn_at_capture: u64, ... } | line 64 | DELETE field | Per design §4 BLOCKER#4, use committed_checkpoint_lsn, not next_lsn_at_capture |
Ripple Check: Char has separate CheckpointSnapshot in persistent_artrie_char/persist.rs — byte deletion does NOT affect char.
KEEP:
pub(super) fn serialize_root_value_bytes(...) | 1297 | KEEP | Called by overlay checkpoint pathsrc/persistent_artrie/cursor_iter.rsSTATUS: DELETE owned cursor collectors
| Symbol | Lines | Verdict | Reason |
|---|---|---|---|
pub(super) fn collect_terms_from_cursor(...) | ~76 | DELETE | Collects from owned cursor; unused post-step-1 |
pub(super) fn collect_terms_with_cursor_and_arena(...) | ~76 | DELETE | Collects from cursor + arena; unused post-step-1 |
src/persistent_artrie/overlay_fault.rs (17136 bytes)STATUS: KEEP; these are test/bench helpers used by char tests
| Symbol | Lines | Verdict | Reason |
|---|---|---|---|
pub(crate) fn bench_enable_eviction(...) | 277–303 | KEEP | Called by persistent_artrie_char/overlay_dictionary_node_faulting_tests.rs and other char eviction tests |
pub(crate) fn bench_immutable_checkpoint_with_eviction() | 325–327 | KEEP | Called by char overlay tests |
pub(crate) fn evictable_node_count() | 334–340 | KEEP | Called by char overlay tests |
pub(crate) fn evict_overlay_nodes(...) | 224–276 | KEEP | Batch eviction driver; used by benches |
pub(crate) fn load_overlay_node_from_disk(...) | 49–155 | KEEP | Overlay loader; LIVE caller in overlay_checkpoint + lockfree_cas |
src/persistent_artrie/lockfree_cas.rs (1500+ lines)STATUS: DELETE owned merge helpers (COLLAPSE step 1 already removed callers); KEEP overlay merge
| Symbol | Lines | Verdict | Reason |
|---|---|---|---|
Owned merge helpers (if any named ..._owned or called from deleted paths) | ~1440 | DELETE | Dead post-step-1 collapse of shared_trait_impl insert/remove tails |
Compiler check: After deleting shared_trait_impl owned tails + parallel_merge collapse, check for remaining owned-only callers in lockfree_cas.
src/persistent_artrie/parallel_merge.rsSTATUS: COLLAPSE (NOT DELETE); replace owned insert_impl with overlay merge path
| Current | Lines | Action | Replacement |
|---|---|---|---|
Line ~166: guard.insert_impl(&term, Some(value)) | 166 | COLLAPSE | Replace with overlay merge helper call (find merge_entries_overlay or equivalent) |
Mirror: Char already collapsed parallel_merge to overlay path (per design §2 step-1).
Find replacement: Search for char parallel_merge overlay merge path (persistent_artrie_char/parallel_merge.rs), then apply same pattern to byte.
src/persistent_artrie/overlay_write_mode.rs (82 lines)STATUS: DELETE dead stubs/arms (already collapsed in L3.3a per design §0.4)
| Symbol | Verdict | Reason |
|---|---|---|
| Dead match arms / owned-regime stubs | DELETE | Owned arms already collapsed in earlier L3.3a work |
Compiler will flag any remaining references to OverlayWriteMode variants that were already removed.
src/persistent_artrie/arena_iter.rsSTATUS: DELETE inline owned-tail reads on self.root
| Symbol | Verdict | Reason |
|---|---|---|
Owned tails reading self.root | DELETE | Inline reads from deleted field; collapse to overlay-only paths |
src/persistent_artrie/mmap_ctor.rs + src/persistent_artrie/io_uring_ctor.rsSTATUS: BLOCKER#4 fallback-port (C1 commit, BEFORE owned deletion)
See separate design document: docs/design/slice3-l33c-execution-plan-2026-06-09.md §4.
src/persistent_artrie/shared_trait_impl.rsSTATUS: COLLAPSE step 1 (owned tails already dead; early return <overlay> makes owned tail unreachable)
| Symbol | Verdict | Action |
|---|---|---|
insert method owned tail | COLLAPSE | Delete owned tail only; overlay early return stays |
insert_with_value method owned tail | COLLAPSE | Delete owned tail only |
remove method owned tail | COLLAPSE | Delete owned tail only |
remove_prefix method owned tail | COLLAPSE | Delete owned tail only |
src/persistent_artrie/atomic_ops.rsSTATUS: COLLAPSE step 1 (owned tails already dead)
| Symbol | Verdict | Action |
|---|---|---|
get_value_bytes owned tail | COLLAPSE | Delete owned tail only; overlay early return stays |
unrouted_* shims owned tails | COLLAPSE | Delete owned tails only |
TRAP (§8.2): Char try_increment_impl_no_wal at line 159 is LIVE (still needed for recovery replay). Do NOT delete char's version.
src/persistent_artrie/lockfree_cas.rs — line ~1476STATUS: COLLAPSE step 1
| Symbol | Lines | Verdict | Reason |
|---|---|---|---|
| Owned tail at line 1476 | 1476 | COLLAPSE | Delete owned tail only; overlay path stays |
Verification:
formal-verification/UNSAFE_INVENTORY.tsv for any rows tagged byte-*-owned-* or similarunsafe blocks tracked; all byte unsafe blocks are in:
Conclusion: Deleting byte owned cluster removes zero tracked unsafe blocks. No row pruning needed for byte. Set-equality gate in UNSAFE_INVENTORY.tsv + UNSAFE_CONTRACTS.tsv requires NO changes for byte.
See: docs/design/slice3-l33c-execution-plan-2026-06-09.md §4.
Applies to: src/persistent_artrie/f5_loader.rs, mmap_ctor.rs, io_uring_ctor.rs (C1 only, NOT in C2 deletion scope).
C1 Change Summary:
load_root_immutable(f5_loader.rs:60): Result → Result<(usize, bool)> (bool = image_loaded)was_loaded_from_disk=loaded_root.is_some() with root_ptr!=0 checkeffective_loaded = (root_ptr!=0) && image_loadedScope: BLOCKER#4 fallback-port only (§4)
Files: f5_loader.rs, mmap_ctor.rs, io_uring_ctor.rs
Behavior: Preserve-equivalent, de-risk keystone by proving codec-only reopen path works
Scope: Entire owned-tree deletion cluster (§1–§22, above)
Files: All 17+ files listed above
Atomicity: All deletions in ONE commit (cluster is self-referential + entangled with TrieRoot + UNSAFE set-equality)
Gate: Run full test suite + cargo check --all-features; verify NO orphaned symbols remain (compiler dead-code warnings must be resolved)
cargo check --all-features returns ZERO new compiler errors/warnings related to owned codeuse super::transitions::ChildNode imports succeed (ChildNode still exists)use super::nodes::{...} imports succeed (Node/ArtNode types still exist for overlay)enumerate_terms_from_disk + decode surface compile without orphaned referencesload_overlay_node_from_disk compiles (KEEP, used by lockfree_cas + checkpoint)persistent_artrie_recovery_tests.rs::byte_invalid_root_descriptor_replays_wal_without_checkpoint_skip (confirms BLOCKER#4 fallback works)cargo test --all-features --lib persistent_artrie (2700+ test count must pass)| File | Total Lines | Status | Deletions | Keepers |
|---|---|---|---|---|
| mutation_core.rs | 448 | DELETE | 44–413 (all) | — |
| transitions.rs | ~900 | PARTIAL | 48–294, 503–761 | ChildNode decode, Overlay variants |
| node_impl.rs | ~400 | PARTIAL | BucketPosition, NodeInner::{ArtNode, Bucket, Root, Empty}, new_root*, new_art_node*, new_bucket | PersistentARTrieNode, NodeInner::Overlay, new_overlay, overlay_child_node |
| dict_impl.rs | ~2000 | PARTIAL | 464–479 (TrieRoot), 280 (root field), 345 (dirty_prefixes), 505–520 (get_root_node), 1874–1970 (owned readers) | Overlay-only struct definition, overlay field in PersistentARTrie |
| dirty_tracking.rs | 158 | DELETE | All 9 public/private functions (42–157) | — |
| disk_load.rs | 1164 | PARTIAL | 89–846 (owned loaders) | enumerate_terms_from_disk, decode surface |
| bucket.rs | ~500 | PARTIAL | insert, insert_key, split* (when orphaned) | from_bytes, len, get_entry, get_suffix, get_value, search, contains, iter, as_bytes, header |
| path_compression.rs | (varies) | VERIFY | common_prefix_len, make_common_prefix (if not used by CX codec) | — |
| serialize_impl.rs | (varies) | DELETE | serialize_node_to_disk (~57) | serialize_node_to_disk_with_value_len |
| persistence_api.rs | (varies) | DELETE | append_batch_mutation_wal_record (~231) | — |
| overlay_checkpoint.rs | (varies) | PARTIAL | next_lsn_at_capture field (64) | serialize_root_value_bytes |
| cursor_iter.rs | (varies) | DELETE | collect_terms_from_cursor, collect_terms_with_cursor_and_arena (~76) | — |
| overlay_fault.rs | 17136 | KEEP | — | bench_enable_eviction, bench_immutable_checkpoint_with_eviction, evictable_node_count, evict_overlay_nodes, load_overlay_node_from_disk |
| lockfree_cas.rs | 1500+ | PARTIAL | owned merge helpers (~1440) | overlay merge helpers |
| parallel_merge.rs | (varies) | COLLAPSE | Line 166: insert_impl owned tail | Replace with overlay merge |
| overlay_write_mode.rs | 82 | DELETE | dead stubs/arms | — |
| arena_iter.rs | (varies) | COLLAPSE | self.root reads (owned tails) | — |
| shared_trait_impl.rs | (varies) | COLLAPSE | insert/insert_with_value/remove/remove_prefix owned tails | Overlay early returns |
| atomic_ops.rs | (varies) | COLLAPSE | get_value_bytes, unrouted_* owned tails | Overlay early returns |
| mmap_ctor.rs | (varies) | C1 only | (BLOCKER#4 fallback-port) | — |
| io_uring_ctor.rs | (varies) | C1 only | (BLOCKER#4 fallback-port) | — |
common_prefix_len / make_common_prefix. If not, DELETE entire file.Confirmed: Byte and char have SEPARATE CheckpointSnapshot structs:
Deleting byte's CheckpointSnapshot.next_lsn_at_capture field does NOT affect char.
Grep confirmed callers in char eviction tests:
Functions bench_enable_eviction, bench_immutable_checkpoint_with_eviction, evictable_node_count are CALLED by char tests and MUST be kept in byte module.
dirty_tracking.rs module (158 lines) is ENTIRELY owned-mutation specific:
Line 166 in parallel_merge.rs calls insert_impl on owned shared_trait_impl. The char variant already uses overlay merge path (need to check persistent_artrie_char/parallel_merge.rs for exact pattern).
Byte owns zero unsafe blocks that are part of owned code:
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |