#![cfg(target_pointer_width = "64")]
pub mod inner;
use std::io::{Read, Write};
use anyhow::Result;
use crate::bit_vectors::prelude::*;
use crate::bit_vectors::BitVector;
use crate::Serializable;
use inner::Rank9SelIndex;
#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct Rank9Sel {
bv: BitVector,
rs: Rank9SelIndex,
}
impl Rank9Sel {
pub fn new(bv: BitVector) -> Self {
let rs = Rank9SelIndex::new(&bv);
Self { bv, rs }
}
#[must_use]
pub fn select1_hints(mut self) -> Self {
self.rs = self.rs.select1_hints();
self
}
#[must_use]
pub fn select0_hints(mut self) -> Self {
self.rs = self.rs.select0_hints();
self
}
pub fn from_bits<I>(bits: I) -> Self
where
I: IntoIterator<Item = bool>,
{
Self::new(BitVector::from_bits(bits))
}
pub const fn bit_vector(&self) -> &BitVector {
&self.bv
}
pub const fn rs_index(&self) -> &Rank9SelIndex {
&self.rs
}
pub const fn len(&self) -> usize {
self.bv.len()
}
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl Build for Rank9Sel {
fn build_from_bits<I>(
bits: I,
_with_rank: bool,
with_select1: bool,
with_select0: bool,
) -> Result<Self>
where
I: IntoIterator<Item = bool>,
Self: Sized,
{
let mut rsbv = Self::from_bits(bits);
if with_select1 {
rsbv = rsbv.select1_hints();
}
if with_select0 {
rsbv = rsbv.select0_hints();
}
Ok(rsbv)
}
}
impl NumBits for Rank9Sel {
#[inline(always)]
fn num_bits(&self) -> usize {
self.len()
}
#[inline(always)]
fn num_ones(&self) -> usize {
self.rs.num_ones()
}
}
impl Access for Rank9Sel {
fn access(&self, pos: usize) -> Option<bool> {
self.bv.access(pos)
}
}
impl Rank for Rank9Sel {
fn rank1(&self, pos: usize) -> Option<usize> {
unsafe { self.rs.rank1(&self.bv, pos) }
}
fn rank0(&self, pos: usize) -> Option<usize> {
unsafe { self.rs.rank0(&self.bv, pos) }
}
}
impl Select for Rank9Sel {
fn select1(&self, k: usize) -> Option<usize> {
unsafe { self.rs.select1(&self.bv, k) }
}
fn select0(&self, k: usize) -> Option<usize> {
unsafe { self.rs.select0(&self.bv, k) }
}
}
impl Serializable for Rank9Sel {
fn serialize_into<W: Write>(&self, mut writer: W) -> Result<usize> {
let mut mem = 0;
mem += self.bv.serialize_into(&mut writer)?;
mem += self.rs.serialize_into(&mut writer)?;
Ok(mem)
}
fn deserialize_from<R: Read>(mut reader: R) -> Result<Self> {
let bv = BitVector::deserialize_from(&mut reader)?;
let rs = Rank9SelIndex::deserialize_from(&mut reader)?;
Ok(Self { bv, rs })
}
fn size_in_bytes(&self) -> usize {
self.bv.size_in_bytes() + self.rs.size_in_bytes()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rank1_all_zeros() {
let bv = Rank9Sel::from_bits([false, false, false]);
assert_eq!(bv.rank1(0), Some(0));
assert_eq!(bv.rank1(1), Some(0));
assert_eq!(bv.rank1(2), Some(0));
assert_eq!(bv.rank1(3), Some(0));
assert_eq!(bv.rank1(4), None);
}
#[test]
fn test_select1_all_zeros() {
let bv = Rank9Sel::from_bits([false, false, false]).select1_hints();
assert_eq!(bv.select1(0), None);
}
#[test]
fn test_rank0_all_ones() {
let bv = Rank9Sel::from_bits([true, true, true]);
assert_eq!(bv.rank0(0), Some(0));
assert_eq!(bv.rank0(1), Some(0));
assert_eq!(bv.rank0(2), Some(0));
assert_eq!(bv.rank0(3), Some(0));
assert_eq!(bv.rank0(4), None);
}
#[test]
fn test_select0_all_ones() {
let bv = Rank9Sel::from_bits([true, true, true]).select0_hints();
assert_eq!(bv.select0(0), None);
}
#[test]
fn test_select0_no_hint() {
let bv = Rank9Sel::from_bits([true, false, false, true]);
assert_eq!(bv.select0(0), Some(1));
assert_eq!(bv.select0(1), Some(2));
assert_eq!(bv.select0(2), None);
}
#[test]
fn test_select1_no_hint() {
let bv = Rank9Sel::from_bits([true, false, false, true]);
assert_eq!(bv.select1(0), Some(0));
assert_eq!(bv.select1(1), Some(3));
assert_eq!(bv.select1(2), None);
}
#[test]
fn test_serialize() {
let mut bytes = vec![];
let bv = Rank9Sel::from_bits([false, true, true, false, true])
.select1_hints()
.select0_hints();
let size = bv.serialize_into(&mut bytes).unwrap();
let other = Rank9Sel::deserialize_from(&bytes[..]).unwrap();
assert_eq!(bv, other);
assert_eq!(size, bytes.len());
assert_eq!(size, bv.size_in_bytes());
}
}