Progress.
This commit is contained in:
50
src/block.rs
50
src/block.rs
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
101
src/lib.rs
101
src/lib.rs
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user