62 using Hash32 = std::array<uint8_t, 32>;
71 template <
typename Key>
class Merkle {
73 static constexpr size_t B = 64;
86 const Key& key,
const Hash32& payload);
118 size_t offset,
size_t limit);
127 std::vector<LeafEntry> entries;
136 struct InternalNode {
137 std::vector<ChildEntry> entries;
141 static std::vector<uint8_t> encode_leaf(
const LeafNode& n);
142 static std::vector<uint8_t> encode_internal(
const InternalNode& n);
143 static LeafNode decode_leaf(
const std::vector<uint8_t>& bytes);
144 static InternalNode decode_internal(
const std::vector<uint8_t>& bytes);
145 static bool is_leaf_bytes(
const std::vector<uint8_t>& bytes);
148 static std::vector<uint8_t> load_node(IStorageBackend& store,
const std::string& hash_hex);
149 static std::string store_leaf(IStorageBackend& store,
const LeafNode& n);
150 static std::string store_internal(IStorageBackend& store,
const InternalNode& n);
153 static Key subtree_min_key(IStorageBackend& store,
const std::string& node_hex);
156 static size_t route(
const InternalNode& node,
const Key& target);
158 struct InsertResult {
159 std::string new_hash;
160 uint64_t leaf_count = 0;
161 bool did_split =
false;
162 uint64_t split_leaf_count = 0;
164 std::string split_hash;
167 static InsertResult insert_into(IStorageBackend& store,
const std::string& node_hex,
168 const Key& key,
const Hash32& payload);
170 struct RemoveResult {
171 std::string new_hash;
172 uint64_t leaf_count = 0;
175 static RemoveResult remove_from(IStorageBackend& store,
const std::string& node_hex,
178 static void page_from(IStorageBackend& store,
const std::string& node_hex,
size_t& offset,
179 size_t limit, std::vector<Entry>& out);
181 static std::optional<Hash32> get_from(IStorageBackend& store,
const std::string& node_hex,
Abstract KV storage backend consumed by CursorManager and Merkle.
Contract between CursorManager / Merkle and a physical storage engine.
Definition IStorageBackend.h:31
static std::optional< Hash32 > Get(IStorageBackend &store, const std::string &root_hex, const Key &key)
Look up the payload for a key.
Definition Merkle.cpp:472
static std::string Remove(IStorageBackend &store, const std::string &root_hex, const Key &key)
Remove a key from the tree.
Definition Merkle.cpp:409
static std::string Insert(IStorageBackend &store, const std::string &root_hex, const Key &key, const Hash32 &payload)
Insert or overwrite a (key, payload) mapping.
Definition Merkle.cpp:253
static std::vector< Entry > Page(IStorageBackend &store, const std::string &root_hex, size_t offset, size_t limit)
Page through entries in key-sorted order.
Definition Merkle.cpp:499
Contains the Relational NT runtime managers and API facade.
Hash32 hex_to_bin(const std::string &hex)
Decode a 64-character lowercase-hex SHA256 string into raw bytes.
Definition Merkle.cpp:48
std::array< uint8_t, 32 > Hash32
32-byte hash, the universal payload type for all merkle levels.
Definition Merkle.h:62
std::string bin_to_hex(const Hash32 &bin)
Encode raw 32 bytes back into a 64-character lowercase-hex string.
Definition Merkle.cpp:68
One (key, payload) pair returned by Page().
Definition Merkle.h:104