Did stuff, stuff that doens't work.
This commit is contained in:
31
src/block.rs
31
src/block.rs
@@ -1,21 +1,40 @@
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::ops::*;
|
||||||
|
use std::hash::Hash;
|
||||||
|
use std::convert::From;
|
||||||
|
|
||||||
pub trait BitBlock {
|
pub trait BitBlock
|
||||||
const ONE: Self;
|
: Copy
|
||||||
|
+ Add<Self, Output = Self>
|
||||||
|
+ Div<Self, Output = Self>
|
||||||
|
+ From<u8>
|
||||||
|
+ Sub<Self, Output = Self>
|
||||||
|
+ Shl<usize, Output = Self>
|
||||||
|
+ Shr<usize, Output = Self>
|
||||||
|
+ Not<Output = Self>
|
||||||
|
+ BitAnd<Self, Output = Self>
|
||||||
|
+ BitOr<Self, Output = Self>
|
||||||
|
+ BitXor<Self, Output = Self>
|
||||||
|
+ Rem<Self, Output = Self>
|
||||||
|
+ Eq
|
||||||
|
+ Ord
|
||||||
|
+ Hash {
|
||||||
const ZERO: Self;
|
const ZERO: Self;
|
||||||
|
const ONE: Self;
|
||||||
|
|
||||||
fn bits() -> usize;
|
fn bits() -> u8;
|
||||||
fn count_ones(self) -> usize;
|
fn count_ones(self) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! bit_block_impl {
|
macro_rules! bit_block_impl {
|
||||||
($(($t: ty, $size: expr)),*) => ($(
|
($(($t: ty, $size: expr)),*) => ($(
|
||||||
impl BitBlock for $t {
|
impl BitBlock for $t {
|
||||||
|
const ZERO: Self = 0;
|
||||||
const ONE: Self = 1;
|
const ONE: Self = 1;
|
||||||
const ZERO: Self = 1;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn bits() -> usize { $size }
|
fn bits() -> u8 { $size }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn count_ones(self) -> usize { self.count_ones() as usize }
|
fn count_ones(self) -> usize { self.count_ones() as usize }
|
||||||
}
|
}
|
||||||
@@ -27,5 +46,5 @@ bit_block_impl!{
|
|||||||
(u16, 16),
|
(u16, 16),
|
||||||
(u32, 32),
|
(u32, 32),
|
||||||
(u64, 64),
|
(u64, 64),
|
||||||
(usize, mem::size_of::<usize>() * 8)
|
(usize, (mem::size_of::<usize>() * 8) as u8)
|
||||||
}
|
}
|
||||||
|
|||||||
99
src/lib.rs
99
src/lib.rs
@@ -15,56 +15,61 @@ mod hasher;
|
|||||||
mod block;
|
mod block;
|
||||||
|
|
||||||
use hasher::BitBuildHasher;
|
use hasher::BitBuildHasher;
|
||||||
|
use block::BitBlock;
|
||||||
const BITS: u64 = 64;
|
|
||||||
|
|
||||||
type Block = u64;
|
|
||||||
type Storage = HashMap<u64, Block, BitBuildHasher>;
|
|
||||||
|
|
||||||
pub type BitHashMap<V> = HashMap<u64, V, BitBuildHasher>;
|
pub type BitHashMap<V> = HashMap<u64, V, BitBuildHasher>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn block_bit(x: &u64, d: &u64) -> (u64, u64) {
|
fn get_block_and_bit<T, B>(x: T) -> (T, B)
|
||||||
(x / d, x % d)
|
where
|
||||||
|
T: BitBlock,
|
||||||
|
B: BitBlock,
|
||||||
|
{
|
||||||
|
(x / T::from(B::bits()), x % T::from(B::bits())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub struct BitSet {
|
pub struct BitSet<T: BitBlock, B: BitBlock = u64> {
|
||||||
blocks: Storage,
|
blocks: HashMap<T, B, BitBuildHasher>,
|
||||||
nbits: usize,
|
nbits: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitSet {
|
impl<T, B> BitSet<T, B>
|
||||||
|
where
|
||||||
|
T: BitBlock,
|
||||||
|
B: BitBlock,
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new() -> BitSet {
|
pub fn new() -> BitSet<T, B> {
|
||||||
BitSet {
|
BitSet {
|
||||||
blocks: Storage::default(),
|
blocks: HashMap::default(),
|
||||||
nbits: 0,
|
nbits: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_capacity(capacity: usize) -> BitSet {
|
pub fn with_capacity(capacity: usize) -> BitSet<B> {
|
||||||
BitSet {
|
BitSet {
|
||||||
blocks: Storage::with_capacity_and_hasher(capacity / BITS as usize, Default::default()),
|
blocks: HashMap::with_capacity_and_hasher(capacity / B::bits() as usize, Default::default()),
|
||||||
nbits: 0,
|
nbits: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn capacity(&self) -> usize {
|
pub fn capacity(&self) -> usize {
|
||||||
self.blocks.capacity() * BITS as usize
|
self.blocks.capacity() * B::bits() as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reserve(&mut self, additional: usize) {
|
pub fn reserve(&mut self, additional: usize) {
|
||||||
self.blocks.reserve(additional / BITS as usize)
|
self.blocks.reserve(additional / B::bits() as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shrink_to_fit(&mut self) {
|
pub fn shrink_to_fit(&mut self) {
|
||||||
self.blocks.retain(|_, block| *block != 0);
|
self.blocks.retain(|_, block| *block != B::ZERO);
|
||||||
self.blocks.shrink_to_fit()
|
self.blocks.shrink_to_fit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
pub fn iter(&self) -> Iter {
|
pub fn iter(&self) -> Iter {
|
||||||
Iter {
|
Iter {
|
||||||
iter: self.blocks.iter(),
|
iter: self.blocks.iter(),
|
||||||
@@ -73,6 +78,7 @@ impl BitSet {
|
|||||||
bit: BITS,
|
bit: BITS,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.nbits
|
self.nbits
|
||||||
@@ -87,16 +93,16 @@ impl BitSet {
|
|||||||
self.nbits = 0;
|
self.nbits = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains(&self, value: &u64) -> bool {
|
pub fn contains(&self, value: &T) -> bool {
|
||||||
let (block, bit) = block_bit(value, &BITS);
|
let (block, bit) = get_block_and_bit::<T, B>(*value);
|
||||||
|
|
||||||
match self.blocks.get(&block) {
|
match self.blocks.get(&block) {
|
||||||
Some(block) => (block & (1 << bit)) != 0,
|
Some(block) => (block & (B::ONE << bit)) != B::ZERO,
|
||||||
None => false,
|
None => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
pub fn is_subset(&self, other: &BitSet) -> bool {
|
pub fn is_subset(&self, other: &BitSet<B>) -> bool {
|
||||||
if self.nbits > other.nbits {
|
if self.nbits > other.nbits {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
@@ -110,12 +116,12 @@ impl BitSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_superset(&self, other: &BitSet) -> bool {
|
pub fn is_superset(&self, other: &BitSet<B>) -> bool {
|
||||||
other.is_subset(self)
|
other.is_subset(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, value: u64) -> bool {
|
pub fn insert(&mut self, value: u64) -> bool {
|
||||||
let (block, bit) = block_bit(&value, &BITS);
|
let (block, bit) = get_block_and_bit::<B>(&value);
|
||||||
let block = self.blocks.entry(block).or_insert(0);
|
let block = self.blocks.entry(block).or_insert(0);
|
||||||
|
|
||||||
let n = 1 << bit;
|
let n = 1 << bit;
|
||||||
@@ -131,7 +137,7 @@ impl BitSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove(&mut self, value: &u64) -> bool {
|
pub fn remove(&mut self, value: &u64) -> bool {
|
||||||
let (block, bit) = block_bit(value, &BITS);
|
let (block, bit) = get_block_and_bit::<B>(value);
|
||||||
let block = self.blocks.entry(block).or_insert(0);
|
let block = self.blocks.entry(block).or_insert(0);
|
||||||
|
|
||||||
let n = 1 << bit;
|
let n = 1 << bit;
|
||||||
@@ -156,24 +162,25 @@ impl BitSet {
|
|||||||
.map(|block| block.count_ones() as usize)
|
.map(|block| block.count_ones() as usize)
|
||||||
.sum();
|
.sum();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
impl fmt::Debug for BitSet {
|
impl<B> fmt::Debug for BitSet<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 FromIterator<u64> for BitSet {
|
impl<B> FromIterator<u64> for BitSet<B> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_iter<I: IntoIterator<Item = u64>>(iter: I) -> BitSet {
|
fn from_iter<I: IntoIterator<Item = u64>>(iter: I) -> BitSet<B> {
|
||||||
let mut set = BitSet::new();
|
let mut set = BitSet::new();
|
||||||
set.extend(iter);
|
set.extend(iter);
|
||||||
set
|
set
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Extend<u64> for BitSet {
|
impl<B> Extend<u64> for BitSet<B> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn extend<I: IntoIterator<Item = u64>>(&mut self, iter: I) {
|
fn extend<I: IntoIterator<Item = u64>>(&mut self, iter: I) {
|
||||||
for i in iter {
|
for i in iter {
|
||||||
@@ -182,7 +189,7 @@ impl Extend<u64> for BitSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Extend<&'a u64> for BitSet {
|
impl<'a, B> Extend<&'a u64> for BitSet<B> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn extend<I: IntoIterator<Item = &'a u64>>(&mut self, iter: I) {
|
fn extend<I: IntoIterator<Item = &'a u64>>(&mut self, iter: I) {
|
||||||
for i in iter {
|
for i in iter {
|
||||||
@@ -191,14 +198,14 @@ impl<'a> Extend<&'a u64> for BitSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for BitSet {
|
impl<B> Default for BitSet<B> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> BitSet {
|
fn default() -> BitSet<B> {
|
||||||
BitSet::new()
|
BitSet::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::BitOr for BitSet {
|
impl<B> ops::BitOr for BitSet<B> {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -216,7 +223,7 @@ impl ops::BitOr for BitSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ops::BitOr<&'a Self> for BitSet {
|
impl<'a, B> ops::BitOr<&'a Self> for BitSet<B> {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -248,7 +255,7 @@ pub struct IntoIter {
|
|||||||
bit: u64,
|
bit: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> IntoIterator for &'a BitSet {
|
impl<'a, B> IntoIterator for &'a BitSet<B> {
|
||||||
type Item = u64;
|
type Item = u64;
|
||||||
type IntoIter = Iter<'a>;
|
type IntoIter = Iter<'a>;
|
||||||
|
|
||||||
@@ -257,7 +264,7 @@ impl<'a> IntoIterator for &'a BitSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoIterator for BitSet {
|
impl<B> IntoIterator for BitSet<B> {
|
||||||
type Item = u64;
|
type Item = u64;
|
||||||
type IntoIter = IntoIter;
|
type IntoIter = IntoIter;
|
||||||
|
|
||||||
@@ -330,8 +337,9 @@ impl Iterator for IntoIter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
impl Serialize for BitSet {
|
/*
|
||||||
|
impl<B> Serialize for BitSet<B> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
@@ -345,15 +353,15 @@ impl Serialize for BitSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for BitSet {
|
impl<'de, B> Deserialize<'de> for BitSet<B> {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
struct SeqVisitor;
|
struct SeqVisitor<B>(PhantomData<B>);
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for SeqVisitor {
|
impl<'de, B> Visitor<'de> for SeqVisitor<B> {
|
||||||
type Value = BitSet;
|
type Value = BitSet<B>;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
formatter.write_str("a sequence")
|
formatter.write_str("a sequence")
|
||||||
@@ -383,7 +391,7 @@ impl<'de> Deserialize<'de> for BitSet {
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
struct SeqInPlaceVisitor<'a>(&'a mut BitSet);
|
struct SeqInPlaceVisitor<'a>(&'a mut BitSet<B>);
|
||||||
|
|
||||||
impl<'a, 'de> Visitor<'de> for SeqInPlaceVisitor<'a> {
|
impl<'a, 'de> Visitor<'de> for SeqInPlaceVisitor<'a> {
|
||||||
type Value = ();
|
type Value = ();
|
||||||
@@ -410,6 +418,7 @@ impl<'de> Deserialize<'de> for BitSet {
|
|||||||
deserializer.deserialize_seq(SeqInPlaceVisitor(place))
|
deserializer.deserialize_seq(SeqInPlaceVisitor(place))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
@@ -644,6 +653,7 @@ mod tests {
|
|||||||
assert_eq!(set.contains(&5), true);
|
assert_eq!(set.contains(&5), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#[test]
|
#[test]
|
||||||
fn test_serde_serialize() {
|
fn test_serde_serialize() {
|
||||||
let mut set = BitSet::new();
|
let mut set = BitSet::new();
|
||||||
@@ -662,4 +672,5 @@ mod tests {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user