use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RecordId {
pub partition_id: u32,
pub sequence: u64,
}
impl RecordId {
#[inline]
pub fn new(partition_id: u32, sequence: u64) -> Self {
Self {
partition_id,
sequence,
}
}
pub const ZERO: Self = Self {
partition_id: 0,
sequence: 0,
};
}
impl fmt::Display for RecordId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.partition_id == 0 {
write!(f, "{}", self.sequence)
} else {
write!(f, "{}/{}", self.partition_id, self.sequence)
}
}
}
impl From<RecordId> for u64 {
#[inline]
fn from(id: RecordId) -> u64 {
id.sequence
}
}
impl From<u64> for RecordId {
#[inline]
fn from(sequence: u64) -> Self {
Self {
partition_id: 0,
sequence,
}
}
}
#[derive(Debug)]
pub struct ReadView<'a> {
pub record_id: u64,
pub timestamp_ns: u64,
pub content: &'a [u8],
pub hash_n: &'a [u8; 32],
}
#[derive(Debug, Clone)]
pub struct Record {
pub id: RecordId,
pub timestamp_ns: u64,
pub content: Vec<u8>,
pub hash_n: [u8; 32],
}
impl Record {
pub fn new(id: RecordId, timestamp_ns: u64, content: Vec<u8>, hash_n: [u8; 32]) -> Self {
Self {
id,
timestamp_ns,
content,
hash_n,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn record_id_display_single_partition() {
let id = RecordId::new(0, 42);
assert_eq!(format!("{}", id), "42");
}
#[test]
fn record_id_display_multi_partition() {
let id = RecordId::new(3, 42);
assert_eq!(format!("{}", id), "3/42");
}
#[test]
fn record_id_into_u64() {
let id = RecordId::new(0, 99);
let seq: u64 = id.into();
assert_eq!(seq, 99);
}
#[test]
fn record_id_from_u64() {
let id: RecordId = 99u64.into();
assert_eq!(id.partition_id, 0);
assert_eq!(id.sequence, 99);
}
#[test]
fn record_id_ordering() {
let a = RecordId::new(0, 10);
let b = RecordId::new(0, 20);
let c = RecordId::new(1, 5);
assert!(a < b);
assert!(a < c);
}
}