use crate::bit_vector::rank_support::RankSupport;
use crate::bit_vector::select_support::SelectSupport;
use crate::ops::{BitVec, Rank, Select, SelectZero, PredSucc};
use crate::raw_vector::{RawVector, AccessRaw, PushRaw};
use crate::serialize::Serialize;
use crate::bits;
use std::io::{Error, ErrorKind};
use std::iter::{FusedIterator, FromIterator};
use std::{cmp, io, marker};
pub mod rank_support;
pub mod select_support;
#[cfg(test)]
mod tests;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct BitVector {
ones: usize,
data: RawVector,
rank: Option<RankSupport>,
select: Option<SelectSupport<Identity>>,
select_zero: Option<SelectSupport<Complement>>,
}
impl BitVector {
pub fn copy_bit_vec<'a, T: BitVec<'a> + Select<'a>>(source: &'a T) -> Self {
let mut data = RawVector::with_len(source.len(), false);
for (_, index) in source.one_iter() {
data.set_bit(index, true);
}
BitVector::from(data)
}
}
#[derive(Clone, Debug)]
pub struct Iter<'a> {
parent: &'a BitVector,
next: usize,
limit: usize,
}
impl<'a> Iterator for Iter<'a> {
type Item = bool;
fn next(&mut self) -> Option<Self::Item> {
if self.next >= self.limit {
None
} else {
let result = Some(self.parent.get(self.next));
self.next += 1;
result
}
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.next += cmp::min(n, self.limit - self.next);
self.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.limit - self.next;
(remaining, Some(remaining))
}
}
impl<'a> DoubleEndedIterator for Iter<'a> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.next >= self.limit {
None
} else {
self.limit -= 1;
Some(self.parent.get(self.limit))
}
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.limit -= cmp::min(n, self.limit - self.next);
self.next_back()
}
}
impl<'a> ExactSizeIterator for Iter<'a> {}
impl<'a> FusedIterator for Iter<'a> {}
impl<'a> BitVec<'a> for BitVector {
type Iter = Iter<'a>;
#[inline]
fn len(&self) -> usize {
self.data.len()
}
#[inline]
fn count_ones(&self) -> usize {
self.ones
}
#[inline]
fn get(&self, index: usize) -> bool {
self.data.bit(index)
}
fn iter(&'a self) -> Self::Iter {
Self::Iter {
parent: self,
next: 0,
limit: self.len(),
}
}
}
impl<'a> Rank<'a> for BitVector {
fn supports_rank(&self) -> bool {
self.rank != None
}
fn enable_rank(&mut self) {
if !self.supports_rank() {
let rank_support = RankSupport::new(self);
self.rank = Some(rank_support);
}
}
fn rank(&self, index: usize) -> usize {
if index >= self.len() {
return self.count_ones();
}
let rank_support = self.rank.as_ref().unwrap();
unsafe { rank_support.rank_unchecked(self, index) }
}
}
pub trait Transformation {
fn bit(parent: &BitVector, index: usize) -> bool;
fn word(parent: &BitVector, index: usize) -> u64;
unsafe fn word_unchecked(parent: &BitVector, index: usize) -> u64;
fn count_ones(parent: &BitVector) -> usize;
fn one_iter(parent: &BitVector) -> OneIter<'_, Self>;
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Identity {}
impl Transformation for Identity {
#[inline]
fn bit(parent: &BitVector, index: usize) -> bool {
parent.get(index)
}
#[inline]
fn word(parent: &BitVector, index: usize) -> u64 {
parent.data.word(index)
}
#[inline]
unsafe fn word_unchecked(parent: &BitVector, index: usize) -> u64 {
parent.data.word_unchecked(index)
}
#[inline]
fn count_ones(parent: &BitVector) -> usize {
parent.count_ones()
}
fn one_iter(parent: &BitVector) -> OneIter<'_, Self> {
parent.one_iter()
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Complement {}
impl Transformation for Complement {
#[inline]
fn bit(parent: &BitVector, index: usize) -> bool {
!parent.get(index)
}
fn word(parent: &BitVector, index: usize) -> u64 {
let (last_index, offset) = bits::split_offset(parent.len());
if index >= last_index {
(!parent.data.word(index)) & unsafe { bits::low_set_unchecked(offset) }
} else {
unsafe { !parent.data.word_unchecked(index) }
}
}
unsafe fn word_unchecked(parent: &BitVector, index: usize) -> u64 {
let (last_index, offset) = bits::split_offset(parent.len());
if index >= last_index {
(!parent.data.word_unchecked(index)) & bits::low_set_unchecked(offset)
} else {
!parent.data.word_unchecked(index)
}
}
#[inline]
fn count_ones(parent: &BitVector) -> usize {
parent.count_zeros()
}
fn one_iter(parent: &BitVector) -> OneIter<'_, Self> {
parent.zero_iter()
}
}
#[derive(Clone, Debug)]
pub struct OneIter<'a, T: Transformation + ?Sized> {
parent: &'a BitVector,
next: (usize, usize),
limit: (usize, usize),
_marker: marker::PhantomData<T>,
}
impl<'a, T: Transformation + ?Sized> OneIter<'a, T> {
fn empty_iter(parent: &'a BitVector) -> OneIter<'a, T> {
OneIter {
parent,
next: (T::count_ones(parent), parent.len()),
limit: (T::count_ones(parent), parent.len()),
_marker: marker::PhantomData,
}
}
}
impl<'a, T: Transformation + ?Sized> Iterator for OneIter<'a, T> {
type Item = (usize, usize);
fn next(&mut self) -> Option<Self::Item> {
if self.next.0 >= self.limit.0 {
None
} else {
let (mut index, offset) = bits::split_offset(self.next.1);
let mut word = unsafe { T::word_unchecked(self.parent, index) & !bits::low_set_unchecked(offset) };
while word == 0 {
index += 1;
word = unsafe { T::word_unchecked(self.parent, index) };
}
let offset = word.trailing_zeros() as usize;
let result = (self.next.0, bits::bit_offset(index, offset));
self.next = (result.0 + 1, result.1 + 1);
Some(result)
}
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
if self.next.0 + n >= self.limit.0 {
self.next = self.limit;
return None;
}
let (mut index, offset) = bits::split_offset(self.next.1);
let mut word = unsafe { T::word_unchecked(self.parent, index) & !bits::low_set_unchecked(offset) };
let mut relative_rank = n;
let mut ones = word.count_ones() as usize;
while ones <= relative_rank {
index += 1;
word = unsafe { T::word_unchecked(self.parent, index) };
relative_rank -= ones;
ones = word.count_ones() as usize;
}
let offset = unsafe { bits::select(word, relative_rank) };
let result = (self.next.0 + n, bits::bit_offset(index, offset));
self.next = (result.0 + 1, result.1 + 1);
Some(result)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.limit.0 - self.next.0;
(remaining, Some(remaining))
}
}
impl<'a, T: Transformation + ?Sized> DoubleEndedIterator for OneIter<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.next.0 >= self.limit.0 {
None
} else {
self.limit = (self.limit.0 - 1, self.limit.1 - 1);
let (mut index, offset) = bits::split_offset(self.limit.1);
let mut word = unsafe { T::word_unchecked(self.parent, index) & bits::low_set_unchecked(offset + 1) };
while word == 0 {
index -= 1;
word = unsafe { T::word_unchecked(self.parent, index) };
}
let offset = bits::WORD_BITS - 1 - (word.leading_zeros() as usize);
self.limit.1 = bits::bit_offset(index, offset);
Some(self.limit)
}
}
}
impl<'a, T: Transformation + ?Sized> ExactSizeIterator for OneIter<'a, T> {}
impl<'a, T: Transformation + ?Sized> FusedIterator for OneIter<'a, T> {}
impl<'a> Select<'a> for BitVector {
type OneIter = OneIter<'a, Identity>;
fn supports_select(&self) -> bool {
self.select != None
}
fn enable_select(&mut self) {
if !self.supports_select() {
let select_support = SelectSupport::<Identity>::new(self);
self.select = Some(select_support);
}
}
fn one_iter(&'a self) -> Self::OneIter {
Self::OneIter {
parent: self,
next: (0, 0),
limit: (Identity::count_ones(self), self.len()),
_marker: marker::PhantomData,
}
}
fn select(&'a self, rank: usize) -> Option<usize> {
if rank >= Identity::count_ones(self) {
None
} else {
let select_support = self.select.as_ref().unwrap();
let value = unsafe { select_support.select_unchecked(self, rank) };
Some(value)
}
}
fn select_iter(&'a self, rank: usize) -> Self::OneIter {
if rank >= Identity::count_ones(self) {
Self::OneIter::empty_iter(self)
} else {
let select_support = self.select.as_ref().unwrap();
let value = unsafe { select_support.select_unchecked(self, rank) };
Self::OneIter {
parent: self,
next: (rank, value),
limit: (Identity::count_ones(self), self.len()),
_marker: marker::PhantomData,
}
}
}
}
impl<'a> SelectZero<'a> for BitVector {
type ZeroIter = OneIter<'a, Complement>;
fn supports_select_zero(&self) -> bool {
self.select_zero != None
}
fn enable_select_zero(&mut self) {
if !self.supports_select_zero() {
let select_support = SelectSupport::<Complement>::new(self);
self.select_zero = Some(select_support);
}
}
fn zero_iter(&'a self) -> Self::ZeroIter {
Self::ZeroIter {
parent: self,
next: (0, 0),
limit: (Complement::count_ones(self), self.len()),
_marker: marker::PhantomData,
}
}
fn select_zero(&'a self, rank: usize) -> Option<usize> {
if rank >= Complement::count_ones(self) {
None
} else {
let select_support = self.select_zero.as_ref().unwrap();
let value = unsafe { select_support.select_unchecked(self, rank) };
Some(value)
}
}
fn select_zero_iter(&'a self, rank: usize) -> Self::ZeroIter {
if rank >= Complement::count_ones(self) {
Self::ZeroIter::empty_iter(self)
} else {
let select_support = self.select_zero.as_ref().unwrap();
let value = unsafe { select_support.select_unchecked(self, rank) };
Self::ZeroIter {
parent: self,
next: (rank, value),
limit: (Complement::count_ones(self), self.len()),
_marker: marker::PhantomData,
}
}
}
}
impl<'a> PredSucc<'a> for BitVector {
type OneIter = OneIter<'a, Identity>;
fn supports_pred_succ(&self) -> bool {
self.rank != None && self.select != None
}
fn enable_pred_succ(&mut self) {
self.enable_rank();
self.enable_select();
}
fn predecessor(&'a self, value: usize) -> Self::OneIter {
let rank = self.rank(value + 1);
if rank == 0 {
Self::OneIter::empty_iter(self)
} else {
self.select_iter(rank - 1)
}
}
fn successor(&'a self, value: usize) -> Self::OneIter {
let rank = self.rank(value);
if rank >= self.count_ones() {
Self::OneIter::empty_iter(self)
} else {
self.select_iter(rank)
}
}
}
impl Serialize for BitVector {
fn serialize_header<T: io::Write>(&self, writer: &mut T) -> io::Result<()> {
self.ones.serialize(writer)?;
Ok(())
}
fn serialize_body<T: io::Write>(&self, writer: &mut T) -> io::Result<()> {
self.data.serialize(writer)?;
self.rank.serialize(writer)?;
self.select.serialize(writer)?;
self.select_zero.serialize(writer)?;
Ok(())
}
fn load<T: io::Read>(reader: &mut T) -> io::Result<Self> {
let ones = usize::load(reader)?;
let data = RawVector::load(reader)?;
if ones > data.len() {
return Err(Error::new(ErrorKind::InvalidData, "Too many set bits"));
}
let rank = Option::<RankSupport>::load(reader)?;
if let Some(value) = rank.as_ref() {
if value.blocks() != bits::div_round_up(data.len(), RankSupport::BLOCK_SIZE) {
return Err(Error::new(ErrorKind::InvalidData, "Invalid number of rank blocks"))
}
}
let select = Option::<SelectSupport<Identity>>::load(reader)?;
if let Some(value) = select.as_ref() {
if value.superblocks() != bits::div_round_up(ones, SelectSupport::<Identity>::SUPERBLOCK_SIZE) {
return Err(Error::new(ErrorKind::InvalidData, "Invalid number of select superblocks"))
}
}
let select_zero = Option::<SelectSupport<Complement>>::load(reader)?;
if let Some(value) = select_zero.as_ref() {
if value.superblocks() != bits::div_round_up(data.len() - ones, SelectSupport::<Complement>::SUPERBLOCK_SIZE) {
return Err(Error::new(ErrorKind::InvalidData, "Invalid number of select_zero superblocks"))
}
}
Ok(BitVector {
ones, data, rank, select, select_zero,
})
}
fn size_in_elements(&self) -> usize {
self.ones.size_in_elements() +
self.data.size_in_elements() +
self.rank.size_in_elements() +
self.select.size_in_elements() +
self.select_zero.size_in_elements()
}
}
impl AsRef<RawVector> for BitVector {
#[inline]
fn as_ref(&self) -> &RawVector {
&(self.data)
}
}
impl From<RawVector> for BitVector {
fn from(data: RawVector) -> Self {
let ones = data.count_ones();
BitVector {
ones,
data,
rank: None,
select: None,
select_zero: None,
}
}
}
impl From<BitVector> for RawVector {
fn from(source: BitVector) -> Self {
source.data
}
}
impl FromIterator<bool> for BitVector {
fn from_iter<I: IntoIterator<Item = bool>>(iter: I) -> Self {
let iter = iter.into_iter();
let (lower_bound, _) = iter.size_hint();
let mut data = RawVector::with_capacity(lower_bound);
for value in iter {
data.push_bit(value);
}
let ones = data.count_ones();
BitVector {
ones,
data,
rank: None,
select: None,
select_zero: None,
}
}
}