Move hasher to a seperate file.

This commit is contained in:
2018-01-04 14:30:49 +01:00
parent 3d14bbc4ae
commit 38104e133e
3 changed files with 53 additions and 56 deletions

View File

@@ -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
View 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>;

View File

@@ -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
}
}