Progress.

This commit is contained in:
2018-01-07 03:09:24 +01:00
parent f475629595
commit 0a91d99044
2 changed files with 98 additions and 53 deletions

View File

@@ -22,29 +22,67 @@ pub trait BitBlock
const ZERO: Self; const ZERO: Self;
const ONE: Self; const ONE: Self;
fn bits() -> u8; fn bits() -> usize;
fn count_ones(self) -> usize; fn count_ones(self) -> usize;
fn block(value: Self) -> Self;
fn bit(value: Self) -> Self;
} }
macro_rules! bit_block_impl { pub trait Block
: Copy
+ Hash
+ Eq
+ Shl<Self, Output = Self>
+ BitAnd<Self, Output = Self>
+ BitOr<Self, Output = Self>
+ Not<Output = Self> {
const ZERO: Self;
const ONE: Self;
fn bits() -> usize;
fn count_ones(self) -> usize;
fn block<B>(value: Self) -> Self
where
B: Block;
fn bit<B>(value: B) -> Self
where
B: Block;
fn biter<B>(value: Self) -> u8
where
B: Block;
}
macro_rules! block_impl {
($(($t: ty, $size: expr)),*) => ($( ($(($t: ty, $size: expr)),*) => ($(
impl BitBlock for $t { impl Block for $t {
const ZERO: Self = 0; const ZERO: Self = 0;
const ONE: Self = 1; const ONE: Self = 1;
#[inline] #[inline]
fn bits() -> u8 { $size } fn bits() -> usize { $size }
#[inline] #[inline]
fn count_ones(self) -> usize { self.count_ones() as usize } fn count_ones(self) -> usize { self.count_ones() as usize }
#[inline]
fn block<B>(value: Self) -> Self where B: Block { value / B::bits() as Self }
#[inline]
fn bit<B>(value: B) -> Self where B: Block { B::biter::<Self>(value) as Self }
#[inline]
fn biter<B>(value: Self) -> u8 where B: Block { (value % B::bits() as Self) as u8 }
} }
)*) )*)
} }
bit_block_impl!{ block_impl!{
(u8, 8), (u8, 8),
(u16, 16), (u16, 16),
(u32, 32), (u32, 32),
(u64, 64), (u64, 64),
(usize, (mem::size_of::<usize>() * 8) as u8) (usize, mem::size_of::<usize>() * 8)
} }

View File

@@ -15,29 +15,29 @@ mod hasher;
mod block; mod block;
use hasher::BitBuildHasher; use hasher::BitBuildHasher;
use block::BitBlock; use block::Block;
pub type BitHashMap<V> = HashMap<u64, V, BitBuildHasher>; pub type BitHashMap<V> = HashMap<u64, V, BitBuildHasher>;
#[inline] #[inline]
fn get_block_and_bit<T, B>(x: T) -> (T, B) fn index<T, B>(value: T) -> (T, B)
where where
T: BitBlock, T: Block,
B: BitBlock, B: Block,
{ {
(x / T::from(B::bits()), x % T::from(B::bits()) (T::block::<B>(value), B::bit(value))
} }
#[derive(PartialEq)] #[derive(PartialEq)]
pub struct BitSet<T: BitBlock, B: BitBlock = u64> { pub struct BitSet<T: Block, B: Block = u64> {
blocks: HashMap<T, B, BitBuildHasher>, blocks: HashMap<T, B, BitBuildHasher>,
nbits: usize, nbits: usize,
} }
impl<T, B> BitSet<T, B> impl<T, B> BitSet<T, B>
where where
T: BitBlock, T: Block,
B: BitBlock, B: Block,
{ {
#[inline] #[inline]
pub fn new() -> BitSet<T, B> { pub fn new() -> BitSet<T, B> {
@@ -50,7 +50,10 @@ where
#[inline] #[inline]
pub fn with_capacity(capacity: usize) -> BitSet<B> { pub fn with_capacity(capacity: usize) -> BitSet<B> {
BitSet { BitSet {
blocks: HashMap::with_capacity_and_hasher(capacity / B::bits() as usize, Default::default()), blocks: HashMap::with_capacity_and_hasher(
capacity / B::bits() as usize,
Default::default(),
),
nbits: 0, nbits: 0,
} }
} }
@@ -94,40 +97,40 @@ where
} }
pub fn contains(&self, value: &T) -> bool { pub fn contains(&self, value: &T) -> bool {
let (block, bit) = get_block_and_bit::<T, B>(*value); let (block, bit) = index::<T, B>(*value);
match self.blocks.get(&block) { match self.blocks.get(&block) {
Some(block) => (block & (B::ONE << bit)) != B::ZERO, Some(block) => (*block & (B::ONE << bit)) != B::ZERO,
None => false, None => false,
} }
} }
/*
pub fn is_subset(&self, other: &BitSet<B>) -> bool { pub fn is_subset(&self, other: &BitSet<T, B>) -> bool {
if self.nbits > other.nbits { if self.nbits > other.nbits {
false false
} else { } else {
self.blocks self.blocks
.iter() .iter()
.all(|(key, block_a)| match other.blocks.get(key) { .all(|(key, block_a)| match other.blocks.get(key) {
Some(block_b) => block_a | block_b == *block_b, Some(block_b) => *block_a | *block_b == *block_b,
None => *block_a == 0, None => *block_a == B::ZERO,
}) })
} }
} }
#[inline] #[inline]
pub fn is_superset(&self, other: &BitSet<B>) -> bool { pub fn is_superset(&self, other: &BitSet<T, B>) -> bool {
other.is_subset(self) other.is_subset(self)
} }
pub fn insert(&mut self, value: u64) -> bool { pub fn insert(&mut self, value: T) -> bool {
let (block, bit) = get_block_and_bit::<B>(&value); let (block, bit) = index::<T, B>(value);
let block = self.blocks.entry(block).or_insert(0); let block = self.blocks.entry(block).or_insert(B::ZERO);
let n = 1 << bit; let n = B::ONE << bit;
if (*block & n) == 0 { if (*block & n) == B::ZERO {
*block |= n; *block = *block | n;
self.nbits += 1; self.nbits += 1;
true true
@@ -136,14 +139,14 @@ where
} }
} }
pub fn remove(&mut self, value: &u64) -> bool { pub fn remove(&mut self, value: &T) -> bool {
let (block, bit) = get_block_and_bit::<B>(value); let (block, bit) = index::<T, B>(*value);
let block = self.blocks.entry(block).or_insert(0); let block = self.blocks.entry(block).or_insert(B::ZERO);
let n = 1 << bit; let n = B::ONE << bit;
if (*block & n) != 0 { if (*block & n) != B::ZERO {
*block &= !n; *block = *block & !n;
self.nbits -= 1; self.nbits -= 1;
true true
@@ -154,93 +157,97 @@ where
pub fn union_with(&mut self, other: &Self) { pub fn union_with(&mut self, other: &Self) {
for (key, value) in &other.blocks { for (key, value) in &other.blocks {
*self.blocks.entry(*key).or_insert(0) |= value; let block = self.blocks.entry(*key).or_insert(B::ZERO);
*block = *block | *value;
} }
self.nbits = self.blocks self.nbits = self.blocks
.values() .values()
.map(|block| block.count_ones() as usize) .map(|block| B::count_ones(*block))
.sum(); .sum();
} }
*/
} }
/* /*
impl<B> fmt::Debug for BitSet<B> { impl<T, B> fmt::Debug for BitSet<T, B> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_set().entries(self.iter()).finish() f.debug_set().entries(self.iter()).finish()
} }
} }
*/
impl<B> FromIterator<u64> for BitSet<B> { impl<T, B> FromIterator<T> for BitSet<T, B> where T: Block, B: Block {
#[inline] #[inline]
fn from_iter<I: IntoIterator<Item = u64>>(iter: I) -> BitSet<B> { fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> BitSet<T, B> {
let mut set = BitSet::new(); let mut set = BitSet::new();
set.extend(iter); set.extend(iter);
set set
} }
} }
impl<B> Extend<u64> for BitSet<B> { impl<T, B> Extend<T> for BitSet<T, B> where T: Block, B: Block {
#[inline] #[inline]
fn extend<I: IntoIterator<Item = u64>>(&mut self, iter: I) { fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
for i in iter { for i in iter {
self.insert(i); self.insert(i);
} }
} }
} }
impl<'a, B> Extend<&'a u64> for BitSet<B> { impl<'a, T: 'a, B> Extend<&'a T> for BitSet<T, B> where T: Block, B: Block {
#[inline] #[inline]
fn extend<I: IntoIterator<Item = &'a u64>>(&mut self, iter: I) { fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
for i in iter { for i in iter {
self.insert(*i); self.insert(*i);
} }
} }
} }
impl<B> Default for BitSet<B> { impl<T, B> Default for BitSet<T, B> where T: Block, B: Block {
#[inline] #[inline]
fn default() -> BitSet<B> { fn default() -> BitSet<T, B> {
BitSet::new() BitSet::new()
} }
} }
impl<B> ops::BitOr for BitSet<B> { impl<T, B> ops::BitOr for BitSet<T, B> where T: Block, B: Block {
type Output = Self; type Output = Self;
#[inline] #[inline]
fn bitor(mut self, rhs: Self) -> Self { fn bitor(mut self, rhs: Self) -> Self {
for (key, value) in &rhs.blocks { for (key, value) in &rhs.blocks {
*self.blocks.entry(*key).or_insert(0) |= value; let block = self.blocks.entry(*key).or_insert(B::ZERO);
*block = *block | *value;
} }
self.nbits = self.blocks self.nbits = self.blocks
.values() .values()
.map(|block| block.count_ones() as usize) .map(|block| block.count_ones())
.sum(); .sum();
self self
} }
} }
impl<'a, B> ops::BitOr<&'a Self> for BitSet<B> { impl<'a, T, B> ops::BitOr<&'a Self> for BitSet<T, B> where T: Block, B: Block {
type Output = Self; type Output = Self;
#[inline] #[inline]
fn bitor(mut self, rhs: &'a Self) -> Self { fn bitor(mut self, rhs: &'a Self) -> Self {
for (key, value) in &rhs.blocks { for (key, value) in &rhs.blocks {
*self.blocks.entry(*key).or_insert(0) |= value; let block = self.blocks.entry(*key).or_insert(B::ZERO);
*block = *block | *value;
} }
self.nbits = self.blocks self.nbits = self.blocks
.values() .values()
.map(|block| block.count_ones() as usize) .map(|block| block.count_ones())
.sum(); .sum();
self self
} }
} }
/*
pub struct Iter<'a> { pub struct Iter<'a> {
iter: std::collections::hash_map::Iter<'a, u64, u64>, iter: std::collections::hash_map::Iter<'a, u64, u64>,
block: u64, block: u64,