Skip to main content

Cursor

Struct Cursor 

Source
pub struct Cursor<'a, CC, VC, WC> { /* private fields */ }
Expand description

Forward cursor over a RankSelect.

Use this instead of repeated rank/select calls when you want to traverse the bitvector in order. The cursor caches a current word and running rank, so a single word load serves many subsequent operations — no re-probing counts or rescanning words.

At a high level the cursor maintains an invariant pair (pos, rank): pos is the next bit to consider, and rank is the number of 1-bits in [0, pos). Every operation maintains this pair so that callers can read either coordinate freely.

Pick the method that matches the question you want to answer:

OperationUse when you want…
next_one“Where is the next 1-bit?” — emits 1-bit positions in order.
step“What is the bit at the current position?” — read-by-bit traversal.
seek_to_pos“Jump to bit position p; what is its rank?” — random forward seek.
seek_to_rank“Jump to the k-th 1-bit; where is it?” — equivalent to select.

The cursor is forward-only: every operation advances pos and rank monotonically. Trying to seek backward triggers a debug-assertion failure.

Implementations§

Source§

impl<'a, CC: Len + IndexAs<u64>, VC: Len + IndexAs<u64>, WC: IndexAs<u64>> Cursor<'a, CC, VC, WC>

Source

pub fn pos(&self) -> usize

Position of the next bit to consider.

Source

pub fn rank(&self) -> u64

Number of 1-bits strictly before pos().

Source

pub fn total_bits(&self) -> usize

Total number of bits in the underlying vector.

Source

pub fn next_one(&mut self) -> Option<usize>

Emit the next 1-bit position in order; advance past it.

Equivalent to select(self.rank()) followed by stepping one past that position, but amortized: a single word load serves up to 64 results.

Use this for streaming through every set bit. The canonical example is recovering monotone Vecs bounds from an RS-encoded unary bitvector: each call returns the next bound’s bit position, no per-call re-probing of counts. Returns None once all set bits have been emitted.

Source

pub fn step(&mut self) -> Option<bool>

Advance one bit. Return its value: Some(true) for 1, Some(false) for 0, or None if past the end.

Use this when you need to visit every bit in order, regardless of value. Common pattern: the lookup-walk loop in a hash table that probes consecutive slots, deciding what to do based on whether each slot is occupied. Each call is a single bit-test + an occasional word-boundary crossing.

Source

pub fn seek_to_pos(&mut self, target: usize) -> bool

Jump forward to bit position target and report its rank (via the cursor’s state) without consuming the bit there.

After return, pos() == target and rank() == rank(target) (the count of 1-bits strictly before target). A subsequent step reads the bit at target.

Use this when you have a known target position and want to read or continue from there. Typical use is hash-table lookup: a query’s slot position is computed from its hash; you want to jump there and then walk forward through the probe chain.

Fast path: if target lies within the cursor’s current word, this is a popcount + mask. Otherwise it pays one RankSelect::rank call to re-anchor.

target must be >= self.pos() (forward-only; debug-asserts otherwise). Returns false if target is past the end of the bitvector.

Source

pub fn seek_to_rank(&mut self, target: u64) -> Option<usize>

Jump forward to the target-th set bit (0-indexed) and return its position. Equivalent to RankSelect::select for the cursor’s current state.

After return, rank() == target + 1 (the target bit has been consumed).

Use this when you have a target rank and want the position. Typical use is “give me bound[k]” against an RS-encoded Vecs-bounds bitvector, possibly skipping forward over a stretch of consecutive bounds you don’t care about.

Fast path: if the target’s bit lies within the cursor’s current word, this is a select_in_word + bit-clear. Otherwise it pays a binary search over counts, mirroring RankSelect::select.

target must be >= self.rank() (forward-only; debug-asserts otherwise). Returns None if there are fewer than target + 1 set bits in total.

Auto Trait Implementations§

§

impl<'a, CC, VC, WC> Freeze for Cursor<'a, CC, VC, WC>

§

impl<'a, CC, VC, WC> RefUnwindSafe for Cursor<'a, CC, VC, WC>

§

impl<'a, CC, VC, WC> Send for Cursor<'a, CC, VC, WC>
where CC: Sync, VC: Sync, WC: Sync,

§

impl<'a, CC, VC, WC> Sync for Cursor<'a, CC, VC, WC>
where CC: Sync, VC: Sync, WC: Sync,

§

impl<'a, CC, VC, WC> Unpin for Cursor<'a, CC, VC, WC>

§

impl<'a, CC, VC, WC> UnsafeUnpin for Cursor<'a, CC, VC, WC>

§

impl<'a, CC, VC, WC> UnwindSafe for Cursor<'a, CC, VC, WC>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.