diff --git a/Cargo.toml b/Cargo.toml index 209d24b..e71c055 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,6 @@ rayon = "1.10.0" roaring = "0.10.9" tempfile = "3.15.0" thiserror = "2.0.9" -nohash = "0.2.0" page_size = "0.6.0" enum-iterator = "2.1.0" diff --git a/src/lib.rs b/src/lib.rs index bbe4269..03b7942 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -83,6 +83,7 @@ mod key; mod metadata; mod node; mod node_id; +mod nohash_hasher; mod parallel; mod reader; mod roaring; diff --git a/src/nohash_hasher.rs b/src/nohash_hasher.rs new file mode 100644 index 0000000..623e06a --- /dev/null +++ b/src/nohash_hasher.rs @@ -0,0 +1,133 @@ +use std::{ + collections::{HashMap, HashSet}, + fmt, + hash::{BuildHasherDefault, Hasher}, + marker::PhantomData, +}; + +/// A `HashMap` with integer keys, using `NoHashHasher`. +pub type IntMap = HashMap>; + +/// A `HashSet` of integers, using `NoHash`. +pub type IntSet = HashSet>; + +/// An alias for `BuildHasherDefault` for use with `NoHash`. +pub type BuildNoHashHasher = BuildHasherDefault>; + +/// `std::hash::Hasher` implementation which maps input value as its hash output. +pub struct NoHash(u64, PhantomData); + +impl fmt::Debug for NoHash { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("NoHash").field(&self.0).finish() + } +} + +impl Default for NoHash { + fn default() -> Self { + NoHash(0, PhantomData) + } +} + +pub trait IsEnabled {} + +impl IsEnabled for u8 {} +impl IsEnabled for u16 {} +impl IsEnabled for u32 {} +impl IsEnabled for u64 {} +impl IsEnabled for usize {} +impl IsEnabled for i8 {} +impl IsEnabled for i16 {} +impl IsEnabled for i32 {} +impl IsEnabled for i64 {} +impl IsEnabled for isize {} + +impl Hasher for NoHash { + fn write(&mut self, _: &[u8]) { + panic!("Invalid use of NoHash") + } + + fn write_u8(&mut self, n: u8) { + self.0 = u64::from(n) + } + fn write_u16(&mut self, n: u16) { + self.0 = u64::from(n) + } + fn write_u32(&mut self, n: u32) { + self.0 = u64::from(n) + } + fn write_u64(&mut self, n: u64) { + self.0 = n + } + fn write_usize(&mut self, n: usize) { + self.0 = n as u64 + } + + fn write_i8(&mut self, n: i8) { + self.0 = n as u64 + } + fn write_i16(&mut self, n: i16) { + self.0 = n as u64 + } + fn write_i32(&mut self, n: i32) { + self.0 = n as u64 + } + fn write_i64(&mut self, n: i64) { + self.0 = n as u64 + } + fn write_isize(&mut self, n: isize) { + self.0 = n as u64 + } + + fn finish(&self) -> u64 { + self.0 + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn ok() { + let mut h1 = NoHash::::default(); + h1.write_u8(42); + assert_eq!(42, h1.finish()); + + let mut h2 = NoHash::::default(); + h2.write_u16(42); + assert_eq!(42, h2.finish()); + + let mut h3 = NoHash::::default(); + h3.write_u32(42); + assert_eq!(42, h3.finish()); + + let mut h4 = NoHash::::default(); + h4.write_u64(42); + assert_eq!(42, h4.finish()); + + let mut h5 = NoHash::::default(); + h5.write_usize(42); + assert_eq!(42, h5.finish()); + + let mut h6 = NoHash::::default(); + h6.write_i8(42); + assert_eq!(42, h6.finish()); + + let mut h7 = NoHash::::default(); + h7.write_i16(42); + assert_eq!(42, h7.finish()); + + let mut h8 = NoHash::::default(); + h8.write_i32(42); + assert_eq!(42, h8.finish()); + + let mut h9 = NoHash::::default(); + h9.write_i64(42); + assert_eq!(42, h9.finish()); + + let mut h10 = NoHash::::default(); + h10.write_isize(42); + assert_eq!(42, h10.finish()) + } +} diff --git a/src/parallel.rs b/src/parallel.rs index efe6640..4ca22fc 100644 --- a/src/parallel.rs +++ b/src/parallel.rs @@ -8,7 +8,6 @@ use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU64, Ordering}; use heed::types::Bytes; use heed::{BytesDecode, BytesEncode, RoTxn}; use memmap2::Mmap; -use nohash::{BuildNoHashHasher, IntMap, IntSet}; use rand::seq::index; use rand::Rng; use roaring::{RoaringBitmap, RoaringTreemap}; @@ -17,6 +16,7 @@ use crate::internals::{KeyCodec, Leaf, NodeCodec}; use crate::key::{Key, Prefix, PrefixCodec}; use crate::node::{Node, SplitPlaneNormal}; use crate::node_id::NodeMode; +use crate::nohash_hasher::{BuildNoHashHasher, IntMap, IntSet}; use crate::{Database, Distance, Error, ItemId, Result}; /// A structure to store the tree nodes out of the heed database.