#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Layout {
pub shards: u64,
pub rows_per_shard: u64,
pub width: u64,
pub row_bytes: u64, pub badge_rows: u64, }
impl Layout {
pub fn new(shards: u64, rows_per_shard: u64, width: u64, elem_bytes: u64) -> Self {
let row_bytes = width * elem_bytes;
let badge_rows = aligned_badge_rows(row_bytes, 4096);
Self {
shards,
rows_per_shard,
width,
row_bytes,
badge_rows,
}
}
pub fn total_rows(&self) -> u64 {
self.shards * self.rows_per_shard
}
pub fn badge_bytes(&self) -> u64 {
self.badge_rows * self.row_bytes
}
pub fn locate(&self, rowid: u64) -> (u64, u64, u64) {
let shard = rowid / self.rows_per_shard;
let in_shard = rowid % self.rows_per_shard;
let badge = in_shard / self.badge_rows;
let in_badge = in_shard % self.badge_rows;
(shard, badge, in_badge)
}
pub fn byte_offset(&self, rowid: u64) -> u64 {
rowid * self.row_bytes
}
}
pub fn aligned_badge_rows(row_bytes: u64, min_bytes: u64) -> u64 {
(min_bytes / row_bytes.max(1)).max(1)
}
#[derive(Debug, Clone, Copy)]
pub struct RowExtent {
pub rows: u64,
pub row_bytes: u64,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn locate_matches_struct() {
let l = Layout::new(8, 156_251, 160, 1);
assert_eq!(l.total_rows(), 8 * 156_251);
assert_eq!(l.row_bytes, 160);
assert_eq!(l.badge_rows, 25);
assert_eq!(l.badge_bytes(), 25 * 160);
let (s, b, r) = l.locate(156_253);
assert_eq!((s, b, r), (1, 0, 2));
}
#[test]
fn row_bytes_bf16() {
let l = Layout::new(8, 156_251, 160, 2);
assert_eq!(l.row_bytes, 320);
assert_eq!(l.badge_rows, 12);
}
}