use crate::kernel::lsm::iterator::Iter;
use crate::kernel::lsm::mem_table::KeyValue;
use crate::kernel::lsm::table::meta::TableMeta;
use crate::kernel::Result;
use itertools::Itertools;

pub(crate) mod loader;
pub(crate) mod meta;
pub(crate) mod scope;
pub(crate) mod skip_table;
pub(crate) mod ss_table;

#[derive(Copy, Clone, Debug)]
pub enum TableType {
    SortedString,
    #[allow(dead_code)]
    Skip,
}

pub(crate) type BoxTable = Box<dyn Table>;

pub(crate) trait Table: Sync + Send {
    fn query(&self, key: &[u8]) -> Result<Option<KeyValue>>;

    fn len(&self) -> usize;

    fn size_of_disk(&self) -> u64;

    fn gen(&self) -> i64;

    fn level(&self) -> usize;

    fn iter<'a>(&'a self) -> Result<Box<dyn Iter<'a, Item = KeyValue> + 'a + Sync + Send>>;
}

/// 通过一组SSTable收集对应的Gen
pub(crate) fn collect_gen(vec_table: &[&dyn Table]) -> Result<(Vec<i64>, TableMeta)> {
    let meta = TableMeta::from(vec_table);

    Ok((
        vec_table.iter().map(|sst| sst.gen()).unique().collect_vec(),
        meta,
    ))
}
