pub const LN_OVERHEAD: usize = 50;
pub const SEC_SLOT_OVERHEAD: usize = 12;
pub const PRI_SLOT_OVERHEAD: usize = 14;
pub const PRI_EMBEDDED_LN_SLOT_OVERHEAD: usize = 20;
pub fn estimate_primary_record_size(
key_size: usize,
data_size: usize,
embedded: bool,
) -> usize {
if embedded {
PRI_EMBEDDED_LN_SLOT_OVERHEAD + key_size + data_size
} else {
LN_OVERHEAD + key_size + data_size + PRI_SLOT_OVERHEAD
}
}
pub fn estimate_secondary_record_size(key_size: usize) -> usize {
SEC_SLOT_OVERHEAD + key_size
}
pub fn estimate_total_size<I>(record_sizes: I) -> usize
where
I: IntoIterator<Item = usize>,
{
record_sizes.into_iter().sum()
}
pub fn should_embed_ln(data_size: usize) -> bool {
data_size <= 16
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_constants() {
assert_eq!(LN_OVERHEAD, 50);
assert_eq!(SEC_SLOT_OVERHEAD, 12);
assert_eq!(PRI_SLOT_OVERHEAD, 14);
assert_eq!(PRI_EMBEDDED_LN_SLOT_OVERHEAD, 20);
}
#[test]
fn test_estimate_primary_record_size_embedded() {
let key_size = 10;
let data_size = 5;
let size = estimate_primary_record_size(key_size, data_size, true);
assert_eq!(size, PRI_EMBEDDED_LN_SLOT_OVERHEAD + key_size + data_size);
assert_eq!(size, 35);
}
#[test]
fn test_estimate_primary_record_size_not_embedded() {
let key_size = 10;
let data_size = 100;
let size = estimate_primary_record_size(key_size, data_size, false);
assert_eq!(
size,
LN_OVERHEAD + key_size + data_size + PRI_SLOT_OVERHEAD
);
assert_eq!(size, 174);
}
#[test]
fn test_estimate_secondary_record_size() {
let key_size = 20;
let size = estimate_secondary_record_size(key_size);
assert_eq!(size, SEC_SLOT_OVERHEAD + key_size);
assert_eq!(size, 32);
}
#[test]
fn test_estimate_total_size() {
let sizes = vec![100, 200, 300];
let total = estimate_total_size(sizes);
assert_eq!(total, 600);
}
#[test]
fn test_estimate_total_size_empty() {
let sizes: Vec<usize> = vec![];
let total = estimate_total_size(sizes);
assert_eq!(total, 0);
}
#[test]
fn test_should_embed_ln_small() {
assert!(should_embed_ln(0));
assert!(should_embed_ln(1));
assert!(should_embed_ln(10));
assert!(should_embed_ln(16));
}
#[test]
fn test_should_embed_ln_large() {
assert!(!should_embed_ln(17));
assert!(!should_embed_ln(100));
assert!(!should_embed_ln(1000));
}
#[test]
fn test_should_embed_ln_boundary() {
assert!(should_embed_ln(16));
assert!(!should_embed_ln(17));
}
#[test]
fn test_primary_record_size_zero_sizes() {
let size_embedded = estimate_primary_record_size(0, 0, true);
let size_not_embedded = estimate_primary_record_size(0, 0, false);
assert_eq!(size_embedded, PRI_EMBEDDED_LN_SLOT_OVERHEAD);
assert_eq!(size_not_embedded, LN_OVERHEAD + PRI_SLOT_OVERHEAD);
}
#[test]
fn test_secondary_record_size_zero() {
let size = estimate_secondary_record_size(0);
assert_eq!(size, SEC_SLOT_OVERHEAD);
}
#[test]
fn test_estimate_total_size_iterator() {
let sizes = (1..=5).map(|i| i * 10);
let total = estimate_total_size(sizes);
assert_eq!(total, 150);
}
}