use anyhow::Result;
use super::ArcMmapHelper;
use core::fmt::Display;
use dsi_bitstream::prelude::*;
use rdst::*;
use std::fs::File;
use std::io::BufWriter;
use std::path::Path;
pub mod gaps;
pub mod grouped_gaps;
pub type DefaultBatchCodec = grouped_gaps::GroupedGapsCodec;
pub type BitWriter<E> = BufBitWriter<E, WordAdapter<usize, BufWriter<File>>>;
pub type BitReader<E> = BufBitReader<E, MemWordReader<u32, ArcMmapHelper<u32>>>;
pub trait BatchCodec: Send + Sync {
type Label: Copy + Send + Sync + 'static;
type DecodedBatch: IntoIterator<Item = ((usize, usize), Self::Label), IntoIter: Send + Sync + Clone>;
type EncodedBatchStats: Display;
fn encode_sorted_batch(
&self,
path: impl AsRef<Path>,
batch: &[((usize, usize), Self::Label)],
) -> Result<(usize, Self::EncodedBatchStats)>;
fn encode_batch(
&self,
path: impl AsRef<Path>,
batch: &mut [((usize, usize), Self::Label)],
) -> Result<(usize, Self::EncodedBatchStats)>;
fn decode_batch(&self, path: impl AsRef<Path>) -> Result<Self::DecodedBatch>;
}
pub type CodecIter<C> = <<C as BatchCodec>::DecodedBatch as IntoIterator>::IntoIter;
#[derive(Clone, Copy, Debug)]
#[repr(transparent)]
pub struct Triple<L>(((usize, usize), L));
impl<L> Triple<L> {
pub fn cast_batch(batch: &[((usize, usize), L)]) -> &[Triple<L>] {
unsafe { std::mem::transmute(batch) }
}
pub fn cast_batch_mut(batch: &mut [((usize, usize), L)]) -> &mut [Triple<L>] {
unsafe { std::mem::transmute(batch) }
}
}
impl<L> RadixKey for Triple<L> {
const LEVELS: usize = 16;
fn get_level(&self, level: usize) -> u8 {
(if level < 8 {
self.0.0.1 >> ((level % 8) * 8)
} else {
self.0.0.0 >> ((level % 8) * 8)
}) as u8
}
}
impl<L> PartialEq for Triple<L> {
fn eq(&self, other: &Self) -> bool {
self.0.0 == other.0.0
}
}
impl<L> Eq for Triple<L> {}
impl<L> PartialOrd for Triple<L> {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl<L> Ord for Triple<L> {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
self.0.0.cmp(&other.0.0)
}
}