Move hasher to a seperate file.
This commit is contained in:
@@ -3,5 +3,8 @@ name = "bit-set"
|
||||
version = "0.1.0"
|
||||
authors = ["logaritmisk <anders.e.olsson@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
unreachable = "1.0"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
||||
32
src/hasher.rs
Normal file
32
src/hasher.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
use std::default::Default;
|
||||
use std::hash::{BuildHasherDefault, Hasher};
|
||||
|
||||
use unreachable;
|
||||
|
||||
pub struct BitHasher(u64);
|
||||
|
||||
impl Default for BitHasher {
|
||||
#[inline]
|
||||
fn default() -> BitHasher {
|
||||
BitHasher(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Hasher for BitHasher {
|
||||
#[inline]
|
||||
fn finish(&self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write(&mut self, _: &[u8]) {
|
||||
unsafe { unreachable::unreachable() };
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u64(&mut self, i: u64) {
|
||||
*self = BitHasher(i);
|
||||
}
|
||||
}
|
||||
|
||||
pub type BitBuildHasher = BuildHasherDefault<BitHasher>;
|
||||
74
src/lib.rs
74
src/lib.rs
@@ -1,43 +1,18 @@
|
||||
extern crate unreachable;
|
||||
|
||||
use std::ops;
|
||||
use std::iter::FromIterator;
|
||||
use std::default::Default;
|
||||
use std::hash::{BuildHasherDefault, Hasher};
|
||||
use std::collections::HashMap;
|
||||
|
||||
mod hasher;
|
||||
|
||||
use hasher::BitBuildHasher;
|
||||
|
||||
const BITS: u64 = 64;
|
||||
|
||||
struct BitHasher(u64);
|
||||
|
||||
impl Default for BitHasher {
|
||||
#[inline]
|
||||
fn default() -> BitHasher {
|
||||
BitHasher(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Hasher for BitHasher {
|
||||
#[inline]
|
||||
fn finish(&self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write(&mut self, _: &[u8]) {
|
||||
panic!("this hasher only works with u64");
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u64(&mut self, i: u64) {
|
||||
*self = BitHasher(i);
|
||||
}
|
||||
}
|
||||
|
||||
type BitBuildHasher = BuildHasherDefault<BitHasher>;
|
||||
type BitHashMap<K, V> = HashMap<K, V, BitBuildHasher>;
|
||||
// type BitHashSet<T> = HashSet<T, BitBuildHasher>;
|
||||
|
||||
type Block = u64;
|
||||
type Storage = BitHashMap<u64, Block>;
|
||||
type Storage = HashMap<u64, Block, BitBuildHasher>;
|
||||
|
||||
#[inline]
|
||||
fn block_bit(x: u64, d: u64) -> (u64, u64) {
|
||||
@@ -60,12 +35,9 @@ impl BitSet {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_capacity(nbits: usize) -> BitSet {
|
||||
let (mut block, bit) = block_bit(nbits as u64, BITS);
|
||||
block += (bit > 0) as u64;
|
||||
|
||||
pub fn with_capacity(capacity: usize) -> BitSet {
|
||||
BitSet {
|
||||
blocks: Storage::with_capacity_and_hasher(block as usize, Default::default()),
|
||||
blocks: Storage::with_capacity_and_hasher(capacity, Default::default()),
|
||||
nbits: 0,
|
||||
}
|
||||
}
|
||||
@@ -124,8 +96,8 @@ impl BitSet {
|
||||
let (block, bit) = block_bit(value, BITS);
|
||||
|
||||
match self.blocks.get(&block) {
|
||||
None => false,
|
||||
Some(block) => (block & (1 << bit)) != 0,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,22 +152,17 @@ impl ops::BitOr for BitSet {
|
||||
type Output = Self;
|
||||
|
||||
#[inline]
|
||||
fn bitor(self, rhs: Self) -> Self {
|
||||
let mut blocks = self.blocks.clone();
|
||||
|
||||
fn bitor(mut self, rhs: Self) -> Self {
|
||||
for (key, value) in &rhs.blocks {
|
||||
*blocks.entry(*key).or_insert(0) |= value;
|
||||
*self.blocks.entry(*key).or_insert(0) |= value;
|
||||
}
|
||||
|
||||
let nbits = blocks
|
||||
self.nbits = self.blocks
|
||||
.values()
|
||||
.map(|block| block.count_ones() as usize)
|
||||
.sum();
|
||||
|
||||
BitSet {
|
||||
blocks: blocks,
|
||||
nbits: nbits,
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,22 +170,17 @@ impl<'a> ops::BitOr<&'a Self> for BitSet {
|
||||
type Output = Self;
|
||||
|
||||
#[inline]
|
||||
fn bitor(self, rhs: &'a Self) -> Self {
|
||||
let mut blocks = self.blocks.clone();
|
||||
|
||||
fn bitor(mut self, rhs: &'a Self) -> Self {
|
||||
for (key, value) in &rhs.blocks {
|
||||
*blocks.entry(*key).or_insert(0) |= value;
|
||||
*self.blocks.entry(*key).or_insert(0) |= value;
|
||||
}
|
||||
|
||||
let nbits = blocks
|
||||
self.nbits = self.blocks
|
||||
.values()
|
||||
.map(|block| block.count_ones() as usize)
|
||||
.sum();
|
||||
|
||||
BitSet {
|
||||
blocks: blocks,
|
||||
nbits: nbits,
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user