use core::{fmt, hash::Hash};
use zerocopy::{
FromBytes, Immutable, IntoBytes, KnownLayout,
byteorder::{LE, U16, U32, U64},
};
use crate::snapshot::{
SNAPSHOT_KIND_BCSR_HEAD_OFFSETS_U16, SNAPSHOT_KIND_BCSR_HEAD_OFFSETS_U32,
SNAPSHOT_KIND_BCSR_HEAD_OFFSETS_U64, SNAPSHOT_KIND_BCSR_HEAD_PARTICIPANTS_U16,
SNAPSHOT_KIND_BCSR_HEAD_PARTICIPANTS_U32, SNAPSHOT_KIND_BCSR_HEAD_PARTICIPANTS_U64,
SNAPSHOT_KIND_BCSR_TAIL_OFFSETS_U16, SNAPSHOT_KIND_BCSR_TAIL_OFFSETS_U32,
SNAPSHOT_KIND_BCSR_TAIL_OFFSETS_U64, SNAPSHOT_KIND_BCSR_TAIL_PARTICIPANTS_U16,
SNAPSHOT_KIND_BCSR_TAIL_PARTICIPANTS_U32, SNAPSHOT_KIND_BCSR_TAIL_PARTICIPANTS_U64,
SNAPSHOT_KIND_BCSR_VERTEX_INCOMING_HYPEREDGES_U16,
SNAPSHOT_KIND_BCSR_VERTEX_INCOMING_HYPEREDGES_U32,
SNAPSHOT_KIND_BCSR_VERTEX_INCOMING_HYPEREDGES_U64,
SNAPSHOT_KIND_BCSR_VERTEX_INCOMING_OFFSETS_U16, SNAPSHOT_KIND_BCSR_VERTEX_INCOMING_OFFSETS_U32,
SNAPSHOT_KIND_BCSR_VERTEX_INCOMING_OFFSETS_U64,
SNAPSHOT_KIND_BCSR_VERTEX_OUTGOING_HYPEREDGES_U16,
SNAPSHOT_KIND_BCSR_VERTEX_OUTGOING_HYPEREDGES_U32,
SNAPSHOT_KIND_BCSR_VERTEX_OUTGOING_HYPEREDGES_U64,
SNAPSHOT_KIND_BCSR_VERTEX_OUTGOING_OFFSETS_U16, SNAPSHOT_KIND_BCSR_VERTEX_OUTGOING_OFFSETS_U32,
SNAPSHOT_KIND_BCSR_VERTEX_OUTGOING_OFFSETS_U64,
};
mod sealed {
pub trait BcsrIndex {}
pub trait BcsrSnapshotIndex {}
pub trait BcsrSnapshotWord {}
}
pub trait BcsrIndex:
sealed::BcsrIndex + Copy + Eq + Ord + fmt::Debug + fmt::Display + Hash + Sized
{
const ZERO: Self;
fn to_usize(self) -> Option<usize>;
#[must_use]
fn from_usize(value: usize) -> Option<Self>;
}
macro_rules! impl_bcsr_index {
($index:ty) => {
impl sealed::BcsrIndex for $index {}
impl BcsrIndex for $index {
const ZERO: Self = 0;
fn to_usize(self) -> Option<usize> {
usize::try_from(self).ok()
}
fn from_usize(value: usize) -> Option<Self> {
Self::try_from(value).ok()
}
}
};
}
impl_bcsr_index!(u16);
impl_bcsr_index!(u32);
impl_bcsr_index!(u64);
impl sealed::BcsrIndex for usize {}
impl BcsrIndex for usize {
const ZERO: Self = 0;
fn to_usize(self) -> Option<usize> {
Some(self)
}
fn from_usize(value: usize) -> Option<Self> {
Some(value)
}
}
pub trait BcsrWord: Copy + oxgraph_layout_util::ZerocopyWord {
type Index: BcsrIndex;
fn get(self) -> Self::Index;
}
macro_rules! impl_native_bcsr_word {
($index:ty) => {
impl BcsrWord for $index {
type Index = $index;
fn get(self) -> Self::Index {
self
}
}
};
}
impl_native_bcsr_word!(u16);
impl_native_bcsr_word!(u32);
impl_native_bcsr_word!(u64);
impl_native_bcsr_word!(usize);
pub trait BcsrSnapshotWord:
sealed::BcsrSnapshotWord + BcsrWord + FromBytes + Immutable + IntoBytes + KnownLayout
{
}
macro_rules! impl_little_endian_bcsr_word {
($word:ty, $index:ty) => {
impl BcsrWord for $word {
type Index = $index;
fn get(self) -> Self::Index {
Self::get(self)
}
}
impl sealed::BcsrSnapshotWord for $word {}
impl BcsrSnapshotWord for $word {}
};
}
impl_little_endian_bcsr_word!(U16<LE>, u16);
impl_little_endian_bcsr_word!(U32<LE>, u32);
impl_little_endian_bcsr_word!(U64<LE>, u64);
pub trait BcsrSnapshotIndex: sealed::BcsrSnapshotIndex + BcsrIndex {
type LittleEndianWord: BcsrSnapshotWord<Index = Self>;
const HEAD_OFFSETS_KIND: u32;
const HEAD_PARTICIPANTS_KIND: u32;
const TAIL_OFFSETS_KIND: u32;
const TAIL_PARTICIPANTS_KIND: u32;
const VERTEX_OUTGOING_OFFSETS_KIND: u32;
const VERTEX_OUTGOING_HYPEREDGES_KIND: u32;
const VERTEX_INCOMING_OFFSETS_KIND: u32;
const VERTEX_INCOMING_HYPEREDGES_KIND: u32;
fn to_le_word(self) -> Self::LittleEndianWord;
}
macro_rules! impl_bcsr_snapshot_index {
(
$index:ty,
$word:ty,
$head_offsets:expr,
$head_participants:expr,
$tail_offsets:expr,
$tail_participants:expr,
$vertex_outgoing_offsets:expr,
$vertex_outgoing_hyperedges:expr,
$vertex_incoming_offsets:expr,
$vertex_incoming_hyperedges:expr
) => {
impl sealed::BcsrSnapshotIndex for $index {}
impl BcsrSnapshotIndex for $index {
type LittleEndianWord = $word;
const HEAD_OFFSETS_KIND: u32 = $head_offsets;
const HEAD_PARTICIPANTS_KIND: u32 = $head_participants;
const TAIL_OFFSETS_KIND: u32 = $tail_offsets;
const TAIL_PARTICIPANTS_KIND: u32 = $tail_participants;
const VERTEX_OUTGOING_OFFSETS_KIND: u32 = $vertex_outgoing_offsets;
const VERTEX_OUTGOING_HYPEREDGES_KIND: u32 = $vertex_outgoing_hyperedges;
const VERTEX_INCOMING_OFFSETS_KIND: u32 = $vertex_incoming_offsets;
const VERTEX_INCOMING_HYPEREDGES_KIND: u32 = $vertex_incoming_hyperedges;
fn to_le_word(self) -> Self::LittleEndianWord {
<$word>::new(self)
}
}
};
}
impl_bcsr_snapshot_index!(
u16,
U16<LE>,
SNAPSHOT_KIND_BCSR_HEAD_OFFSETS_U16,
SNAPSHOT_KIND_BCSR_HEAD_PARTICIPANTS_U16,
SNAPSHOT_KIND_BCSR_TAIL_OFFSETS_U16,
SNAPSHOT_KIND_BCSR_TAIL_PARTICIPANTS_U16,
SNAPSHOT_KIND_BCSR_VERTEX_OUTGOING_OFFSETS_U16,
SNAPSHOT_KIND_BCSR_VERTEX_OUTGOING_HYPEREDGES_U16,
SNAPSHOT_KIND_BCSR_VERTEX_INCOMING_OFFSETS_U16,
SNAPSHOT_KIND_BCSR_VERTEX_INCOMING_HYPEREDGES_U16
);
impl_bcsr_snapshot_index!(
u32,
U32<LE>,
SNAPSHOT_KIND_BCSR_HEAD_OFFSETS_U32,
SNAPSHOT_KIND_BCSR_HEAD_PARTICIPANTS_U32,
SNAPSHOT_KIND_BCSR_TAIL_OFFSETS_U32,
SNAPSHOT_KIND_BCSR_TAIL_PARTICIPANTS_U32,
SNAPSHOT_KIND_BCSR_VERTEX_OUTGOING_OFFSETS_U32,
SNAPSHOT_KIND_BCSR_VERTEX_OUTGOING_HYPEREDGES_U32,
SNAPSHOT_KIND_BCSR_VERTEX_INCOMING_OFFSETS_U32,
SNAPSHOT_KIND_BCSR_VERTEX_INCOMING_HYPEREDGES_U32
);
impl_bcsr_snapshot_index!(
u64,
U64<LE>,
SNAPSHOT_KIND_BCSR_HEAD_OFFSETS_U64,
SNAPSHOT_KIND_BCSR_HEAD_PARTICIPANTS_U64,
SNAPSHOT_KIND_BCSR_TAIL_OFFSETS_U64,
SNAPSHOT_KIND_BCSR_TAIL_PARTICIPANTS_U64,
SNAPSHOT_KIND_BCSR_VERTEX_OUTGOING_OFFSETS_U64,
SNAPSHOT_KIND_BCSR_VERTEX_OUTGOING_HYPEREDGES_U64,
SNAPSHOT_KIND_BCSR_VERTEX_INCOMING_OFFSETS_U64,
SNAPSHOT_KIND_BCSR_VERTEX_INCOMING_HYPEREDGES_U64
);