use super::CARTNode;
fn leaf(value: u64) -> Box<CARTNode> {
Box::new(CARTNode::new_leaf(value))
}
#[test]
fn grow_node4_to_node16_preserves_children() {
let node = CARTNode::Node4 {
num_children: 4,
keys: [30, 10, 40, 20],
children: [
Some(leaf(300)),
Some(leaf(100)),
Some(leaf(400)),
Some(leaf(200)),
],
};
let grown = node.grow_to_node16();
match &grown {
CARTNode::Node16 {
num_children,
keys,
children,
} => {
assert_eq!(*num_children, 4);
assert_eq!(&keys[..4], &[10, 20, 30, 40]);
for (i, expected_val) in [100u64, 200, 300, 400].iter().enumerate() {
let child = children[i].as_ref().unwrap();
let mut vals = Vec::new();
child.collect_all(&mut vals);
assert_eq!(vals, vec![*expected_val]);
}
for slot in &children[4..] {
assert!(slot.is_none());
}
}
other => panic!("Expected Node16, got {other:?}"),
}
}
#[test]
fn grow_node4_to_node16_partial_fill() {
let node = CARTNode::Node4 {
num_children: 2,
keys: [5, 3, 0, 0],
children: [Some(leaf(50)), Some(leaf(30)), None, None],
};
let grown = node.grow_to_node16();
match &grown {
CARTNode::Node16 {
num_children,
keys,
children,
} => {
assert_eq!(*num_children, 2);
assert_eq!(&keys[..2], &[3, 5]);
assert!(children[0].is_some());
assert!(children[1].is_some());
for slot in &children[2..] {
assert!(slot.is_none());
}
}
other => panic!("Expected Node16, got {other:?}"),
}
}
#[test]
fn grow_node16_to_node48_preserves_children() {
let mut keys = [0u8; 16];
let mut children: [Option<Box<CARTNode>>; 16] = Default::default();
for i in 0u8..16 {
let key = i * 10; keys[i as usize] = key;
children[i as usize] = Some(leaf(u64::from(key) * 100));
}
let node = CARTNode::Node16 {
num_children: 16,
keys,
children,
};
let grown = node.grow_to_node48();
match &grown {
CARTNode::Node48 {
num_children,
keys: idx,
children: slots,
} => {
assert_eq!(*num_children, 16);
for i in 0u8..16 {
let key_byte = i * 10;
let slot = idx[key_byte as usize];
assert_ne!(slot, 255, "key {key_byte} should have a slot");
let child = slots[slot as usize].as_ref().unwrap();
let mut vals = Vec::new();
child.collect_all(&mut vals);
assert_eq!(vals, vec![u64::from(key_byte) * 100]);
}
}
other => panic!("Expected Node48, got {other:?}"),
}
}
#[test]
fn grow_node16_to_node48_empty_slots_are_255() {
let mut keys = [0u8; 16];
let mut children: [Option<Box<CARTNode>>; 16] = Default::default();
keys[0] = 5;
keys[1] = 100;
keys[2] = 200;
children[0] = Some(leaf(1));
children[1] = Some(leaf(2));
children[2] = Some(leaf(3));
let node = CARTNode::Node16 {
num_children: 3,
keys,
children,
};
let grown = node.grow_to_node48();
match &grown {
CARTNode::Node48 {
num_children, keys, ..
} => {
assert_eq!(*num_children, 3);
let occupied: [usize; 3] = [5, 100, 200];
for (byte, &key_val) in keys.iter().enumerate() {
if occupied.contains(&byte) {
assert_ne!(key_val, 255);
} else {
assert_eq!(key_val, 255, "byte {byte} should be empty (255)");
}
}
}
other => panic!("Expected Node48, got {other:?}"),
}
}
#[test]
fn grow_node48_to_node256_preserves_children() {
let mut keys = [255u8; 256];
let mut children: [Option<Box<CARTNode>>; 48] = std::array::from_fn(|_| None);
let entries: [(u8, u64); 5] = [(0, 10), (42, 420), (128, 1280), (200, 2000), (255, 2550)];
for (slot, &(byte, val)) in entries.iter().enumerate() {
keys[byte as usize] = slot as u8;
children[slot] = Some(leaf(val));
}
let node = CARTNode::Node48 {
num_children: 5,
keys,
children,
};
let grown = node.grow_to_node256();
match &grown {
CARTNode::Node256 {
num_children,
children,
} => {
assert_eq!(*num_children, 5);
for &(byte, val) in &entries {
let child = children[byte as usize].as_ref().unwrap();
let mut vals = Vec::new();
child.collect_all(&mut vals);
assert_eq!(vals, vec![val], "child at byte {byte} mismatch");
}
let populated = children.iter().filter(|c| c.is_some()).count();
assert_eq!(populated, 5);
}
other => panic!("Expected Node256, got {other:?}"),
}
}
#[test]
fn grow_to_node16_on_node16_returns_clone() {
let node = CARTNode::Node16 {
num_children: 1,
keys: {
let mut k = [0u8; 16];
k[0] = 42;
k
},
children: {
let mut c: [Option<Box<CARTNode>>; 16] = Default::default();
c[0] = Some(leaf(99));
c
},
};
let result = node.grow_to_node16();
assert!(matches!(
result,
CARTNode::Node16 {
num_children: 1,
..
}
));
}
#[test]
fn grow_to_node16_on_leaf_returns_clone() {
let node = CARTNode::new_leaf(7);
let result = node.grow_to_node16();
assert!(matches!(result, CARTNode::Leaf { .. }));
}
#[test]
fn grow_to_node48_on_node4_returns_clone() {
let node = CARTNode::Node4 {
num_children: 1,
keys: [10, 0, 0, 0],
children: [Some(leaf(1)), None, None, None],
};
let result = node.grow_to_node48();
assert!(matches!(
result,
CARTNode::Node4 {
num_children: 1,
..
}
));
}
#[test]
fn grow_to_node256_on_node16_returns_clone() {
let node = CARTNode::Node16 {
num_children: 0,
keys: [0u8; 16],
children: Default::default(),
};
let result = node.grow_to_node256();
assert!(matches!(
result,
CARTNode::Node16 {
num_children: 0,
..
}
));
}