diff --git a/src/data/mod.rs b/src/data/mod.rs index 90af972..bc0bfed 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -38,7 +38,7 @@ pub struct Store { metadata: StoreMetadata, - data: HashSet, // The entry sha256 hash is used as the `key` here, as `Entry` both hasshes to, and `Borrow`s to `Sha256Hash`. + data: HashSet, // The entry sha256 hash is used as the `key` here, as `Entry` both hasshes to, and `Borrow`s to `Sha256Hash`. data_hashes: Arena, // used to lookup in `data`. tag_mappings: Arena>, @@ -70,7 +70,7 @@ impl Store assert!(metadata.root.exists() && metadata.root.is_dir(), "Metadata root {:?} passed to `new` not existant or not a directory", metadata.root); Self { metadata, - data: HashSet::new(), + data: HashSet::with_hasher(Default::default()), data_hashes: Arena::new(), tag_mappings: Arena::new(), @@ -87,7 +87,7 @@ impl Store Self { metadata, - data: HashSet::with_capacity(cap), + data: HashSet::with_capacity_and_hasher(cap, Default::default()), data_hashes: Arena::with_capacity(cap), tag_mappings: Arena::with_capacity(cap), diff --git a/src/ext/hashers.rs b/src/ext/hashers.rs new file mode 100644 index 0000000..f546b0f --- /dev/null +++ b/src/ext/hashers.rs @@ -0,0 +1,36 @@ +use super::*; +use std::hash::{BuildHasherDefault, Hasher}; +use smallvec::SmallVec; +use cryptohelpers::sha256; + +/// A hasher that takes the first 8 bytes from SHA256 hash as its output. +/// +/// # Notes +/// Intended for use for `HashSet` with a SHA256 key. +/// Hashing anything other than a SHA256 hash with this hasher is undefined. +#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Default)] +pub struct Sha256TopHasher(SmallVec<[u8; sha256::SIZE]>); + +/// A `BuildHasher` for [`Sha256TopHasher`]. +pub type Sha256TopBuildHasher = BuildHasherDefault; + +impl Sha256TopHasher +{ + /// Create a new hasher + #[inline] fn new() -> Self + { + Self(SmallVec::new()) + } +} + +impl Hasher for Sha256TopHasher +{ + #[inline] fn finish(&self) -> u64 { + let mut bytes = [0u8; std::mem::size_of::()]; + crate::slice::copy_bytes(self.0.as_ref(), &mut bytes[..]); + u64::from_le_bytes(bytes) + } + #[inline] fn write(&mut self, bytes: &[u8]) { + self.0.extend_from_slice(bytes); + } +} diff --git a/src/ext.rs b/src/ext/iters.rs similarity index 96% rename from src/ext.rs rename to src/ext/iters.rs index 8a32d11..a41ded5 100644 --- a/src/ext.rs +++ b/src/ext/iters.rs @@ -1,16 +1,10 @@ -use std::iter::FusedIterator; -use std::collections::BTreeSet; -use std::borrow::Borrow; -use futures::prelude::*; +use super::*; /// An iterator that may be empty. #[derive(Debug, Clone)] pub struct MaybeIter(Option) where I: Iterator; -mod streams; -pub use streams::*; - pub trait OptionIterExt: Sized where I: Iterator { diff --git a/src/ext/mod.rs b/src/ext/mod.rs new file mode 100644 index 0000000..631bbae --- /dev/null +++ b/src/ext/mod.rs @@ -0,0 +1,13 @@ +use std::iter::FusedIterator; +use std::collections::BTreeSet; +use std::borrow::Borrow; +use futures::prelude::*; + +mod iters; +pub use iters::*; + +mod streams; +pub use streams::*; + +mod hashers; +pub use hashers::*;