use super::*;
fn make_inode_buf(symbols_offset: usize, symbols: &[u8]) -> Vec<u8> {
let total = symbols_offset + symbols.len();
let mut buf = vec![0u8; total.max(16).max(32)];
buf[0] = symbols.len() as u8;
for (i, &s) in symbols.iter().enumerate() {
buf[symbols_offset + i] = s;
}
buf
}
fn make_disc_buf(discs: &[u8]) -> Vec<u8> {
let len = discs.len();
let mut buf = vec![0u8; len.max(16) + 32];
buf[..len].copy_from_slice(discs);
buf
}
#[test]
fn test_inode_find_child_basic() {
let symbols_offset = 2;
let symbols = [10u8, 20, 30, 40, 50, 60];
let buf = make_inode_buf(symbols_offset, &symbols);
assert_eq!(
inode_find_child(buf.as_ptr(), symbols_offset, 6, 10),
Some(0)
);
assert_eq!(
inode_find_child(buf.as_ptr(), symbols_offset, 6, 30),
Some(2)
);
assert_eq!(
inode_find_child(buf.as_ptr(), symbols_offset, 6, 60),
Some(5)
);
assert_eq!(
inode_find_child(buf.as_ptr(), symbols_offset, 6, 15),
None
);
assert_eq!(
inode_find_child(buf.as_ptr(), symbols_offset, 6, 5),
None
);
assert_eq!(
inode_find_child(buf.as_ptr(), symbols_offset, 6, 65),
None
);
}
#[test]
fn test_inode_find_child_min_count() {
let symbols_offset = 2;
let buf = make_inode_buf(symbols_offset, &[100, 200]);
assert_eq!(
inode_find_child(buf.as_ptr(), symbols_offset, 2, 100),
Some(0)
);
assert_eq!(
inode_find_child(buf.as_ptr(), symbols_offset, 2, 200),
Some(1)
);
assert_eq!(
inode_find_child(buf.as_ptr(), symbols_offset, 2, 150),
None
);
}
#[test]
fn test_inode_find_child_boundary_bytes() {
let symbols_offset = 2;
for &byte in &[0x00, 0x7F, 0x80, 0xFF] {
let buf = make_inode_buf(symbols_offset, &[byte, byte.wrapping_add(1)]);
assert_eq!(
inode_find_child(buf.as_ptr(), symbols_offset, 2, byte),
Some(0)
);
}
}
#[test]
fn test_inode_find_child_lower_bound_basic() {
let symbols_offset = 2;
let symbols = [10u8, 20, 30, 40, 50, 60];
let buf = make_inode_buf(symbols_offset, &symbols);
assert_eq!(
inode_find_child_lower_bound(buf.as_ptr(), symbols_offset, 6, 10),
0
);
assert_eq!(
inode_find_child_lower_bound(buf.as_ptr(), symbols_offset, 6, 30),
2
);
assert_eq!(
inode_find_child_lower_bound(buf.as_ptr(), symbols_offset, 6, 60),
5
);
assert_eq!(
inode_find_child_lower_bound(buf.as_ptr(), symbols_offset, 6, 15),
1
);
assert_eq!(
inode_find_child_lower_bound(buf.as_ptr(), symbols_offset, 6, 5),
0
);
assert_eq!(
inode_find_child_lower_bound(buf.as_ptr(), symbols_offset, 6, 65),
6
);
}
#[test]
fn test_inode_find_child_lower_bound_boundary_bytes() {
let symbols_offset = 2;
let buf = make_inode_buf(symbols_offset, &[0x00, 0x7F, 0x80, 0xFF]);
assert_eq!(
inode_find_child_lower_bound(buf.as_ptr(), symbols_offset, 4, 0x00),
0
);
assert_eq!(
inode_find_child_lower_bound(buf.as_ptr(), symbols_offset, 4, 0x7F),
1
);
assert_eq!(
inode_find_child_lower_bound(buf.as_ptr(), symbols_offset, 4, 0x80),
2
);
assert_eq!(
inode_find_child_lower_bound(buf.as_ptr(), symbols_offset, 4, 0xFF),
3
);
assert_eq!(
inode_find_child_lower_bound(buf.as_ptr(), symbols_offset, 4, 0x40),
1
);
assert_eq!(
inode_find_child_lower_bound(buf.as_ptr(), symbols_offset, 4, 0x90),
3
);
}
#[test]
fn test_hnode_find_child_basic() {
let discs: Vec<u8> = (10..=70).step_by(10).collect();
let buf = make_disc_buf(&discs);
assert_eq!(hnode_find_child(buf.as_ptr(), 7, 10), Some(0));
assert_eq!(hnode_find_child(buf.as_ptr(), 7, 40), Some(3));
assert_eq!(hnode_find_child(buf.as_ptr(), 7, 70), Some(6));
assert_eq!(hnode_find_child(buf.as_ptr(), 7, 15), None);
assert_eq!(hnode_find_child(buf.as_ptr(), 7, 5), None);
assert_eq!(hnode_find_child(buf.as_ptr(), 7, 75), None);
}
#[test]
fn test_hnode_find_child_chunk_boundaries() {
let discs16: Vec<u8> = (0..16).map(|i| i * 10).collect();
let buf16 = make_disc_buf(&discs16);
assert_eq!(hnode_find_child(buf16.as_ptr(), 16, 0), Some(0));
assert_eq!(hnode_find_child(buf16.as_ptr(), 16, 150), Some(15));
assert_eq!(hnode_find_child(buf16.as_ptr(), 16, 85), None);
let discs17: Vec<u8> = (0..17).map(|i| i * 10).collect();
let buf17 = make_disc_buf(&discs17);
assert_eq!(hnode_find_child(buf17.as_ptr(), 17, 160), Some(16));
let discs31: Vec<u8> = (0..31).map(|i| i * 8).collect();
let buf31 = make_disc_buf(&discs31);
assert_eq!(hnode_find_child(buf31.as_ptr(), 31, 0), Some(0));
assert_eq!(hnode_find_child(buf31.as_ptr(), 31, 240), Some(30));
}
#[test]
fn test_hnode_find_child_boundary_bytes() {
let discs = [0x00, 0x40, 0x7F, 0x80, 0xC0, 0xFF];
let buf = make_disc_buf(&discs);
for &byte in &discs {
assert_eq!(
hnode_find_child(buf.as_ptr(), discs.len(), byte),
Some(discs.iter().position(|&d| d == byte).unwrap())
);
}
}
#[test]
fn test_hnode_find_child_lower_bound_basic() {
let discs: Vec<u8> = (10..=70).step_by(10).collect();
let buf = make_disc_buf(&discs);
assert_eq!(hnode_find_child_lower_bound(buf.as_ptr(), 7, 10), 0);
assert_eq!(hnode_find_child_lower_bound(buf.as_ptr(), 7, 40), 3);
assert_eq!(hnode_find_child_lower_bound(buf.as_ptr(), 7, 70), 6);
assert_eq!(hnode_find_child_lower_bound(buf.as_ptr(), 7, 15), 1);
assert_eq!(hnode_find_child_lower_bound(buf.as_ptr(), 7, 25), 2);
assert_eq!(hnode_find_child_lower_bound(buf.as_ptr(), 7, 5), 0);
assert_eq!(hnode_find_child_lower_bound(buf.as_ptr(), 7, 75), 7);
}
#[test]
fn test_hnode_find_child_lower_bound_boundary_bytes() {
let discs = [0x00, 0x40, 0x7F, 0x80, 0xC0, 0xFF];
let buf = make_disc_buf(&discs);
assert_eq!(hnode_find_child_lower_bound(buf.as_ptr(), 6, 0x40), 1);
assert_eq!(hnode_find_child_lower_bound(buf.as_ptr(), 6, 0x7F), 2);
assert_eq!(hnode_find_child_lower_bound(buf.as_ptr(), 6, 0x80), 3);
assert_eq!(hnode_find_child_lower_bound(buf.as_ptr(), 6, 0x90), 4);
assert_eq!(hnode_find_child_lower_bound(buf.as_ptr(), 6, 0xFF), 5);
}
#[test]
fn test_children_mask() {
let mut children = [0u32; 16];
assert_eq!(children_mask(&children), 0);
children[0] = 1;
assert_eq!(children_mask(&children), 0b0000_0000_0000_0001);
children[7] = 42;
assert_eq!(children_mask(&children), 0b0000_0000_1000_0001);
children[15] = 255;
assert_eq!(children_mask(&children), 0b1000_0000_1000_0001);
for i in 0..16 {
children[i] = (i + 1) as u32;
}
assert_eq!(children_mask(&children), 0xFFFF);
}
#[test]
fn test_children_mask_u16() {
let mut children = [0u16; 16];
assert_eq!(children_mask_u16(&children), 0);
children[0] = 1;
assert_eq!(children_mask_u16(&children), 0b0000_0000_0000_0001);
children[7] = 42;
assert_eq!(children_mask_u16(&children), 0b0000_0000_1000_0001);
children[15] = 255;
assert_eq!(children_mask_u16(&children), 0b1000_0000_1000_0001);
for i in 0..16 {
children[i] = (i + 1) as u16;
}
assert_eq!(children_mask_u16(&children), 0xFFFF);
}
#[test]
fn test_children_mask_u64() {
let mut children = [0u64; 16];
assert_eq!(children_mask_u64(&children), 0);
children[0] = 1;
assert_eq!(children_mask_u64(&children), 0b0000_0000_0000_0001);
children[7] = 42;
assert_eq!(children_mask_u64(&children), 0b0000_0000_1000_0001);
children[15] = 255;
assert_eq!(children_mask_u64(&children), 0b1000_0000_1000_0001);
for i in 0..16 {
children[i] = (i + 1) as u64;
}
assert_eq!(children_mask_u64(&children), 0xFFFF);
}
#[test]
fn test_children_mask_u8() {
let mut children = [0u8; 16];
assert_eq!(children_mask_u8(&children), 0);
children[0] = 1;
assert_eq!(children_mask_u8(&children), 0b0000_0000_0000_0001);
children[7] = 42;
assert_eq!(children_mask_u8(&children), 0b0000_0000_1000_0001);
children[15] = 255;
assert_eq!(children_mask_u8(&children), 0b1000_0000_1000_0001);
for i in 0..16 {
children[i] = (i + 1) as u8;
}
assert_eq!(children_mask_u8(&children), 0xFFFF);
}
#[test]
fn test_hnode_large_discriminants() {
let discs: Vec<u8> = (0..32).collect();
let buf = make_disc_buf(&discs);
for i in 0u8..32 {
assert_eq!(hnode_find_child(buf.as_ptr(), 32, i), Some(i as usize));
assert_eq!(hnode_find_child_lower_bound(buf.as_ptr(), 32, i), i as usize);
}
assert_eq!(hnode_find_child(buf.as_ptr(), 32, 32), None);
assert_eq!(hnode_find_child_lower_bound(buf.as_ptr(), 32, 32), 32);
}