Skip to content

Commit

Permalink
Remove mutability from name hash
Browse files Browse the repository at this point in the history
  • Loading branch information
David Judd committed May 7, 2017
1 parent 23b26aa commit c751caa
Show file tree
Hide file tree
Showing 6 changed files with 15 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "human_name"
version = "0.6.5"
version = "0.7.0"
authors = ["David Judd <david.a.judd@gmail.com>"]
description = "A library for parsing and comparing human names"
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion src/comparison.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl Name {
#[cfg_attr(rustfmt, rustfmt_skip)]
pub fn consistent_with(&self, other: &Name) -> bool {
// Fast path
if self.memoized_surname_hash() != other.memoized_surname_hash() {
if self.hash != other.hash {
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion src/external.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub extern "C" fn human_name_consistent_with(a: &Name, b: &Name) -> bool {

#[no_mangle]
pub extern "C" fn human_name_hash(name: &Name) -> u64 {
name.memoized_surname_hash()
name.hash
}

#[no_mangle]
Expand Down
30 changes: 10 additions & 20 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ pub mod external;
mod eq_hash;

use std::borrow::Cow;
use std::cell::Cell;
use std::hash::{Hash, Hasher};
use std::collections::hash_map::DefaultHasher;
use std::slice::Iter;
Expand Down Expand Up @@ -66,7 +65,7 @@ pub struct Name {
generation_from_suffix: Option<usize>,
initials: String,
word_indices_in_initials: Vec<(usize, usize)>,
hash: Cell<Option<u64>>,
pub hash: u64,
}

impl Name {
Expand Down Expand Up @@ -186,13 +185,16 @@ impl Name {
names.shrink_to_fit();
word_indices_in_initials.shrink_to_fit();

let mut s = DefaultHasher::new();
Name::hash_surnames(&names[surname_index_in_names..], &mut s);

Some(Name {
words: names,
surname_index: surname_index_in_names,
generation_from_suffix: generation_from_suffix,
initials: initials,
word_indices_in_initials: word_indices_in_initials,
hash: Cell::new(None),
hash: s.finish(),
})
}

Expand Down Expand Up @@ -410,7 +412,11 @@ impl Name {
/// We can't use the first initial because we might ignore it if someone goes
/// by a middle name or nickname, or due to transliteration.
pub fn surname_hash<H: Hasher>(&self, state: &mut H) {
let surname_chars = self.surnames()
Name::hash_surnames(self.surnames(), state)
}

fn hash_surnames<H: Hasher>(surnames: &[String], state: &mut H) {
let surname_chars = surnames
.iter()
.flat_map(|w| w.chars())
.flat_map(transliterate)
Expand All @@ -420,22 +426,6 @@ impl Name {
c.hash(state);
}
}

/// Memoizes the result of `surname_hash` when used with `DefaultHasher`
pub fn memoized_surname_hash(&self) -> u64 {
{
let cached = self.hash.get();
if cached.is_some() {
return cached.unwrap();
}

let mut s = DefaultHasher::new();
self.surname_hash(&mut s);
self.hash.set(Some(s.finish()));
}

self.memoized_surname_hash()
}
}

struct GivenNamesOrInitials<'a> {
Expand Down
2 changes: 1 addition & 1 deletion tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ fn equality() {
"{} should be equal to {} but was not!",
b,
a);
assert!(parsed_a.unwrap().memoized_surname_hash() == parsed_b.unwrap().memoized_surname_hash(),
assert!(parsed_a.unwrap().hash == parsed_b.unwrap().hash,
"{} should have the same hash as {} but did not!",
a,
b);
Expand Down

0 comments on commit c751caa

Please sign in to comment.