Use shared quadratic probing for settings.
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user