pub struct RsVec { /* private fields */ }Expand description
A bitvector that supports constant-time rank and select queries and is optimized for fast queries.
The bitvector is stored as a vector of u64s. The bit-vector stores meta-data for constant-time
rank and select queries, which takes sub-linear additional space. The space overhead is
28 bits per 512 bits of user data (~5.47%).
§Example
use vers_vecs::{BitVec, RsVec};
let mut bit_vec = BitVec::new();
bit_vec.append_word(u64::MAX);
let rs_vec = RsVec::from_bit_vec(bit_vec);
assert_eq!(rs_vec.rank1(64), 64);
assert_eq!(rs_vec.select1(64), 64);Implementations§
Source§impl RsVec
impl RsVec
Sourcepub fn select_iter<const ZERO: bool>(&self) -> SelectIter<'_, ZERO> ⓘ
pub fn select_iter<const ZERO: bool>(&self) -> SelectIter<'_, ZERO> ⓘ
Get an iterator over the bits in the vector. The iterator will return the indices of the
0-bits or the 1-bits in the vector, depending on the constant ZERO
(if true, 0-bits are returned).
It uses the select data structure to speed up iteration.
It is also faster than calling select on each rank, because the iterator exploits
the linear access pattern.
This method has convenience methods iter0 and iter1.
Sourcepub fn into_select_iter<const ZERO: bool>(self) -> SelectIntoIter<ZERO> ⓘ
pub fn into_select_iter<const ZERO: bool>(self) -> SelectIntoIter<ZERO> ⓘ
Convert vector into an iterator over the bits in the vector. The iterator will return the indices of the
0-bits or the 1-bits in the vector, depending on the constant ZERO
(if true, 0-bits are returned).
It uses the select data structure to speed up iteration.
It is also faster than calling select on each rank, because the iterator exploits
the linear access pattern.
This method has convenience methods into_iter0 and into_iter1.
Sourcepub fn iter0(&self) -> SelectIter<'_, true> ⓘ
pub fn iter0(&self) -> SelectIter<'_, true> ⓘ
Get an iterator over the 0-bits in the vector that uses the select data structure to speed
up iteration.
It is faster than calling select0 on each rank, because the iterator
exploits the linear access pattern.
See SelectIter for more information.
Sourcepub fn iter1(&self) -> SelectIter<'_, false> ⓘ
pub fn iter1(&self) -> SelectIter<'_, false> ⓘ
Get an iterator over the 1-bits in the vector that uses the select data structure to speed
up iteration.
It is faster than calling select1 on each rank, because the iterator
exploits the linear access pattern.
See SelectIter for more information.
Sourcepub fn into_iter0(self) -> SelectIntoIter<true> ⓘ
pub fn into_iter0(self) -> SelectIntoIter<true> ⓘ
Convert vector into an iterator over the 0-bits in the vector
that uses the select data structure to speed up iteration.
It is faster than calling select0 on each rank, because the iterator
exploits the linear access pattern.
See SelectIntoIter for more information.
Sourcepub fn into_iter1(self) -> SelectIntoIter<false> ⓘ
pub fn into_iter1(self) -> SelectIntoIter<false> ⓘ
Convert vector into an iterator over the 1-bits in the vector
that uses the select data structure to speed up iteration.
It is faster than calling select1 on each rank, because the iterator
exploits the linear access pattern.
See SelectIntoIter for more information.
Source§impl RsVec
impl RsVec
Source§impl RsVec
impl RsVec
Sourcepub fn from_bit_vec(vec: BitVec) -> RsVec
pub fn from_bit_vec(vec: BitVec) -> RsVec
Sourcepub fn rank0(&self, pos: usize) -> usize
pub fn rank0(&self, pos: usize) -> usize
Return the 0-rank of the bit at the given position. The 0-rank is the number of 0-bits in the vector up to but excluding the bit at the given position. Calling this function with an index larger than the length of the bit-vector will report the total number of 0-bits in the bit-vector.
§Parameters
pos: The position of the bit to return the rank of.
Sourcepub fn rank1(&self, pos: usize) -> usize
pub fn rank1(&self, pos: usize) -> usize
Return the 1-rank of the bit at the given position. The 1-rank is the number of 1-bits in the vector up to but excluding the bit at the given position. Calling this function with an index larger than the length of the bit-vector will report the total number of 1-bits in the bit-vector.
§Parameters
pos: The position of the bit to return the rank of.
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Return the length of the vector, i.e. the number of bits it contains.
Sourcepub fn get(&self, pos: usize) -> Option<u64>
pub fn get(&self, pos: usize) -> Option<u64>
Return the bit at the given position. The bit takes the least significant
bit of the returned u64 word.
If the position is larger than the length of the vector, None is returned.
Sourcepub fn get_unchecked(&self, pos: usize) -> u64
pub fn get_unchecked(&self, pos: usize) -> u64
Return the bit at the given position. The bit takes the least significant bit of the returned u64 word.
§Panics
This function may panic if pos >= self.len() (alternatively, it may return garbage).
Sourcepub fn get_bits(&self, pos: usize, len: usize) -> Option<u64>
pub fn get_bits(&self, pos: usize, len: usize) -> Option<u64>
Return multiple bits at the given position. The number of bits to return is given by len.
At most 64 bits can be returned.
If the position at the end of the query is larger than the length of the vector,
None is returned (even if the query partially overlaps with the vector).
If the length of the query is larger than 64, None is returned.
Sourcepub fn get_bits_unchecked(&self, pos: usize, len: usize) -> u64
pub fn get_bits_unchecked(&self, pos: usize, len: usize) -> u64
Return multiple bits at the given position. The number of bits to return is given by len.
At most 64 bits can be returned.
This function is always inlined, because it gains a lot from loop optimization and can utilize the processor pre-fetcher better if it is.
§Errors
If the length of the query is larger than 64, unpredictable data will be returned.
Use get_bits to properly handle this case with an Option.
§Panics
If the position or interval is larger than the length of the vector, the function will either return unpredictable data, or panic.
Sourcepub fn into_bit_vec(self) -> BitVec
pub fn into_bit_vec(self) -> BitVec
Convert the RsVec into a BitVec.
This consumes the RsVec, and discards all meta-data.
Since RsVecs are innately immutable, this conversion is the only way to modify the
underlying data.
§Example
use vers_vecs::{BitVec, RsVec};
let mut bit_vec = BitVec::new();
bit_vec.append_word(u64::MAX);
let rs_vec = RsVec::from_bit_vec(bit_vec);
assert_eq!(rs_vec.rank1(64), 64);
let mut bit_vec = rs_vec.into_bit_vec();
bit_vec.flip_bit(32);
let rs_vec = RsVec::from_bit_vec(bit_vec);
assert_eq!(rs_vec.rank1(64), 63);
assert_eq!(rs_vec.select0(0), 32);Sourcepub fn sparse_equals<const ZERO: bool>(&self, other: &Self) -> bool
pub fn sparse_equals<const ZERO: bool>(&self, other: &Self) -> bool
Check if two RsVecs are equal. For sparse vectors (either sparsely filled with 1-bits or
0-bits), this is faster than comparing the vectors bit by bit.
Choose the value of ZERO depending on which bits are more sparse.
This method is faster than full_equals for sparse vectors beginning at roughly 1
million bits. Above 4 million bits, this method becomes faster than full equality in general.
§Parameters
other: The otherRsVecto compare to.ZERO: Whether to compare the sparse 0-bits (true) or the sparse 1-bits (false).
§Returns
true if the vectors’ contents are equal, false otherwise.
Sourcepub fn full_equals(&self, other: &Self) -> bool
pub fn full_equals(&self, other: &Self) -> bool
Check if two RsVecs are equal. This compares limb by limb. This is usually faster than a
sparse_equals call for small vectors.
§Parameters
other: The otherRsVecto compare to.
§Returns
true if the vectors’ contents are equal, false otherwise.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for RsVec
impl<'de> Deserialize<'de> for RsVec
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl<'a> IntoIterator for &'a RsVec
impl<'a> IntoIterator for &'a RsVec
Source§impl<'a> IntoIterator for &'a mut RsVec
impl<'a> IntoIterator for &'a mut RsVec
Source§impl IntoIterator for RsVec
impl IntoIterator for RsVec
Source§impl MemDbgImpl for RsVecwhere
Vec<u64>: MemDbgImpl + FlatType,
usize: MemDbgImpl + FlatType,
Vec<BlockDescriptor>: MemDbgImpl + FlatType,
Vec<SuperBlockDescriptor>: MemDbgImpl + FlatType,
Vec<SelectSuperBlockDescriptor>: MemDbgImpl + FlatType,
impl MemDbgImpl for RsVecwhere
Vec<u64>: MemDbgImpl + FlatType,
usize: MemDbgImpl + FlatType,
Vec<BlockDescriptor>: MemDbgImpl + FlatType,
Vec<SuperBlockDescriptor>: MemDbgImpl + FlatType,
Vec<SelectSuperBlockDescriptor>: MemDbgImpl + FlatType,
fn _mem_dbg_rec_on( &self, _memdbg_writer: &mut impl Write, _memdbg_total_size: usize, _memdbg_max_depth: usize, _memdbg_prefix: &mut String, _memdbg_is_last: bool, _memdbg_flags: DbgFlags, _memdbg_refs: &mut HashSet<usize>, ) -> Result
fn _mem_dbg_depth_on( &self, writer: &mut impl Write, total_size: usize, max_depth: usize, prefix: &mut String, field_name: Option<&str>, is_last: bool, padded_size: usize, flags: DbgFlags, dbg_refs: &mut HashSet<usize>, ) -> Result<(), Error>
Source§fn _mem_dbg_depth_on_impl(
&self,
writer: &mut impl Write,
total_size: usize,
max_depth: usize,
prefix: &mut String,
field_name: Option<&str>,
is_last: bool,
padded_size: usize,
flags: DbgFlags,
dbg_refs: &mut HashSet<usize>,
ref_display: RefDisplay,
) -> Result<(), Error>
fn _mem_dbg_depth_on_impl( &self, writer: &mut impl Write, total_size: usize, max_depth: usize, prefix: &mut String, field_name: Option<&str>, is_last: bool, padded_size: usize, flags: DbgFlags, dbg_refs: &mut HashSet<usize>, ref_display: RefDisplay, ) -> Result<(), Error>
Source§impl MemSize for RsVec
impl MemSize for RsVec
Source§impl PartialEq for RsVec
impl PartialEq for RsVec
Source§fn eq(&self, other: &Self) -> bool
fn eq(&self, other: &Self) -> bool
Check if two RsVecs are equal. This method calls sparse_equals if the vector has more
than 4’000’000 bits, and full_equals otherwise.
This was determined with benchmarks on an x86_64 machine,
on which sparse_equals outperforms full_equals consistently above this threshold.
§Parameters
other: The otherRsVecto compare to.
§Returns
true if the vectors’ contents are equal, false otherwise.
Auto Trait Implementations§
impl Freeze for RsVec
impl RefUnwindSafe for RsVec
impl Send for RsVec
impl Sync for RsVec
impl Unpin for RsVec
impl UnsafeUnpin for RsVec
impl UnwindSafe for RsVec
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> MemDbg for Twhere
T: MemDbgImpl,
impl<T> MemDbg for Twhere
T: MemDbgImpl,
Source§fn mem_dbg(&self, flags: DbgFlags) -> Result<(), Error>
fn mem_dbg(&self, flags: DbgFlags) -> Result<(), Error>
std only.Source§fn mem_dbg_on(
&self,
writer: &mut impl Write,
flags: DbgFlags,
) -> Result<(), Error>
fn mem_dbg_on( &self, writer: &mut impl Write, flags: DbgFlags, ) -> Result<(), Error>
core::fmt::Write debug info about the structure memory
usage, expanding all levels of nested structures.Source§fn mem_dbg_depth(&self, max_depth: usize, flags: DbgFlags) -> Result<(), Error>
fn mem_dbg_depth(&self, max_depth: usize, flags: DbgFlags) -> Result<(), Error>
std only.mem_dbg, but expanding only up to max_depth
levels of nested structures.Source§fn mem_dbg_depth_on(
&self,
writer: &mut impl Write,
max_depth: usize,
flags: DbgFlags,
) -> Result<(), Error>
fn mem_dbg_depth_on( &self, writer: &mut impl Write, max_depth: usize, flags: DbgFlags, ) -> Result<(), Error>
core::fmt::Write debug info about the structure memory
usage as mem_dbg_on, but expanding only up to
max_depth levels of nested structures.