From 2864398c7b723c1d43166d422ea7028ef33cf9e3 Mon Sep 17 00:00:00 2001 From: Marcos Magueta Date: Sun, 10 May 2026 03:36:59 -0300 Subject: sqlite backend with actual pagination --- src/TupleCodec.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/TupleCodec.cpp (limited to 'src/TupleCodec.cpp') diff --git a/src/TupleCodec.cpp b/src/TupleCodec.cpp new file mode 100644 index 0000000..9b76046 --- /dev/null +++ b/src/TupleCodec.cpp @@ -0,0 +1,72 @@ +#include "TupleCodec.h" + +#include + +#include +#include +#include +#include + +namespace nt::TupleCodec +{ + static std::vector Sorted(std::vector attrs) + { + std::sort(attrs.begin(), attrs.end(), + [](const Attribute& a, const Attribute& b) { return a.name < b.name; }); + return attrs; + } + + std::string Hash(const std::vector& attrs) + { + auto bytes = Serialize(attrs); + return picosha2::hash256_hex_string(bytes.begin(), bytes.end()); + } + + std::vector Serialize(const std::vector& attrs) + { + // Format: [uint32_le name_len][name][uint32_le value_len][value] ... + // Attributes are stored in sorted name order for determinism. + std::vector out; + auto write_u32 = [&](uint32_t n) { + out.push_back(static_cast(n)); + out.push_back(static_cast(n >> 8)); + out.push_back(static_cast(n >> 16)); + out.push_back(static_cast(n >> 24)); + }; + + for (const auto& a : Sorted({ attrs.begin(), attrs.end() })) + { + write_u32(static_cast(a.name.size())); + out.insert(out.end(), a.name.begin(), a.name.end()); + write_u32(static_cast(a.value.size())); + out.insert(out.end(), a.value.begin(), a.value.end()); + } + return out; + } + + std::vector Deserialize(const std::vector& bytes) + { + auto read_u32 = [&](size_t pos) -> uint32_t { + return static_cast(bytes[pos]) + | (static_cast(bytes[pos + 1]) << 8) + | (static_cast(bytes[pos + 2]) << 16) + | (static_cast(bytes[pos + 3]) << 24); + }; + + std::vector result; + size_t pos = 0; + while (pos + 8 <= bytes.size()) + { + uint32_t name_len = read_u32(pos); pos += 4; + std::string name(reinterpret_cast(bytes.data() + pos), name_len); + pos += name_len; + + uint32_t value_len = read_u32(pos); pos += 4; + std::string value(reinterpret_cast(bytes.data() + pos), value_len); + pos += value_len; + + result.push_back({ std::move(name), std::move(value) }); + } + return result; + } +} -- cgit v1.2.3