Skip to main content

SeqVecSlice

Struct SeqVecSlice 

Source
pub struct SeqVecSlice<'a, T: Storable, E: Endianness, B: AsRef<[u64]>> { /* private fields */ }
Expand description

An immutable, zero-copy slice of a SeqVec.

This struct provides a view into a contiguous portion of a SeqVec without copying the underlying compressed data. It is created by the slice or split_at methods on a SeqVec.

All operations on a SeqVecSlice are relative to the start of the slice, not the parent vector. The slice contains a contiguous range of sequences.

§Examples

use compressed_intvec::seq::{SeqVec, LESeqVec};

let sequences: &[&[u32]] = &[&[1, 2], &[3, 4, 5], &[6], &[7, 8, 9, 10]];
let vec: LESeqVec<u32> = SeqVec::from_slices(sequences)?;

// Create a slice of sequences 1 through 2 (indices 1 and 2)
let slice = vec.slice(1, 2).unwrap();

assert_eq!(slice.len(), 2);

// Accessing a sequence within the slice
// Index 0 of the slice corresponds to sequence 1 of the original vector
let seq0: Vec<u32> = slice.get(0).unwrap().collect();
assert_eq!(seq0, vec![3, 4, 5]);

// Iterating over the slice
let all_values: Vec<Vec<u32>> = slice.iter()
    .map(|seq| seq.collect())
    .collect();
assert_eq!(all_values, vec![vec![3, 4, 5], vec![6]]);

Implementations§

Source§

impl<'a, T: Storable, E: Endianness, B: AsRef<[u64]>> SeqVecSlice<'a, T, E, B>

Source

pub fn len(&self) -> usize

Returns the number of sequences in the slice.

Source

pub fn is_empty(&self) -> bool

Returns true if the slice contains no sequences.

Source

pub fn get(&self, index: usize) -> Option<SeqIter<'_, T, E>>
where for<'b> BufBitReader<E, MemWordReader<u64, &'b [u64], true>, DefaultReadParams>: BitRead<E, Error = Infallible> + CodesRead<E> + BitSeek<Error = Infallible>,

Returns an iterator over the elements of the sequence at index within the slice, or None if the index is out of bounds.

The index is relative to the start of the slice.

Source

pub unsafe fn get_unchecked(&self, index: usize) -> SeqIter<'_, T, E>
where for<'b> BufBitReader<E, MemWordReader<u64, &'b [u64], true>, DefaultReadParams>: BitRead<E, Error = Infallible> + CodesRead<E> + BitSeek<Error = Infallible>,

Returns an iterator over the elements of the sequence at index within the slice without bounds checking.

The index is relative to the start of the slice.

§Safety

Calling this method with an out-of-bounds index is undefined behavior. The caller must ensure that index < self.len().

Source

pub fn decode_vec(&self, index: usize) -> Option<Vec<T>>
where for<'b> BufBitReader<E, MemWordReader<u64, &'b [u64], true>, DefaultReadParams>: BitRead<E, Error = Infallible> + CodesRead<E> + BitSeek<Error = Infallible>,

Returns the sequence at index as a materialized Vec<T>, or None if the index is out of bounds.

This method fully decodes the sequence and allocates a new vector.

§Examples
use compressed_intvec::seq::{SeqVec, LESeqVec};

let sequences: &[&[u32]] = &[&[1, 2], &[3, 4, 5], &[6]];
let vec: LESeqVec<u32> = SeqVec::from_slices(sequences)?;

let slice = vec.slice(1, 2).unwrap();
assert_eq!(slice.decode_vec(0), Some(vec![3, 4, 5]));
assert_eq!(slice.decode_vec(1), Some(vec![6]));
assert_eq!(slice.decode_vec(2), None); // Out of bounds
Source

pub unsafe fn decode_vec_unchecked(&self, index: usize) -> Vec<T>
where for<'b> BufBitReader<E, MemWordReader<u64, &'b [u64], true>, DefaultReadParams>: BitRead<E, Error = Infallible> + CodesRead<E> + BitSeek<Error = Infallible>,

Returns the sequence at index as a materialized Vec<T> without bounds checking.

§Safety

Calling this method with an out-of-bounds index is undefined behavior.

Source

pub fn decode_into(&self, index: usize, buf: &mut Vec<T>) -> Option<usize>
where for<'b> BufBitReader<E, MemWordReader<u64, &'b [u64], true>, DefaultReadParams>: BitRead<E, Error = Infallible> + CodesRead<E> + BitSeek<Error = Infallible>,

Decodes the sequence at index into a reusable buffer.

The buffer is cleared and then filled with the decoded sequence elements. Returns the number of elements decoded, or None if the index is out of bounds.

§Examples
use compressed_intvec::seq::{SeqVec, LESeqVec};

let sequences: &[&[u32]] = &[&[1, 2], &[3, 4, 5], &[6]];
let vec: LESeqVec<u32> = SeqVec::from_slices(sequences)?;

let slice = vec.slice(1, 2).unwrap();

let mut buf = Vec::new();
assert_eq!(slice.decode_into(0, &mut buf), Some(3));
assert_eq!(buf, vec![3, 4, 5]);

// Buffer is reused (cleared internally).
assert_eq!(slice.decode_into(1, &mut buf), Some(1));
assert_eq!(buf, vec![6]);
Source

pub unsafe fn decode_into_unchecked( &self, index: usize, buf: &mut Vec<T>, ) -> usize
where for<'b> BufBitReader<E, MemWordReader<u64, &'b [u64], true>, DefaultReadParams>: BitRead<E, Error = Infallible> + CodesRead<E> + BitSeek<Error = Infallible>,

Decodes sequence index into the provided buffer without bounds checking.

§Safety

Calling this method with an out-of-bounds index is undefined behavior.

Source

pub fn iter(&self) -> SeqVecSliceIter<'_, T, E, B>
where for<'b> BufBitReader<E, MemWordReader<u64, &'b [u64], true>, DefaultReadParams>: BitRead<E, Error = Infallible> + CodesRead<E> + BitSeek<Error = Infallible>,

Returns an iterator over the sequences in the slice.

Source§

impl<T, E, B> SeqVecSlice<'_, T, E, B>
where T: Storable + PartialEq, E: Endianness, B: AsRef<[u64]>, for<'b> BufBitReader<E, MemWordReader<u64, &'b [u64], true>, DefaultReadParams>: BitRead<E, Error = Infallible> + CodesRead<E> + BitSeek<Error = Infallible>,

Binary searches this slice for a sequence matching the given elements.

If the sequence is found, returns Ok(usize) with the index of the matching sequence within the slice. If not found, returns Err(usize) with the insertion point to maintain order.

The comparison is performed element-by-element with early termination: sequences with different lengths or any differing element are ordered according to the first difference encountered.

§Performance Note

Each binary search probe fully decodes a compressed sequence until a difference is found or the sequence ends. For log(n) probes, each decoding is O(m) where m is the sequence length. This is O(m * log n) overall.

  • If sequences are short or differ early, early termination makes this very efficient.
  • If sequences are very long and similar, decoding cost dominates.
  • To extract a key from each sequence efficiently, use binary_search_by_key to extract a sortable key from the compressed data (e.g., first element) rather than the full sequence.
§Examples
use compressed_intvec::seq::{SeqVec, LESeqVec};

let sequences: &[&[u32]] = &[&[1, 2], &[3, 4, 5], &[6, 7], &[8]];
let vec: LESeqVec<u32> = SeqVec::from_slices(sequences)?;

let slice = vec.slice(0, 4).unwrap();

assert_eq!(slice.binary_search(&[3, 4, 5]), Ok(1));
assert_eq!(slice.binary_search(&[6, 7]), Ok(2));
assert_eq!(slice.binary_search(&[5]), Err(2)); // Would be inserted at index 2
Source

pub fn binary_search_by<F>(&self, f: F) -> Result<usize, usize>
where F: FnMut(SeqIter<'_, T, E>) -> Ordering,

Binary searches this slice with a custom comparison function.

The comparison function receives a SeqIter for the probe sequence and should return the ordering relative to the target.

§Performance Note

The closure receives a SeqIter for the probe sequence, which may require decoding the compressed data. Each probe can involve up to O(m) decoding operations where m is the sequence length.

  • For fast key extraction (first element, hash, etc.), decode only what is needed within the closure and return early.
  • To search by a pre-computed key, use binary_search_by_key instead, which is optimized for key-based comparisons.
  • For comparisons requiring the full sequence, full decoding is unavoidable: O(m * log n).
§Examples
use compressed_intvec::seq::{SeqVec, LESeqVec};
use std::cmp::Ordering;

let sequences: &[&[u32]] = &[&[1], &[1, 2], &[1, 2, 3], &[1, 2, 3, 4]];
let vec: LESeqVec<u32> = SeqVec::from_slices(sequences)?;

let slice = vec.slice(0, 4).unwrap();

// Search by sequence length (decodes all elements)
let result = slice.binary_search_by(|probe| {
    let probe_len = probe.count();
    probe_len.cmp(&3)
});

assert_eq!(result, Ok(2));

// Search by first element only (early termination)
let result = slice.binary_search_by(|mut probe| {
    match probe.next() {
        Some(first) => first.cmp(&1),
        None => Ordering::Less,
    }
});
Source

pub fn binary_search_by_key<K, F>(&self, b: &K, f: F) -> Result<usize, usize>
where F: FnMut(SeqIter<'_, T, E>) -> K, K: Ord,

Binary searches this slice with a key extraction function.

§Examples
use compressed_intvec::seq::{SeqVec, LESeqVec};

let sequences: &[&[u32]] = &[&[10], &[20], &[30, 40], &[50]];
let vec: LESeqVec<u32> = SeqVec::from_slices(sequences)?;

let slice = vec.slice(0, 4).unwrap();

// Search by first element
let result = slice.binary_search_by_key(&30, |mut probe| probe.next().unwrap());
assert_eq!(result, Ok(2)); // Found sequence [30, 40]

Trait Implementations§

Source§

impl<'a, T: Clone + Storable, E: Clone + Endianness, B: Clone + AsRef<[u64]>> Clone for SeqVecSlice<'a, T, E, B>

Source§

fn clone(&self) -> SeqVecSlice<'a, T, E, B>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a, T: Debug + Storable, E: Debug + Endianness, B: Debug + AsRef<[u64]>> Debug for SeqVecSlice<'a, T, E, B>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a, T, E, B> IntoIterator for &'a SeqVecSlice<'a, T, E, B>
where T: Storable, E: Endianness, B: AsRef<[u64]>, for<'b> BufBitReader<E, MemWordReader<u64, &'b [u64], true>, DefaultReadParams>: BitRead<E, Error = Infallible> + CodesRead<E> + BitSeek<Error = Infallible>,

Source§

fn into_iter(self) -> Self::IntoIter

Returns an iterator over the sequences in the slice.

This implementation allows slices to be used in for loops:

for seq in &slice {
    // Process each sequence
}
Source§

type Item = SeqIter<'a, T, E>

The type of the elements being iterated over.
Source§

type IntoIter = SeqVecSliceIter<'a, T, E, B>

Which kind of iterator are we turning this into?
Source§

impl<'a, T, E, B> PartialEq<&SeqVec<T, E, B>> for SeqVecSlice<'a, T, E, B>
where T: Storable + PartialEq, E: Endianness, B: AsRef<[u64]>, for<'b> BufBitReader<E, MemWordReader<u64, &'b [u64], true>, DefaultReadParams>: BitRead<E, Error = Infallible> + CodesRead<E> + BitSeek<Error = Infallible>,

Source§

fn eq(&self, other: &&SeqVec<T, E, B>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<'a, T, E, B> PartialEq<SeqVec<T, E, B>> for SeqVecSlice<'a, T, E, B>
where T: Storable + PartialEq, E: Endianness, B: AsRef<[u64]>, for<'b> BufBitReader<E, MemWordReader<u64, &'b [u64], true>, DefaultReadParams>: BitRead<E, Error = Infallible> + CodesRead<E> + BitSeek<Error = Infallible>,

Source§

fn eq(&self, other: &SeqVec<T, E, B>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<'a, T, E, B> PartialEq<SeqVecSlice<'a, T, E, B>> for SeqVec<T, E, B>
where T: Storable + PartialEq, E: Endianness, B: AsRef<[u64]>, for<'b> BufBitReader<E, MemWordReader<u64, &'b [u64], true>, DefaultReadParams>: BitRead<E, Error = Infallible> + CodesRead<E> + BitSeek<Error = Infallible>,

Source§

fn eq(&self, other: &SeqVecSlice<'a, T, E, B>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<'a, T, E, B> PartialEq for SeqVecSlice<'a, T, E, B>
where T: Storable + PartialEq, E: Endianness, B: AsRef<[u64]>, for<'b> BufBitReader<E, MemWordReader<u64, &'b [u64], true>, DefaultReadParams>: BitRead<E, Error = Infallible> + CodesRead<E> + BitSeek<Error = Infallible>,

Source§

fn eq(&self, other: &SeqVecSlice<'a, T, E, B>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<'a, T, E, B> Eq for SeqVecSlice<'a, T, E, B>
where T: Storable + Eq, E: Endianness, B: AsRef<[u64]>, for<'b> BufBitReader<E, MemWordReader<u64, &'b [u64], true>, DefaultReadParams>: BitRead<E, Error = Infallible> + CodesRead<E> + BitSeek<Error = Infallible>,

Auto Trait Implementations§

§

impl<'a, T, E, B> Freeze for SeqVecSlice<'a, T, E, B>

§

impl<'a, T, E, B> RefUnwindSafe for SeqVecSlice<'a, T, E, B>

§

impl<'a, T, E, B> Send for SeqVecSlice<'a, T, E, B>
where B: Sync, T: Sync,

§

impl<'a, T, E, B> Sync for SeqVecSlice<'a, T, E, B>
where B: Sync, T: Sync,

§

impl<'a, T, E, B> Unpin for SeqVecSlice<'a, T, E, B>

§

impl<'a, T, E, B> UnsafeUnpin for SeqVecSlice<'a, T, E, B>

§

impl<'a, T, E, B> UnwindSafe for SeqVecSlice<'a, T, E, B>

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> CastableFrom<T> for T

Source§

fn cast_from(value: T) -> T

Call Self as W
Source§

impl<T, U> CastableInto<U> for T
where U: CastableFrom<T>,

Source§

fn cast(self) -> U

Call W::cast_from(self)
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DowncastableFrom<T> for T

Source§

fn downcast_from(value: T) -> T

Truncate the current UnsignedInt to a possibly smaller size
Source§

impl<T, U> DowncastableInto<U> for T
where U: DowncastableFrom<T>,

Source§

fn downcast(self) -> U

Call W::downcast_from(self)
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Splat<T> for T

Source§

fn splat(value: T) -> T

Source§

impl<T> To<T> for T

Source§

fn to(self) -> T

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.
Source§

impl<T> UpcastableFrom<T> for T

Source§

fn upcast_from(value: T) -> T

Extend the current UnsignedInt to a possibly bigger size.
Source§

impl<T, U> UpcastableInto<U> for T
where U: UpcastableFrom<T>,

Source§

fn upcast(self) -> U

Call W::upcast_from(self)