use std::io::{Read, Write};
use std::sync::Arc;
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use crate::sstable::table::Table;
use crate::{InternalKeyRange, Result};
#[derive(Clone)]
pub(crate) struct Level {
pub(crate) tables: Vec<Arc<Table>>,
}
impl std::ops::Deref for Level {
type Target = Vec<Arc<Table>>;
fn deref(&self) -> &Self::Target {
&self.tables
}
}
impl Default for Level {
fn default() -> Self {
const DEFAULT_CAPACITY: usize = 10;
Self {
tables: Vec::with_capacity(DEFAULT_CAPACITY),
}
}
}
impl Level {
#[allow(unused)]
pub(crate) fn with_capacity(capacity: usize) -> Self {
Self {
tables: Vec::with_capacity(capacity),
}
}
pub(crate) fn insert(&mut self, table: Arc<Table>) {
let insert_pos = self
.tables
.partition_point(|x| x.meta.properties.seqnos.1 > table.meta.properties.seqnos.1);
self.tables.insert(insert_pos, table);
}
pub(crate) fn insert_sorted_by_key(&mut self, table: Arc<Table>) {
let insert_pos = self.tables.partition_point(|existing| {
match (&existing.meta.smallest_point, &table.meta.smallest_point) {
(Some(existing_smallest), Some(new_smallest)) => {
existing_smallest.user_key < new_smallest.user_key
}
_ => true,
}
});
self.tables.insert(insert_pos, table);
}
pub(crate) fn remove(&mut self, table_id: u64) -> bool {
let len_before = self.tables.len();
self.tables.retain(|table| table.id != table_id);
len_before > self.tables.len()
}
pub(crate) fn overlapping_tables<'a>(
&'a self,
range: &'a InternalKeyRange,
) -> impl Iterator<Item = &'a Arc<Table>> + 'a {
self.tables.iter().filter(move |table| table.overlaps_with_range(range))
}
pub(crate) fn find_first_overlapping_table(&self, range: &InternalKeyRange) -> usize {
self.tables.partition_point(|table| table.is_before_range(range))
}
pub(crate) fn find_last_overlapping_table(&self, range: &InternalKeyRange) -> usize {
self.tables.partition_point(|table| !table.is_after_range(range))
}
}
#[derive(Clone)]
pub(crate) struct Levels(pub(crate) Vec<Arc<Level>>);
impl Levels {
#[allow(unused)]
pub(crate) fn new(level_count: usize, capacity_per_level: usize) -> Self {
Self((0..level_count).map(|_| Arc::new(Level::with_capacity(capacity_per_level))).collect())
}
pub(crate) fn total_tables(&self) -> usize {
self.0.iter().map(|level| level.tables.len()).sum()
}
pub(crate) fn encode<W: Write>(&self, writer: &mut W) -> Result<()> {
writer.write_u8(self.0.len() as u8)?;
for level in &self.0 {
writer.write_u32::<BigEndian>(level.tables.len() as u32)?;
for table in &level.tables {
writer.write_u64::<BigEndian>(table.id)?;
}
}
Ok(())
}
pub(crate) fn decode<R: Read>(reader: &mut R) -> Result<Vec<Vec<u64>>> {
let level_count = reader.read_u8()?;
let mut levels = Vec::with_capacity(level_count as usize);
for _ in 0..level_count {
let table_count = reader.read_u32::<BigEndian>()?;
let mut level = Vec::with_capacity(table_count as usize);
for _ in 0..table_count {
let table_id = reader.read_u64::<BigEndian>()?;
level.push(table_id);
}
levels.push(level);
}
Ok(levels)
}
pub(crate) fn get_levels(&self) -> &Vec<Arc<Level>> {
&self.0
}
pub(crate) fn get_levels_mut(&mut self) -> &mut Vec<Arc<Level>> {
&mut self.0
}
}
impl IntoIterator for Levels {
type IntoIter = std::vec::IntoIter<Arc<Level>>;
type Item = Arc<Level>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<'a> IntoIterator for &'a Levels {
type IntoIter = std::slice::Iter<'a, Arc<Level>>;
type Item = &'a Arc<Level>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
impl AsRef<Vec<Arc<Level>>> for Levels {
fn as_ref(&self) -> &Vec<Arc<Level>> {
&self.0
}
}