#pragma once #include #include #include #include #include #include #include namespace pdfengine { struct CacheKey { std::string documentId; int pageIndex = 0; size_t contentRevision = 1; size_t layoutRevision = 1; bool operator==(const CacheKey& other) const noexcept { return documentId == other.documentId && pageIndex == other.pageIndex && contentRevision == other.contentRevision && layoutRevision == other.layoutRevision; } }; struct CacheKeyHash { size_t operator()(const CacheKey& k) const noexcept { size_t h1 = std::hash{}(k.documentId); size_t h2 = std::hash{}(k.pageIndex); size_t h3 = std::hash{}(k.contentRevision); size_t h4 = std::hash{}(k.layoutRevision); return h1 ^ (h2 << 1) ^ (h3 << 2) ^ (h4 << 3); } }; class MultiLevelCache { public: static MultiLevelCache& instance(); void putLayoutTree(const CacheKey& key, std::shared_ptr tree); [[nodiscard]] std::shared_ptr getLayoutTree(const CacheKey& key) const; void putSpatialIndex(const CacheKey& key, std::shared_ptr index); [[nodiscard]] std::shared_ptr getSpatialIndex(const CacheKey& key) const; void invalidatePage(const std::string& documentId, int pageIndex); void invalidateDocument(const std::string& documentId); void clear(); [[nodiscard]] size_t size() const; private: MultiLevelCache() = default; mutable std::mutex m_mutex; std::unordered_map, CacheKeyHash> m_layoutCache; std::unordered_map, CacheKeyHash> m_spatialCache; }; } // namespace pdfengine