1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//! BTI (Big Trie Index) parser implementation
//!
//! This module provides parsing capabilities for BTI format components:
//! - Partitions.db BTI index for partition lookups
//! - Rows.db BTI index for clustering key lookups within partitions
//!
//! ## Node-type encoding (TrieNode.java, Cassandra 5.0)
//!
//! The high nibble (bits 7-4) of every node's first byte is a 4-bit ordinal that
//! selects one of up to 16 concrete trie-node subtypes:
//!
//! | Nibble | Java class | Rust category | Pointer size |
//! |--------|---------------------|------------------|--------------|
//! | 0 | PayloadOnly | `PayloadOnly` | — |
//! | 1 | SingleNoPayload4 | `Single` | 4-bit delta |
//! | 2 | Single8 | `Single` | 1 byte |
//! | 3 | SingleNoPayload12 | `Single` | 12-bit delta |
//! | 4 | Single16 | `Single` | 2 bytes |
//! | 5 | Sparse8 | `Sparse` | 1 byte |
//! | 6 | Sparse12 | `Sparse` | 12-bit |
//! | 7 | Sparse16 | `Sparse` | 2 bytes |
//! | 8 | Sparse24 | `Sparse` | 3 bytes |
//! | 9 | Sparse40 | `Sparse` | 5 bytes |
//! | 10 | Dense12 | `Dense` | 12-bit |
//! | 11 | Dense16 | `Dense` | 2 bytes |
//! | 12 | Dense24 | `Dense` | 3 bytes |
//! | 13 | Dense32 | `Dense` | 4 bytes |
//! | 14 | Dense40 | `Dense` | 5 bytes |
//! | 15 | LongDense | `Dense` | 8 bytes |
//!
//! The low nibble (bits 3-0) carries payload flags; a non-zero value means a
//! payload follows immediately after the node's fixed-size header.
//!
//! All transition deltas are stored as *backward* distances (the child always
//! appears earlier in the file), so the absolute child position is:
//! `child_pos = parent_pos - delta`
//!
//! The "no-payload" Single variants (nibbles 1 and 3) encode the delta in the
//! low nibble / low 12 bits of the first two bytes respectively, and cannot
//! carry a payload (their payload-flag nibble is always 0).
//!
//! ## Module layout (issue #1119, epic #1116)
//!
//! - [`node_decode`] — node-type nibble classification + the 16-ordinal
//! `parse_bti_node` dispatcher and its byte/12-bit readers.
//! - [`partitions`] — `Partitions.db` leaf payload decode, trie walk, and
//! point lookup (`lookup_partition_in_bti_file`).
//! - [`traversal`] — depth-capped in-order DFS primitives + the headerless
//! partition iterator.
//! - [`rows`] — `Rows.db` `RowIndexReader.IndexInfo` / `TrieIndexEntry`
//! decode, row iteration, and range-block selection.
//! - [`rows_floor`] — O(key-length) `separatorFloor` / strict-ceiling `Rows.db`
//! walks (issue #1647 / L1) + the shared per-node payload primitive.
//! - [`encoding`] — Cassandra OSS50 byte-comparable clustering-bound encoders.
// O(depth) next-partition (in-order successor) walk (issue #2058). Consumed only by
// the reader's within-SSTable seek bound (`partition_successor` / `point_compaction`),
// compiled out under `tombstones` like the seek path it serves.
// Public surface — re-exported unchanged so `bti::parser::X` paths keep working.
pub use ;
pub use ;
// Crate-internal uncounted encoder (issue #2058): the successor walk encodes the SAME
// key a point read already hashed, so it must not inflate C4's `KEY_HASH_CALLS`.
// Consumed only by the seek-bound path, compiled out under `tombstones`.
pub use encode_partition_key_for_bti_trie_uncounted;
pub use ;
// Structural row-index-root validation (issue #3002): the validated-root
// capability type plus the rejection reason a clustering reader reports when it
// takes the honest full-partition fallback.
pub use ;
// Crate-internal uncounted `TrieIndexEntry.deserialize` (issue #2058): the successor
// walk resolves a WIDE successor's `data_position` for the seek END bound, which must
// not bump the L1 clustering-window `ROWS_DB_ENTRY_RESOLVES` invariant. Also used by
// `verify` (issue #3002), which is NOT compiled out under `tombstones` — hence no cfg
// gate here.
pub use resolve_rows_db_entry_uncounted;
// Crate-internal only: the zero-copy slice walker's sole consumers are the
// SSTable reader (partition_lookup / data_access::bti). Kept off the public
// semver surface (rust-reviewer #1574). `lookup_partition_in_bti_slice` takes a
// PRE-ENCODED byte-comparable key so callers hoist the Murmur3 hash + encoding
// (issue #1575 / C4): every BTI partition lookup now encodes then walks via this
// single primitive.
pub use lookup_partition_in_bti_slice;
// Crate-internal next-partition successor walk (issue #2058). Consumed only by the
// reader's seek-bound path (compiled out under `tombstones`); kept off the public
// semver surface like the point slice walker.
pub use partition_successor_in_bti_slice;
// Test-only hook for the issue #2058 real-fixture oracle (local walk == old DFS).
pub use partition_successor_in_bti_slice_for_test;
// Test-only hooks for the issue #1650 (L3) targeted-descent counter invariants.
pub use ;
// Crate-internal only: the O(key-length) Rows.db floor/ceiling walks (issue #1647
// / L1). Their sole consumer is the SSTable reader's clustering-window path
// (data_access::bti), which is compiled out under `tombstones`; kept off the
// public semver surface like the slice walker.
pub use ;
// Test-only hooks for the issue #3002 real-fixture window oracle (block 0 is a
// STORED floor once the root base is correct; the END bound is the half the floor
// walk alone cannot prove).
pub use ;
pub use ;