#pragma once #include #include #include #include #include #include #include class ILeafSet { public: using Ptr = std::shared_ptr; virtual ~ILeafSet() = default; virtual uint8_t GetByte(const uint64_t byteIdx) const = 0; virtual void SetByte(const uint64_t byteIdx, const uint8_t value) = 0; void Add(const mmr::LeafIndex& idx); void Remove(const mmr::LeafIndex& idx); bool Contains(const mmr::LeafIndex& idx) const noexcept; mw::Hash Root() const; void Rewind(const uint64_t numLeaves, const std::vector& leavesToAdd); const mmr::LeafIndex& GetNextLeafIdx() const noexcept { return m_nextLeafIdx; } uint64_t GetNumNodes() const noexcept { return GetNextLeafIdx().GetPosition(); } BitSet ToBitSet() const; virtual void ApplyUpdates( const uint32_t file_index, const mmr::LeafIndex& nextLeafIdx, const std::unordered_map& modifiedBytes ) = 0; protected: uint8_t BitToByte(const uint8_t bit) const; ILeafSet(const mmr::LeafIndex& nextLeafIdx) : m_nextLeafIdx(nextLeafIdx) { } mmr::LeafIndex m_nextLeafIdx; }; class LeafSet : public ILeafSet { public: using Ptr = std::shared_ptr; static LeafSet::Ptr Open(const FilePath& leafset_dir, const uint32_t file_index); static FilePath GetPath(const FilePath& leafset_dir, const uint32_t file_index); uint8_t GetByte(const uint64_t byteIdx) const final; void SetByte(const uint64_t byteIdx, const uint8_t value) final; void ApplyUpdates( const uint32_t file_index, const mmr::LeafIndex& nextLeafIdx, const std::unordered_map& modifiedBytes ) final; void Flush(const uint32_t file_index); void Cleanup(const uint32_t current_file_index) const; private: LeafSet(FilePath dir, MemMap&& mmap, const mmr::LeafIndex& nextLeafIdx) : ILeafSet(nextLeafIdx), m_dir(std::move(dir)), m_mmap(std::move(mmap)) {} FilePath m_dir; MemMap m_mmap; std::unordered_map m_modifiedBytes; }; class LeafSetCache : public ILeafSet { public: using Ptr = std::shared_ptr; using UPtr = std::unique_ptr; LeafSetCache(const ILeafSet::Ptr& pBacked) : ILeafSet(pBacked->GetNextLeafIdx()), m_pBacked(pBacked) { } uint8_t GetByte(const uint64_t byteIdx) const final; void SetByte(const uint64_t byteIdx, const uint8_t value) final; void ApplyUpdates( const uint32_t file_index, const mmr::LeafIndex& nextLeafIdx, const std::unordered_map& modifiedBytes ) final; void Flush(const uint32_t file_index); private: ILeafSet::Ptr m_pBacked; std::unordered_map m_modifiedBytes; };