Skip to main content

engramdb_io/
tiers.rs

1//! 分层管理(M1 简单版):频率驱动热集 + 预算;T1=RAM 显式驻留,T2=OS 页缓存,T3=显式 IO。
2//!
3//! M1 引入 TierManager 的决策面:给定 count 索引与 ram budget,
4//! 输出"热集行集合"(T1)与"需要显式预取的分片-块"(T3 提示)。
5//! M1.5 后接 io_uring 后端与共享内存缓存池(服务化)。
6
7use std::collections::BinaryHeap;
8use std::path::Path;
9
10/// 热集:count 排序的 top-N 行(T1 驻留候选)。
11#[derive(Debug, Default)]
12pub struct TierManager {
13    pub hot_rows: Vec<u64>,
14    pub ram_budget_bytes: u64,
15}
16
17impl TierManager {
18    /// 从 count 索引构建热集(仅取 top `$budget/row_bytes` 行)。
19    /// 输入语义:`row_costs` = (rowid, count)。为保持 M1 小而正确,
20    /// 这里接 "count-dump" 文件:行 {rowid} {count}(步进)。
21    pub fn from_counts_dump(
22        path: &Path,
23        budget_bytes: u64,
24        row_bytes: u64,
25    ) -> std::io::Result<Self> {
26        let text = std::fs::read_to_string(path)?;
27        let mut heap: BinaryHeap<(u64, u64)> = BinaryHeap::new();
28        for line in text.lines() {
29            let mut it = line.split_whitespace();
30            let (rowid, count) = match (it.next(), it.next()) {
31                (Some(a), Some(b)) => (a.parse().unwrap_or(0), b.parse().unwrap_or(0)),
32                _ => (0, 0),
33            };
34            if rowid == 0 {
35                continue;
36            }
37            heap.push((count, rowid));
38        }
39        let max_rows = (budget_bytes / row_bytes.max(1)) as usize;
40        let mut hot_rows = Vec::with_capacity(max_rows.min(heap.len()));
41        while hot_rows.len() < max_rows {
42            match heap.pop() {
43                Some((_, rowid)) => hot_rows.push(rowid),
44                None => break,
45            }
46        }
47        hot_rows.sort_unstable();
48        Ok(Self {
49            hot_rows,
50            ram_budget_bytes: budget_bytes,
51        })
52    }
53
54    pub fn is_hot(&self, rowid: u64) -> bool {
55        // M1:线性(热集调用点在 gather 之前,后续优化为 bitset)
56        self.hot_rows.binary_search(&rowid).is_ok()
57    }
58}