Use shared quadratic probing for settings.

This commit is contained in:
Jakob Stoklund Olesen
2016-08-18 13:23:46 -07:00
parent 722a3a6ae6
commit f9850b1405

View File

@@ -23,7 +23,7 @@
use std::fmt; use std::fmt;
use std::result; use std::result;
use constant_hash::simple_hash; use constant_hash::{probe, simple_hash};
/// A string-based configurator for settings groups. /// A string-based configurator for settings groups.
/// ///
@@ -75,27 +75,12 @@ impl Builder {
/// Look up a descriptor by name. /// Look up a descriptor by name.
fn lookup(&self, name: &str) -> Result<(usize, detail::Detail)> { fn lookup(&self, name: &str) -> Result<(usize, detail::Detail)> {
let table = self.template.hash_table; match probe(self.template, name, simple_hash(name)) {
let descs = self.template.descriptors; None => Err(Error::BadName),
let mask = table.len() - 1; Some(entry) => {
assert!((mask + 1).is_power_of_two()); let d = &self.template.descriptors[self.template.hash_table[entry] as usize];
Ok((d.offset as usize, d.detail))
let mut idx = simple_hash(name) as usize;
let mut step: usize = 0;
loop {
idx = idx & mask;
let entry = table[idx] as usize;
if entry >= descs.len() {
return Err(Error::BadName);
} }
let desc = &descs[entry];
if desc.name == name {
return Ok((desc.offset as usize, desc.detail));
}
step += 1;
assert!(step <= mask);
idx += step;
} }
} }
} }
@@ -167,6 +152,7 @@ pub type Result<T> = result::Result<T, Error>;
/// code in other modules. /// code in other modules.
pub mod detail { pub mod detail {
use std::fmt; use std::fmt;
use constant_hash;
/// An instruction group template. /// An instruction group template.
pub struct Template { pub struct Template {
@@ -207,6 +193,22 @@ pub mod detail {
} }
} }
/// The template contains a hash table for by-name lookup.
impl<'a> constant_hash::Table<&'a str> for Template {
fn len(&self) -> usize {
self.hash_table.len()
}
fn key(&self, idx: usize) -> Option<&'a str> {
let e = self.hash_table[idx] as usize;
if e < self.descriptors.len() {
Some(self.descriptors[e].name)
} else {
None
}
}
}
/// A setting descriptor holds the information needed to generically set and print a setting. /// A setting descriptor holds the information needed to generically set and print a setting.
/// ///
/// Each settings group will be represented as a constant DESCRIPTORS array. /// Each settings group will be represented as a constant DESCRIPTORS array.