Skip to content

Commit b1f637f

Browse files
authored
bugfix: Inconsistent chunking defaults between node.rs constants and TreeConfig::default() (#180)
1 parent 8919dba commit b1f637f

2 files changed

Lines changed: 37 additions & 28 deletions

File tree

src/config.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,29 @@ pub struct TreeConfig<const N: usize> {
3030
}
3131

3232
impl<const N: usize> Default for TreeConfig<N> {
33+
/// Default tuning for the probabilistic chunker.
34+
///
35+
/// The chunker fires a split whenever the rolling hash matches `pattern`. With
36+
/// `pattern = 0b11111111` (eight `1` bits) the probability of a split at any
37+
/// given position is `1 / 2^8 = 1/256`, so the **expected** number of entries
38+
/// per leaf is ~256. Smaller patterns (fewer `1` bits) give smaller, more
39+
/// numerous nodes; larger patterns give fewer, larger nodes.
40+
///
41+
/// `min_chunk_size` is the rolling-hash window: a node will not split until
42+
/// it holds at least this many entries.
43+
///
44+
/// `max_chunk_size` is a hard safety cap measured in **entries**. It is set
45+
/// to ~16× the expected chunk size so it never fires on well-distributed
46+
/// data, but still prevents pathological runaway nodes on low-entropy or
47+
/// adversarial inputs. Note this is not a byte cap — see the documentation
48+
/// on storing large values inline.
3349
fn default() -> Self {
3450
TreeConfig {
3551
base: 257,
3652
modulus: 1_000_000_007,
37-
min_chunk_size: 2,
38-
max_chunk_size: 16 * 1024,
39-
pattern: 0b11,
53+
min_chunk_size: 8,
54+
max_chunk_size: 4096,
55+
pattern: 0b11111111,
4056
root_hash: None,
4157
key_schema: None,
4258
value_schema: None,

src/node.rs

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ limitations under the License.
1313
*/
1414
#![allow(clippy::too_many_arguments)]
1515

16+
use crate::config::TreeConfig;
1617
use crate::digest::ValueDigest;
1718
use crate::encoding::EncodingType;
1819
use crate::proof::Proof;
@@ -28,20 +29,10 @@ use twox_hash::XxHash64;
2829
const INIT_LEVEL: u8 = 0;
2930
/// seed for the hash function
3031
const HASH_SEED: u64 = 0;
31-
/// default base for the rolling hash
32-
const DEFAULT_BASE: u64 = 257;
33-
/// default modulus for the rolling hash
34-
const DEFAULT_MOD: u64 = 1_000_000_007;
35-
/// min_chunk_size also known as the window size of the rolling hash
36-
const DEFAULT_MIN_CHUNK_SIZE: usize = 8;
37-
/// max_chunk_size is the maximum number of key-value pairs in a node
38-
const DEFAULT_MAX_CHUNK_SIZE: usize = 1024 * 1024;
39-
40-
/// The default pattern is 0b11, which is used to determine the split points
41-
/// The number of bit 1 determines the probability of split,
42-
/// e.g., 0b11 has a higher probability of split than 0b1111
43-
/// default pattern is 0b111111 (value=63)
44-
const DEFAULT_PATTERN: u64 = 0b111111;
32+
33+
// Chunking defaults (base, modulus, min_chunk_size, max_chunk_size, pattern) live
34+
// on `TreeConfig::default()` in `crate::config`. `ProllyNode::default()` and
35+
// `ProllyNodeBuilder::default()` read from there so there is one source of truth.
4536

4637
/// Trait representing a node with a fixed size N.
4738
/// This trait provides methods for inserting, deleting, and finding key-value pairs in the node.
@@ -170,18 +161,19 @@ pub struct ProllyNode<const N: usize> {
170161

171162
impl<const N: usize> Default for ProllyNode<N> {
172163
fn default() -> Self {
164+
let cfg = TreeConfig::<N>::default();
173165
ProllyNode {
174166
keys: Vec::new(),
175167
key_schema: None,
176168
values: Vec::new(),
177169
value_schema: None,
178170
is_leaf: true,
179-
level: 0,
180-
base: DEFAULT_BASE,
181-
modulus: DEFAULT_MOD,
182-
min_chunk_size: DEFAULT_MIN_CHUNK_SIZE,
183-
max_chunk_size: DEFAULT_MAX_CHUNK_SIZE,
184-
pattern: DEFAULT_PATTERN,
171+
level: INIT_LEVEL,
172+
base: cfg.base,
173+
modulus: cfg.modulus,
174+
min_chunk_size: cfg.min_chunk_size,
175+
max_chunk_size: cfg.max_chunk_size,
176+
pattern: cfg.pattern,
185177
split: false,
186178
merged: false,
187179
encode_types: Vec::new(),
@@ -204,16 +196,17 @@ pub struct ProllyNodeBuilder<const N: usize> {
204196

205197
impl<const N: usize> Default for ProllyNodeBuilder<N> {
206198
fn default() -> Self {
199+
let cfg = TreeConfig::<N>::default();
207200
ProllyNodeBuilder {
208201
keys: Vec::new(),
209202
values: Vec::new(),
210203
is_leaf: true,
211204
level: INIT_LEVEL,
212-
base: DEFAULT_BASE,
213-
modulus: DEFAULT_MOD,
214-
min_chunk_size: DEFAULT_MIN_CHUNK_SIZE,
215-
max_chunk_size: DEFAULT_MAX_CHUNK_SIZE,
216-
pattern: DEFAULT_PATTERN,
205+
base: cfg.base,
206+
modulus: cfg.modulus,
207+
min_chunk_size: cfg.min_chunk_size,
208+
max_chunk_size: cfg.max_chunk_size,
209+
pattern: cfg.pattern,
217210
}
218211
}
219212
}

0 commit comments

Comments
 (0)