#ifndef GEOPRO_RENDER_SOURCE_BRICKPAGER_HPP #define GEOPRO_RENDER_SOURCE_BRICKPAGER_HPP #include #include #include #include #include namespace geopro::data { class ChunkedVolumeStore; } namespace geopro::render { // 缓存键:完整 brick 标识(含 level)。 struct BrickId { int level = 0, bx = 0, by = 0, bz = 0; bool operator==(const BrickId& o) const noexcept { return level == o.level && bx == o.bx && by == o.by && bz == o.bz; } }; // 内存恒定的 brick LRU 缓存:任意时刻驻留 ≤ budgetBricks 个解压块, // 与体总大小无关。这是 C 方案核外渲染的内存控制核心。 class BrickPager { public: BrickPager(const geopro::data::ChunkedVolumeStore& store, std::size_t budgetBricks); // 载入 visible 中缺失的块(经 store.readBrick 解压),按请求顺序更新 LRU; // 之后淘汰最久未用的,直到 residentCount() <= budget。 // 若 visible.size() > budget,保留最近请求(visible 末尾)的 budget 个。 void requestVisible(const std::vector& visible); // 命中返回该块解压数据指针(数据由 pager 持有,下次淘汰前有效);未驻留返回 // nullptr。get 不改动 LRU(保持 const 语义),驻留集仅由 requestVisible 决定。 const std::vector* get(const BrickId& id) const; std::size_t residentCount() const { return cache_.size(); } std::size_t budget() const { return budget_; } private: struct Entry { std::vector data; std::list::iterator lruIt; // 指向 lru_ 中本块位置 }; struct BrickIdHash { std::size_t operator()(const BrickId& id) const noexcept; }; // 把 id 移到 MRU 端(lru_ 头部)。 void touch(const BrickId& id); // 从 LRU 端淘汰直到 residentCount() <= budget_。 void evictToBudget(); const geopro::data::ChunkedVolumeStore& store_; std::size_t budget_; std::list lru_; // front = 最近使用(MRU),back = 最久未用(LRU) std::unordered_map cache_; }; } // namespace geopro::render #endif // GEOPRO_RENDER_SOURCE_BRICKPAGER_HPP