core: simplify and fix hash table iterator
This commit is contained in:
parent
d1fabb4804
commit
3758f94b03
|
@ -29,7 +29,7 @@ pub struct Ref<'a> {
|
|||
#[derive(Clone)]
|
||||
pub struct Iter<'a> {
|
||||
strtab: &'a [u8],
|
||||
chains: &'a [u8],
|
||||
chains: core::slice::ChunksExact<'a, u8>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
|
@ -41,7 +41,7 @@ pub struct Value<R> {
|
|||
impl Settings {
|
||||
#[inline]
|
||||
pub fn chain_entry_size(&self) -> usize {
|
||||
16 * (1 + usize::from(self.entsize))
|
||||
(1 + usize::from(self.entsize)).checked_mul(16).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,6 +114,11 @@ impl<'a> Ref<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
fn get_e_name<'s>(strtab: &'s [u8], sel: &[u8]) -> Option<&'s [u8]> {
|
||||
let e_name_ix = usize::try_from(u32::from_be_bytes(sel[8..12].try_into().unwrap())).ok()?;
|
||||
Some(trunc_key_at0(strtab.get(e_name_ix..)?))
|
||||
}
|
||||
|
||||
/// NOTE: the key is truncated after the first null byte
|
||||
pub fn lookup(&self, key: &[u8]) -> Option<Value<&'a [u8]>> {
|
||||
let key = trunc_key_at0(key);
|
||||
|
@ -135,15 +140,13 @@ impl<'a> Ref<'a> {
|
|||
|
||||
for sel in self
|
||||
.chains
|
||||
.chunks(self.settings.chain_entry_size())
|
||||
.chunks_exact(self.settings.chain_entry_size())
|
||||
.skip(chain_start)
|
||||
{
|
||||
assert!(sel.len() >= 16);
|
||||
let e_hash = u64::from_be_bytes(sel[0..8].try_into().unwrap());
|
||||
if (h | 1) == (e_hash | 1) {
|
||||
let e_name_ix =
|
||||
usize::try_from(u32::from_be_bytes(sel[8..12].try_into().unwrap())).ok()?;
|
||||
let e_name = trunc_key_at0(self.strtab.get(e_name_ix..)?);
|
||||
let e_name = Self::get_e_name(self.strtab, sel)?;
|
||||
|
||||
if e_name == key {
|
||||
return Some(Value::parse(sel).unwrap());
|
||||
|
@ -161,7 +164,7 @@ impl<'a> Ref<'a> {
|
|||
pub fn iter(&self) -> Iter<'a> {
|
||||
Iter {
|
||||
strtab: self.strtab,
|
||||
chains: self.chains,
|
||||
chains: self.chains.chunks_exact(self.settings.chain_entry_size()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -170,13 +173,8 @@ impl<'a> Iterator for Iter<'a> {
|
|||
type Item = (u64, &'a [u8], Value<&'a [u8]>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.chains.len() < 32 {
|
||||
return None;
|
||||
}
|
||||
let (i, j) = self.chains.split_at(32);
|
||||
self.chains = j;
|
||||
let e_name_ix = usize::try_from(u32::from_be_bytes(i[8..12].try_into().unwrap())).ok()?;
|
||||
let e_name = trunc_key_at0(self.strtab.get(e_name_ix..)?);
|
||||
let i = self.chains.next()?;
|
||||
let e_name = Ref::get_e_name(self.strtab, i)?;
|
||||
Some((
|
||||
u64::from_be_bytes(i[0..8].try_into().unwrap()),
|
||||
e_name,
|
||||
|
|
Loading…
Reference in a new issue