pub const HEADER_SIZE: u32 = 4096;
pub const BLOCK_SIZE: u32 = 256 * 1024;
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BlockId(pub u64);
impl BlockId {
pub const fn new(id: u64) -> Self {
Self(id)
}
pub const fn as_u64(self) -> u64 {
self.0
}
pub const fn byte_offset(self) -> u64 {
HEADER_SIZE as u64 + self.0 * BLOCK_SIZE as u64
}
}
impl std::fmt::Display for BlockId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "block:{}", self.0)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Extent {
pub start: BlockId,
pub count: u32,
}
impl Extent {
pub const fn new(start: BlockId, count: u32) -> Self {
Self { start, count }
}
pub const fn end(&self) -> BlockId {
BlockId(self.start.0 + self.count as u64)
}
pub const fn byte_len(&self) -> u64 {
self.count as u64 * BLOCK_SIZE as u64
}
pub const fn is_adjacent_to(&self, other: &Extent) -> bool {
self.end().0 == other.start.0
}
}
impl std::fmt::Display for Extent {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"blocks:[{}..{})",
self.start.0,
self.start.0 + self.count as u64
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn block_id_byte_offset() {
assert_eq!(BlockId(0).byte_offset(), 4096);
assert_eq!(BlockId(1).byte_offset(), 4096 + 256 * 1024);
assert_eq!(BlockId(4).byte_offset(), 4096 + 4 * 256 * 1024);
}
#[test]
fn block_id_display() {
assert_eq!(format!("{}", BlockId(42)), "block:42");
}
#[test]
fn extent_end() {
let ext = Extent::new(BlockId(10), 5);
assert_eq!(ext.end(), BlockId(15));
}
#[test]
fn extent_byte_len() {
let ext = Extent::new(BlockId(0), 4);
assert_eq!(ext.byte_len(), 4 * 256 * 1024);
}
#[test]
fn extent_adjacency() {
let a = Extent::new(BlockId(10), 5);
let b = Extent::new(BlockId(15), 3);
let c = Extent::new(BlockId(20), 2);
assert!(a.is_adjacent_to(&b));
assert!(!a.is_adjacent_to(&c));
assert!(b.is_adjacent_to(&Extent::new(BlockId(18), 2)));
assert!(!b.is_adjacent_to(&c));
}
#[test]
fn extent_display() {
let ext = Extent::new(BlockId(3), 7);
assert_eq!(format!("{ext}"), "blocks:[3..10)");
}
#[test]
fn block_size_is_256kb() {
assert_eq!(BLOCK_SIZE, 262_144);
}
#[test]
fn header_size_is_4kb() {
assert_eq!(HEADER_SIZE, 4096);
}
}