hash_table: add unit test

This commit is contained in:
Alain Zscheile 2023-01-25 17:00:33 +01:00
parent a40017fcf1
commit fbe69f488e
2 changed files with 63 additions and 6 deletions

View file

@ -41,7 +41,7 @@ pub struct Iter<'a> {
chains: core::slice::ChunksExact<'a, u8>,
}
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Value<R> {
pub typ: u32,
pub rest: R,
@ -94,7 +94,7 @@ impl Header {
}
pub fn tabsize(&self) -> usize {
let tmp: usize = 4 + usize::try_from(self.nbuckets).unwrap() + 2 * usize::from(self.nblf);
let tmp: usize = 5 + usize::try_from(self.nbuckets).unwrap() + 2 * usize::from(self.nblf);
4 * tmp + self.settings.chain_entry_size() * usize::try_from(self.nchains).unwrap()
}
}
@ -136,7 +136,7 @@ impl<'a> Ref<'a> {
Some(Ref {
settings: header.settings,
strtab: alldata.get(usize::try_from(header.strtab_link).ok()?..)?,
bloom: &data[16..bloom_end],
bloom: &data[20..bloom_end],
buckets: &data[bloom_end..buckets_end],
chains: &data[buckets_end..chains_end],
})
@ -211,7 +211,7 @@ impl<'a> Iterator for Iter<'a> {
}
}
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct PreEntry<R> {
/// index into the string table corresponding to the entry name
pub name_ix: u32,
@ -225,7 +225,7 @@ pub struct PreEntry<R> {
use alloc::{boxed::Box, vec, vec::Vec};
#[cfg(feature = "alloc")]
pub fn serialize<I, R, O>(
pub fn serialize<I, R>(
strtab: crate::StrtabDescriptorRef<'_>,
nbuckets: u32,
nblf: u16,
@ -340,7 +340,9 @@ where
entry[0..8].copy_from_slice(&u64::to_be_bytes(h));
entry[8..12].copy_from_slice(&u32::to_be_bytes(name_ix));
entry[12..16].copy_from_slice(&u32::to_be_bytes(typ));
entry[16..16 + rest.len()].copy_from_slice(&rest[..]);
if !rest.is_empty() {
entry[16..16 + rest.len()].copy_from_slice(&rest[..]);
}
}
}
@ -349,3 +351,57 @@ where
Some(ret)
}
#[cfg(all(test, feature = "alloc"))]
mod tests {
use super::{Settings, PreEntry};
#[test]
fn simple() {
let strtab = crate::StrtabDescriptorRef {
data: b"\x00a\x00b\x00c\x00d\x00",
location: 0,
};
let sts = Settings {
seed: 0xcafe,
entsize: 0,
blshift: 20,
};
use alloc::{boxed::Box, vec};
let nullslc: Box<[u8]> = [].to_vec().into_boxed_slice();
let blob = super::serialize(strtab, 2, 1, sts, [PreEntry {
name_ix: 1,
typ: 0,
rest: nullslc.clone(),
}, PreEntry {
name_ix: 3,
typ: 1,
rest: nullslc.clone(),
}, PreEntry {
name_ix: 5,
typ: 2,
rest: nullslc.clone(),
}, PreEntry {
name_ix: 7,
typ: 3,
rest: nullslc,
}].into_iter()).expect("unable to serialize hash table");
let mut conc = vec![0u8; 16];
conc[..strtab.data.len()].copy_from_slice(strtab.data);
conc.extend_from_slice(&blob[..]);
core::mem::drop(blob);
let crf = super::Ref::parse(&conc, 1).expect("unable to parse hash table again");
let elem_a = crf.lookup(b"a").expect("unable to retrieve 'b' element");
assert_eq!(elem_a.typ, 0);
let elem_b = crf.lookup(b"b").expect("unable to retrieve 'b' element");
assert_eq!(elem_b.typ, 1);
let elem_c = crf.lookup(b"c").expect("unable to retrieve 'b' element");
assert_eq!(elem_c.typ, 2);
let elem_d = crf.lookup(b"d").expect("unable to retrieve 'b' element");
assert_eq!(elem_d.typ, 3);
assert_eq!(crf.lookup(b"e"), None);
}
}

View file

@ -88,6 +88,7 @@ pub fn decode_location(location: u32) -> Option<usize> {
}
/// A reference to a string table, including its data and location
#[derive(Clone, Copy)]
pub struct StrtabDescriptorRef<'a> {
pub data: &'a [u8],