use noxu_util::Lsn;
#[derive(Debug, Clone)]
pub struct LnInfo {
pub lsn: Lsn,
pub db_id: i64,
pub key: Vec<u8>,
pub obsolete: bool,
pub log_size: i32,
pub deleted: bool,
pub expiration_time: u64,
}
impl LnInfo {
pub fn new(
lsn: Lsn,
db_id: i64,
key: Vec<u8>,
log_size: i32,
deleted: bool,
expiration_time: u64,
) -> Self {
Self {
lsn,
db_id,
key,
obsolete: false,
log_size,
deleted,
expiration_time,
}
}
pub fn lsn(&self) -> Lsn {
self.lsn
}
pub fn db_id(&self) -> i64 {
self.db_id
}
pub fn key(&self) -> &[u8] {
&self.key
}
pub fn log_size(&self) -> i32 {
self.log_size
}
pub fn is_deleted(&self) -> bool {
self.deleted
}
pub fn is_obsolete(&self) -> bool {
self.obsolete
}
pub fn set_obsolete(&mut self, obsolete: bool) {
self.obsolete = obsolete;
}
pub fn expiration_time(&self) -> u64 {
self.expiration_time
}
pub fn is_expired(&self, current_time: u64) -> bool {
self.expiration_time > 0 && self.expiration_time <= current_time
}
pub fn memory_size(&self) -> usize {
let base = 54;
let key_size = self.key.len();
base + key_size
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_ln_info() {
let lsn = Lsn::new(1, 1000);
let key = vec![1, 2, 3, 4];
let info = LnInfo::new(lsn, 42, key, 128, false, 0);
assert_eq!(info.lsn(), lsn);
assert_eq!(info.db_id(), 42);
assert_eq!(info.key(), &[1, 2, 3, 4]);
assert_eq!(info.log_size(), 128);
assert!(!info.is_deleted());
assert!(!info.is_obsolete());
assert_eq!(info.expiration_time(), 0);
}
#[test]
fn test_deleted_ln() {
let lsn = Lsn::new(1, 1000);
let info = LnInfo::new(lsn, 42, vec![1, 2, 3], 64, true, 0);
assert!(info.is_deleted());
assert!(!info.is_obsolete());
}
#[test]
fn test_mark_obsolete() {
let lsn = Lsn::new(1, 1000);
let mut info = LnInfo::new(lsn, 42, vec![1, 2, 3], 64, false, 0);
assert!(!info.is_obsolete());
info.set_obsolete(true);
assert!(info.is_obsolete());
info.set_obsolete(false);
assert!(!info.is_obsolete());
}
#[test]
fn test_expiration() {
let lsn = Lsn::new(1, 1000);
let expiration_time = 1000000;
let info =
LnInfo::new(lsn, 42, vec![1, 2, 3], 64, false, expiration_time);
assert_eq!(info.expiration_time(), expiration_time);
assert!(!info.is_expired(500000)); assert!(info.is_expired(1000000)); assert!(info.is_expired(1500000)); }
#[test]
fn test_no_expiration() {
let lsn = Lsn::new(1, 1000);
let info = LnInfo::new(lsn, 42, vec![1, 2, 3], 64, false, 0);
assert!(!info.is_expired(1000000)); }
#[test]
fn test_memory_size() {
let lsn = Lsn::new(1, 1000);
let small_key = vec![1, 2, 3];
let large_key = vec![0u8; 1000];
let info_small = LnInfo::new(lsn, 42, small_key.clone(), 64, false, 0);
let info_large = LnInfo::new(lsn, 42, large_key.clone(), 64, false, 0);
let size_small = info_small.memory_size();
let size_large = info_large.memory_size();
assert!(size_large > size_small);
assert_eq!(size_large - size_small, large_key.len() - small_key.len());
}
#[test]
fn test_clone() {
let lsn = Lsn::new(1, 1000);
let info = LnInfo::new(lsn, 42, vec![1, 2, 3, 4], 128, false, 5000);
let cloned = info.clone();
assert_eq!(cloned.lsn(), info.lsn());
assert_eq!(cloned.db_id(), info.db_id());
assert_eq!(cloned.key(), info.key());
assert_eq!(cloned.log_size(), info.log_size());
assert_eq!(cloned.is_deleted(), info.is_deleted());
assert_eq!(cloned.expiration_time(), info.expiration_time());
}
#[test]
fn test_large_database_id() {
let lsn = Lsn::new(1, 1000);
let info = LnInfo::new(lsn, i64::MAX, vec![1, 2, 3], 64, false, 0);
assert_eq!(info.db_id(), i64::MAX);
}
#[test]
fn test_empty_key() {
let lsn = Lsn::new(1, 1000);
let info = LnInfo::new(lsn, 42, vec![], 64, false, 0);
assert_eq!(info.key(), &[]);
assert!(info.memory_size() > 0); }
#[test]
fn test_accessors() {
let lsn = Lsn::new(5, 12345);
let key = vec![10, 20, 30];
let info = LnInfo::new(lsn, 99, key, 256, true, 88888);
assert_eq!(info.lsn(), Lsn::new(5, 12345));
assert_eq!(info.db_id(), 99);
assert_eq!(info.key(), &[10, 20, 30]);
assert_eq!(info.log_size(), 256);
assert!(info.is_deleted());
assert_eq!(info.expiration_time(), 88888);
}
}