fn check_simple_ascii_trie<S>(items: &LiteMap<&[u8], usize>, trie: &ZeroTrieSimpleAscii<S>) where
S: AsRef<[u8]> + ?Sized,
{ // Check that each item is in the trie for (k, v) in items.iter() {
assert_eq!(trie.get(k), Some(*v));
} // Check that some items are not in the trie for s in NON_EXISTENT_STRINGS.iter() {
assert_eq!(trie.get(s.as_bytes()), None);
} // Check that the iterator returns items in the same order as the LiteMap
assert!(items
.iter()
.map(|(s, v)| (String::from_utf8(s.to_vec()).unwrap(), *v))
.eq(trie.iter())); // Check that the const builder works let const_trie = ZeroTrieSimpleAscii::try_from_litemap_with_const_builder(items).unwrap();
assert_eq!(trie.as_bytes(), const_trie.as_bytes());
}
fn check_phf_ascii_trie<S>(items: &LiteMap<&[u8], usize>, trie: &ZeroTriePerfectHash<S>) where
S: AsRef<[u8]> + ?Sized,
{ // Check that each item is in the trie for (k, v) in items.iter() {
assert_eq!(trie.get(k), Some(*v));
} // Check that some items are not in the trie for s in NON_EXISTENT_STRINGS.iter() {
assert_eq!(trie.get(s.as_bytes()), None);
} // Check that the iterator returns the contents of the LiteMap // Note: Since the items might not be in order, we collect them into a new LiteMap let recovered_items: LiteMap<_, _> = trie.iter().collect();
assert_eq!(
items.to_borrowed_keys_values::<[u8], usize, Vec<_>>(),
recovered_items.to_borrowed_keys_values()
);
}
fn check_phf_bytes_trie<S>(items: &LiteMap<&[u8], usize>, trie: &ZeroTriePerfectHash<S>) where
S: AsRef<[u8]> + ?Sized,
{ // Check that each item is in the trie for (k, v) in items.iter() {
assert_eq!(trie.get(k), Some(*v), "{k:?}");
} // Check that some items are not in the trie for s in NON_EXISTENT_STRINGS.iter() {
assert_eq!(trie.get(s.as_bytes()), None, "{s:?}");
} // Check that the iterator returns the contents of the LiteMap // Note: Since the items might not be in order, we collect them into a new LiteMap let recovered_items: LiteMap<_, _> = trie.iter().collect();
assert_eq!(
items.to_borrowed_keys_values::<[u8], usize, Vec<_>>(),
recovered_items.to_borrowed_keys_values()
);
}
#[test] fn test_basic() { let lm1a: LiteMap<&[u8], usize> = testdata::basic::DATA_ASCII.iter().copied().collect(); let lm1b: LiteMap<&[u8], usize> = lm1a.to_borrowed_keys(); let lm2: LiteMap<&[u8], usize> = testdata::basic::DATA_UNICODE.iter().copied().collect(); let lm3: LiteMap<&[u8], usize> = testdata::basic::DATA_BINARY.iter().copied().collect();
let expected_bytes = testdata::basic::TRIE_ASCII; let trie = ZeroTrieSimpleAscii::try_from(&lm1a).unwrap();
assert_bytes_eq!(26, trie.as_bytes(), expected_bytes);
check_simple_ascii_trie(&lm1a, &trie);
let trie = ZeroTriePerfectHash::try_from(&lm1b).unwrap();
assert_bytes_eq!(26, trie.as_bytes(), expected_bytes);
check_phf_ascii_trie(&lm1a, &trie);
let expected_bytes = testdata::basic::TRIE_UNICODE; let trie = ZeroTriePerfectHash::try_from(&lm2).unwrap();
assert_bytes_eq!(39, trie.as_bytes(), expected_bytes);
check_phf_bytes_trie(&lm2, &trie);
let expected_bytes = testdata::basic::TRIE_BINARY; let trie = ZeroTriePerfectHash::try_from(&lm3).unwrap();
assert_bytes_eq!(26, trie.as_bytes(), expected_bytes);
check_phf_bytes_trie(&lm3, &trie);
}
#[rustfmt::skip] let expected_bytes = &[ 0b10000000, // value 0 0b11000010, // branch of 2
b'a', //
b'b', // 13, // 0b11000011, // start of 'a' subtree: branch of 3
b'x', //
b'y', //
b'z', // 3, // 5, //
b'b', // 0b10010000, // value 100 (lead) 0x54, // value 100 (trail)
b'c', // 0b10000010, // value 2
b'd', // 0b10000011, // value 3
b'x', // start of 'b' subtree
b'e', // 0b10000100, // value 4 0b11000010, // branch of 2
b'f', //
b'i', // 7, // 0b11000010, // branch of 2
b'g', //
b'h', // 2, // 0b10010011, // value 500 (lead) 0x64, // value 500 (trail) 0b10000110, // value 6 0b10000111, // value 7
b'k', //
b'l', // 0b10001000, // value 8
b'm', // 0b10100001, // span of length 1
utf8_byte!('Κ', 0), // NOTE: all three letters have the same lead byte 0b11000011, // branch of 3
utf8_byte!('Κ', 1),
utf8_byte!('α', 1),
utf8_byte!('η', 1), 21, 27, 0b10110000, // span of length 18 (lead) 0b00000010, // span of length 18 (trail)
utf8_byte!('α', 0),
utf8_byte!('α', 1),
utf8_byte!('λ', 0),
utf8_byte!('λ', 1),
utf8_byte!('η', 0),
utf8_byte!('η', 1),
utf8_byte!('μ', 0),
utf8_byte!('μ', 1),
utf8_byte!('έ', 0),
utf8_byte!('έ', 1),
utf8_byte!('ρ', 0),
utf8_byte!('ρ', 1),
utf8_byte!('α', 0),
utf8_byte!('α', 1),
utf8_byte!('α', 0),
utf8_byte!('α', 1),
utf8_byte!('α', 0),
utf8_byte!('α', 1), 0b10001001, // value 9
b'n', 0b10100010, // span of length 2
utf8_byte!('λ', 0),
utf8_byte!('λ', 1),
b'o', 0b10001010, // value 10 0b10001011, // value 11
]; let trie_phf = ZeroTriePerfectHash::try_from(&litemap).unwrap();
assert_bytes_eq!(73, trie_phf.as_bytes(), expected_bytes);
check_phf_bytes_trie(&litemap, &trie_phf);
}
#[test] fn test_max_branch() { // Evaluate a branch with all 256 possible children letmut litemap: LiteMap<&[u8], usize> = LiteMap::new_vec(); let all_bytes: Vec<u8> = (u8::MIN..=u8::MAX).collect();
assert_eq!(all_bytes.len(), 256); let all_bytes_prefixed: Vec<[u8; 2]> = (u8::MIN..=u8::MAX).map(|x| [b'\0', x]).collect(); for b in all_bytes.iter() {
litemap.insert(core::slice::from_ref(b), *b as usize);
} for s in all_bytes_prefixed.iter() {
litemap.insert(s, s[1] as usize);
} let trie_phf = ZeroTriePerfectHash::try_from(&litemap).unwrap();
assert_eq!(trie_phf.byte_len(), 3042);
check_phf_bytes_trie(&litemap, &trie_phf);
}
#[test] fn test_short_subtags_10pct() { let litemap = strings_to_litemap(testdata::short_subtags_10pct::STRINGS);
let trie = ZeroTrieSimpleAscii::try_from(&litemap).unwrap();
assert_eq!(trie.byte_len(), 1050);
check_simple_ascii_trie(&litemap, &trie);
let litemap_bytes = litemap.to_borrowed_keys::<[u8], Vec<_>>(); let trie_phf = ZeroTriePerfectHash::try_from(&litemap_bytes).unwrap();
assert_eq!(trie_phf.byte_len(), 1100);
check_phf_ascii_trie(&litemap, &trie_phf);
let zhm: zerovec::ZeroMap<[u8], u32> = litemap.iter().map(|(a, b)| (*a, *b as u32)).collect(); let zhm_buf = postcard::to_allocvec(&zhm).unwrap();
assert_eq!(zhm_buf.len(), 1890);
let zhm: zerovec::ZeroMap<[u8], u8> = litemap.iter().map(|(a, b)| (*a, *b as u8)).collect(); let zhm_buf = postcard::to_allocvec(&zhm).unwrap();
assert_eq!(zhm_buf.len(), 1326);
let zhm: zerovec::ZeroHashMap<[u8], u32> =
litemap.iter().map(|(a, b)| (*a, *b as u32)).collect(); let zhm_buf = postcard::to_allocvec(&zhm).unwrap();
assert_eq!(zhm_buf.len(), 3396);
let zhm: zerovec::ZeroHashMap<[u8], u8> = litemap.iter().map(|(a, b)| (*a, *b as u8)).collect(); let zhm_buf = postcard::to_allocvec(&zhm).unwrap();
assert_eq!(zhm_buf.len(), 2832);
}
#[test] fn test_short_subtags() { let litemap = strings_to_litemap(testdata::short_subtags::STRINGS);
let trie = ZeroTrieSimpleAscii::try_from(&litemap).unwrap();
assert_eq!(trie.byte_len(), 8793);
check_simple_ascii_trie(&litemap, &trie);
let litemap_bytes = litemap.to_borrowed_keys::<[u8], Vec<_>>(); let trie_phf = ZeroTriePerfectHash::try_from(&litemap_bytes).unwrap();
assert_eq!(trie_phf.byte_len(), 9400);
check_phf_ascii_trie(&litemap, &trie_phf);
let zm: zerovec::ZeroMap<[u8], u32> = litemap.iter().map(|(a, b)| (*a, *b as u32)).collect(); let zhm_buf = postcard::to_allocvec(&zm).unwrap();
assert_eq!(zhm_buf.len(), 18931);
let zm: zerovec::ZeroMap<[u8], u8> = litemap.iter().map(|(a, b)| (*a, *b as u8)).collect(); let zhm_buf = postcard::to_allocvec(&zm).unwrap();
assert_eq!(zhm_buf.len(), 13300);
let zhm: zerovec::ZeroHashMap<[u8], u32> =
litemap.iter().map(|(a, b)| (*a, *b as u32)).collect(); let zhm_buf = postcard::to_allocvec(&zhm).unwrap();
assert_eq!(zhm_buf.len(), 33949);
let zhm: zerovec::ZeroHashMap<[u8], u8> = litemap.iter().map(|(a, b)| (*a, *b as u8)).collect(); let zhm_buf = postcard::to_allocvec(&zhm).unwrap();
assert_eq!(zhm_buf.len(), 28318);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.