const FIRST: u8 = b'a';
const LAST: u8 = b'z';
use crate::sstable::{Error, Result};
pub struct SortedBytesIterator {
buf: Vec<u8>,
current: usize,
first: u8,
last: u8,
counter: usize,
limit: usize,
}
impl Clone for SortedBytesIterator {
fn clone(&self) -> Self {
let length = self.buf.len();
Self {
buf: vec![self.first; length],
current: length,
first: self.first,
last: self.last,
counter: 0,
limit: self.limit,
}
}
}
impl SortedBytesIterator {
pub fn new(length: usize, limit: usize) -> Result<Self> {
Self::new_first_last(length, FIRST, LAST, limit)
}
pub fn reset(&mut self) {
for v in self.buf.iter_mut() {
*v = self.first;
}
self.current = self.buf.len();
self.counter = 0;
}
pub fn new_first_last(length: usize, first: u8, last: u8, limit: usize) -> Result<Self> {
if length == 0 {
return Err(Error::ProgrammingError("length should be greater than 0"));
}
if last <= first {
return Err(Error::ProgrammingError("expected last > first"));
}
let buf = vec![first; length];
Ok(Self {
buf,
current: length,
first,
last,
counter: 0,
limit,
})
}
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<&[u8]> {
let buflen = self.buf.len();
if self.limit > 0 && self.counter == self.limit {
return None;
}
if self.current == buflen {
self.current = buflen - 1;
} else {
loop {
let val = unsafe { self.buf.get_unchecked_mut(self.current) };
if *val < self.last {
*val += 1;
for v in self.buf.iter_mut().skip(self.current + 1) {
*v = self.first
}
self.current = buflen - 1;
break;
} else {
match self.current {
0 => return None,
_ => self.current -= 1,
}
}
}
}
self.counter += 1;
Some(&self.buf)
}
}