Skip to content

Commit 0cf93bb

Browse files
authored
Auto merge of #238 - leops:try_static, r=jdm
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)
2 parents 82ac0d9 + c057dde commit 0cf93bb

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

integration-tests/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,12 @@ fn test_from_string() {
290290
assert!(Atom::from("camembert".to_owned()) == Atom::from("camembert"));
291291
}
292292

293+
#[test]
294+
fn test_try_static() {
295+
assert!(Atom::try_static("head").is_some());
296+
assert!(Atom::try_static("not in the static table").is_none());
297+
}
298+
293299
#[cfg(all(test, feature = "unstable"))]
294300
#[path = "bench.rs"]
295301
mod bench;

src/atom.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,22 @@ impl<Static: StaticAtomSet> Atom<Static> {
149149
_ => unsafe { debug_unreachable!() },
150150
}
151151
}
152+
153+
pub fn try_static(string_to_add: &str) -> Option<Self> {
154+
Self::try_static_internal(string_to_add).ok()
155+
}
156+
157+
fn try_static_internal(string_to_add: &str) -> Result<Self, phf_shared::Hashes> {
158+
let static_set = Static::get();
159+
let hash = phf_shared::hash(&*string_to_add, &static_set.key);
160+
let index = phf_shared::get_index(&hash, static_set.disps, static_set.atoms.len());
161+
162+
if static_set.atoms[index as usize] == string_to_add {
163+
Ok(Self::pack_static(index))
164+
} else {
165+
Err(hash)
166+
}
167+
}
152168
}
153169

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

171187
impl<'a, Static: StaticAtomSet> From<Cow<'a, str>> for Atom<Static> {
172188
fn from(string_to_add: Cow<'a, str>) -> Self {
173-
let static_set = Static::get();
174-
let hash = phf_shared::hash(&*string_to_add, &static_set.key);
175-
let index = phf_shared::get_index(&hash, static_set.disps, static_set.atoms.len());
176-
177-
if static_set.atoms[index as usize] == string_to_add {
178-
Self::pack_static(index)
179-
} else {
189+
Self::try_static_internal(&*string_to_add).unwrap_or_else(|hash| {
180190
let len = string_to_add.len();
181191
if len <= MAX_INLINE_LEN {
182192
let mut data: u64 = (INLINE_TAG as u64) | ((len as u64) << LEN_OFFSET);
@@ -200,7 +210,7 @@ impl<'a, Static: StaticAtomSet> From<Cow<'a, str>> for Atom<Static> {
200210
phantom: PhantomData,
201211
}
202212
}
203-
}
213+
})
204214
}
205215
}
206216

0 commit comments

Comments
 (0)