Skip to content

Commit

Permalink
Auto merge of #238 - leops:try_static, r=jdm
Browse files Browse the repository at this point in the history
Add an Atom::try_static method

This methods returns a new static Atom, or None if the provided string is not present in the static table. This is an optimization when using this library to speed up matching against a large table of static atoms, as it allows to skip locking the global table and inserting the new string when the match is going to fail anyway.

I'm not too sure about the name of the method but nothing better comes to mind right now, and same goes for the specifics of the implementation (I moved the hash calculation to a private method to limit code duplication but it's only three lines so it's probably not that important, plus returning the Hashes in Result::Err seems dubious)
  • Loading branch information
bors-servo authored Apr 20, 2021
2 parents 82ac0d9 + c057dde commit 0cf93bb
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 8 deletions.
6 changes: 6 additions & 0 deletions integration-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,12 @@ fn test_from_string() {
assert!(Atom::from("camembert".to_owned()) == Atom::from("camembert"));
}

#[test]
fn test_try_static() {
assert!(Atom::try_static("head").is_some());
assert!(Atom::try_static("not in the static table").is_none());
}

#[cfg(all(test, feature = "unstable"))]
#[path = "bench.rs"]
mod bench;
26 changes: 18 additions & 8 deletions src/atom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,22 @@ impl<Static: StaticAtomSet> Atom<Static> {
_ => unsafe { debug_unreachable!() },
}
}

pub fn try_static(string_to_add: &str) -> Option<Self> {
Self::try_static_internal(string_to_add).ok()
}

fn try_static_internal(string_to_add: &str) -> Result<Self, phf_shared::Hashes> {
let static_set = Static::get();
let hash = phf_shared::hash(&*string_to_add, &static_set.key);
let index = phf_shared::get_index(&hash, static_set.disps, static_set.atoms.len());

if static_set.atoms[index as usize] == string_to_add {
Ok(Self::pack_static(index))
} else {
Err(hash)
}
}
}

impl<Static: StaticAtomSet> Default for Atom<Static> {
Expand All @@ -170,13 +186,7 @@ impl<Static: StaticAtomSet> Hash for Atom<Static> {

impl<'a, Static: StaticAtomSet> From<Cow<'a, str>> for Atom<Static> {
fn from(string_to_add: Cow<'a, str>) -> Self {
let static_set = Static::get();
let hash = phf_shared::hash(&*string_to_add, &static_set.key);
let index = phf_shared::get_index(&hash, static_set.disps, static_set.atoms.len());

if static_set.atoms[index as usize] == string_to_add {
Self::pack_static(index)
} else {
Self::try_static_internal(&*string_to_add).unwrap_or_else(|hash| {
let len = string_to_add.len();
if len <= MAX_INLINE_LEN {
let mut data: u64 = (INLINE_TAG as u64) | ((len as u64) << LEN_OFFSET);
Expand All @@ -200,7 +210,7 @@ impl<'a, Static: StaticAtomSet> From<Cow<'a, str>> for Atom<Static> {
phantom: PhantomData,
}
}
}
})
}
}

Expand Down

0 comments on commit 0cf93bb

Please sign in to comment.