use std::ops::Range;
use std::sync::Arc;
use crate::model::Coord;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Block {
pub size: Coord,
pub query_start: Coord,
pub reference_start: Coord,
}
#[derive(Debug, Default)]
pub struct Blocks {
sizes: Vec<Coord>,
query_starts: Vec<Coord>,
reference_starts: Vec<Coord>,
}
impl Blocks {
pub fn new() -> Self {
Blocks::default()
}
pub fn with_capacity(n: usize) -> Self {
Blocks {
sizes: Vec::with_capacity(n),
query_starts: Vec::with_capacity(n),
reference_starts: Vec::with_capacity(n),
}
}
pub fn push(&mut self, size: Coord, query_start: Coord, reference_start: Coord) -> usize {
let idx = self.sizes.len();
self.sizes.push(size);
self.query_starts.push(query_start);
self.reference_starts.push(reference_start);
idx
}
pub fn len(&self) -> usize {
self.sizes.len()
}
pub fn is_empty(&self) -> bool {
self.sizes.is_empty()
}
#[cfg_attr(not(feature = "parallel"), allow(dead_code))]
pub(crate) fn append(&mut self, other: &mut Blocks) {
self.sizes.append(&mut other.sizes);
self.query_starts.append(&mut other.query_starts);
self.reference_starts.append(&mut other.reference_starts);
}
pub(crate) fn sizes_mut(&mut self) -> &mut Vec<Coord> {
&mut self.sizes
}
pub(crate) fn query_starts_mut(&mut self) -> &mut Vec<Coord> {
&mut self.query_starts
}
pub(crate) fn reference_starts_mut(&mut self) -> &mut Vec<Coord> {
&mut self.reference_starts
}
}
#[derive(Debug, Clone)]
pub struct BlockSlice {
storage: Arc<Blocks>,
range: Range<usize>,
}
impl BlockSlice {
pub fn new(storage: Arc<Blocks>, range: Range<usize>) -> Self {
BlockSlice { storage, range }
}
pub fn len(&self) -> usize {
self.range.len()
}
pub fn is_empty(&self) -> bool {
self.range.is_empty()
}
pub fn sizes(&self) -> &[Coord] {
&self.storage.sizes[self.range.clone()]
}
pub fn query_starts(&self) -> &[Coord] {
&self.storage.query_starts[self.range.clone()]
}
pub fn reference_starts(&self) -> &[Coord] {
&self.storage.reference_starts[self.range.clone()]
}
pub fn get(&self, i: usize) -> Option<Block> {
if i >= self.len() {
return None;
}
let idx = self.range.start + i;
Some(Block {
size: self.storage.sizes[idx],
query_start: self.storage.query_starts[idx],
reference_start: self.storage.reference_starts[idx],
})
}
pub fn iter(&self) -> impl Iterator<Item = Block> + '_ {
(0..self.len()).map(move |i| self.get(i).expect("index within range"))
}
}