use super::{iter::SeqVecBitReader, SeqIter, SeqVec};
use crate::variable::traits::Storable;
use dsi_bitstream::prelude::{BitRead, BitSeek, CodesRead, Endianness};
use std::cmp::Ordering;
use std::fmt;
use std::ops::Range;
#[derive(Debug, Clone)]
pub struct SeqVecSlice<'a, T: Storable, E: Endianness, B: AsRef<[u64]>> {
vec: &'a SeqVec<T, E, B>,
start: usize,
len: usize,
}
impl<'a, T: Storable, E: Endianness, B: AsRef<[u64]>> SeqVecSlice<'a, T, E, B> {
pub(super) fn new(vec: &'a SeqVec<T, E, B>, range: Range<usize>) -> Self {
debug_assert!(
range.end <= vec.num_sequences(),
"Slice range exceeds vector bounds"
);
Self {
vec,
start: range.start,
len: range.len(),
}
}
#[inline]
pub fn len(&self) -> usize {
self.len
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len == 0
}
#[inline]
pub fn get(&self, index: usize) -> Option<SeqIter<'_, T, E>>
where
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
if index >= self.len {
return None;
}
Some(unsafe { self.get_unchecked(index) })
}
#[inline(always)]
pub unsafe fn get_unchecked(&self, index: usize) -> SeqIter<'_, T, E>
where
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
debug_assert!(index < self.len, "Index out of bounds");
let parent_index = self.start + index;
unsafe { self.vec.get_unchecked(parent_index) }
}
#[inline]
pub fn decode_vec(&self, index: usize) -> Option<Vec<T>>
where
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
let parent_index = self.start.checked_add(index)?;
if index >= self.len {
return None;
}
self.vec.decode_vec(parent_index)
}
#[inline]
pub unsafe fn decode_vec_unchecked(&self, index: usize) -> Vec<T>
where
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
let parent_index = self.start + index;
unsafe { self.vec.decode_vec_unchecked(parent_index) }
}
#[inline]
pub fn decode_into(&self, index: usize, buf: &mut Vec<T>) -> Option<usize>
where
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
let parent_index = self.start.checked_add(index)?;
if index >= self.len {
return None;
}
self.vec.decode_into(parent_index, buf)
}
#[inline]
pub unsafe fn decode_into_unchecked(&self, index: usize, buf: &mut Vec<T>) -> usize
where
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
let parent_index = self.start + index;
unsafe { self.vec.decode_into_unchecked(parent_index, buf) }
}
pub fn iter(&self) -> SeqVecSliceIter<'_, T, E, B>
where
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
SeqVecSliceIter::new(self)
}
}
impl<T, E, B> SeqVecSlice<'_, T, E, B>
where
T: Storable + PartialEq,
E: Endianness,
B: AsRef<[u64]>,
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
pub fn binary_search(&self, sequence: &[T]) -> Result<usize, usize>
where
T: Ord,
{
self.binary_search_by(|probe_iter| {
let mut probe_iter = probe_iter.peekable();
let mut seq_iter = sequence.iter().peekable();
loop {
match (probe_iter.next(), seq_iter.next()) {
(Some(a), Some(b)) => {
let cmp = a.cmp(b);
if cmp != Ordering::Equal {
return cmp;
}
}
(None, Some(_)) => return Ordering::Less,
(Some(_), None) => return Ordering::Greater,
(None, None) => return Ordering::Equal,
}
}
})
}
#[inline]
pub fn binary_search_by<F>(&self, mut f: F) -> Result<usize, usize>
where
F: FnMut(SeqIter<'_, T, E>) -> Ordering,
{
let mut low = 0;
let mut high = self.len();
while low < high {
let mid = low + (high - low) / 2;
let cmp = f(unsafe { self.get_unchecked(mid) });
match cmp {
Ordering::Less => low = mid + 1,
Ordering::Equal => return Ok(mid),
Ordering::Greater => high = mid,
}
}
Err(low)
}
#[inline]
pub fn binary_search_by_key<K, F>(&self, b: &K, mut f: F) -> Result<usize, usize>
where
F: FnMut(SeqIter<'_, T, E>) -> K,
K: Ord,
{
self.binary_search_by(|probe| f(probe).cmp(b))
}
}
pub struct SeqVecSliceIter<'a, T: Storable, E: Endianness, B: AsRef<[u64]>> {
slice: &'a SeqVecSlice<'a, T, E, B>,
front: usize,
back: usize,
}
impl<T: Storable, E: Endianness, B: AsRef<[u64]>> fmt::Debug for SeqVecSliceIter<'_, T, E, B> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SeqVecSliceIter")
.field("remaining", &self.back.saturating_sub(self.front))
.finish()
}
}
impl<'a, T, E, B> IntoIterator for &'a SeqVecSlice<'a, T, E, B>
where
T: Storable,
E: Endianness,
B: AsRef<[u64]>,
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
type Item = SeqIter<'a, T, E>;
type IntoIter = SeqVecSliceIter<'a, T, E, B>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T: Storable, E: Endianness, B: AsRef<[u64]>> SeqVecSliceIter<'a, T, E, B> {
fn new(slice: &'a SeqVecSlice<'a, T, E, B>) -> Self {
Self {
slice,
front: 0,
back: slice.len(),
}
}
}
impl<'a, T, E, B> Iterator for SeqVecSliceIter<'a, T, E, B>
where
T: Storable,
E: Endianness,
B: AsRef<[u64]>,
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
type Item = SeqIter<'a, T, E>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.front >= self.back {
return None;
}
let index = self.front;
self.front += 1;
Some(unsafe { self.slice.get_unchecked(index) })
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.back.saturating_sub(self.front);
(remaining, Some(remaining))
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let remaining = self.back.saturating_sub(self.front);
if n >= remaining {
self.front = self.back;
return None;
}
self.front += n;
self.next()
}
#[inline]
fn count(self) -> usize {
self.back.saturating_sub(self.front)
}
}
impl<'a, T, E, B> ExactSizeIterator for SeqVecSliceIter<'a, T, E, B>
where
T: Storable,
E: Endianness,
B: AsRef<[u64]>,
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
fn len(&self) -> usize {
self.back.saturating_sub(self.front)
}
}
impl<'a, T, E, B> std::iter::FusedIterator for SeqVecSliceIter<'a, T, E, B>
where
T: Storable,
E: Endianness,
B: AsRef<[u64]>,
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
}
impl<'a, T, E, B> DoubleEndedIterator for SeqVecSliceIter<'a, T, E, B>
where
T: Storable,
E: Endianness,
B: AsRef<[u64]>,
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
if self.front >= self.back {
return None;
}
self.back -= 1;
Some(unsafe { self.slice.get_unchecked(self.back) })
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let remaining = self.back.saturating_sub(self.front);
if n >= remaining {
self.back = self.front;
return None;
}
self.back -= n;
self.next_back()
}
}
impl<'a, T, E, B> PartialEq<SeqVecSlice<'a, T, E, B>> for SeqVecSlice<'a, T, E, B>
where
T: Storable + PartialEq,
E: Endianness,
B: AsRef<[u64]>,
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
fn eq(&self, other: &SeqVecSlice<'a, T, E, B>) -> bool {
if self.len() != other.len() {
return false;
}
self.iter()
.zip(other.iter())
.all(|(seq_a, seq_b)| seq_a.eq(seq_b))
}
}
impl<'a, T, E, B> Eq for SeqVecSlice<'a, T, E, B>
where
T: Storable + Eq,
E: Endianness,
B: AsRef<[u64]>,
for<'b> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
}
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> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
fn eq(&self, other: &SeqVec<T, E, B>) -> bool {
if self.len() != other.num_sequences() {
return false;
}
self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
}
}
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> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
fn eq(&self, other: &SeqVecSlice<'a, T, E, B>) -> bool {
other.eq(self)
}
}
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> SeqVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
fn eq(&self, other: &&SeqVec<T, E, B>) -> bool {
self.eq(*other)
}
}