diff options
| author | Marcos Magueta <maguetamarcos@gmail.com> | 2026-05-10 03:36:59 -0300 |
|---|---|---|
| committer | Marcos Magueta <maguetamarcos@gmail.com> | 2026-05-10 03:36:59 -0300 |
| commit | 2864398c7b723c1d43166d422ea7028ef33cf9e3 (patch) | |
| tree | ec63cd647239612167c36e521610f69023ed9303 /src/TupleCodec.cpp | |
| parent | 7ffd4d99bbb8e358c6694c27c7ff859967872ece (diff) | |
| download | RNT-2864398c7b723c1d43166d422ea7028ef33cf9e3.tar.gz RNT-2864398c7b723c1d43166d422ea7028ef33cf9e3.zip | |
sqlite backend with actual pagination
Diffstat (limited to '')
| -rw-r--r-- | src/TupleCodec.cpp | 72 |
1 files changed, 72 insertions, 0 deletions
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 <picosha2.h> + +#include <algorithm> +#include <cstdint> +#include <cstring> +#include <numeric> + +namespace nt::TupleCodec +{ + static std::vector<Attribute> Sorted(std::vector<Attribute> 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<Attribute>& attrs) + { + auto bytes = Serialize(attrs); + return picosha2::hash256_hex_string(bytes.begin(), bytes.end()); + } + + std::vector<uint8_t> Serialize(const std::vector<Attribute>& attrs) + { + // Format: [uint32_le name_len][name][uint32_le value_len][value] ... + // Attributes are stored in sorted name order for determinism. + std::vector<uint8_t> out; + auto write_u32 = [&](uint32_t n) { + out.push_back(static_cast<uint8_t>(n)); + out.push_back(static_cast<uint8_t>(n >> 8)); + out.push_back(static_cast<uint8_t>(n >> 16)); + out.push_back(static_cast<uint8_t>(n >> 24)); + }; + + for (const auto& a : Sorted({ attrs.begin(), attrs.end() })) + { + write_u32(static_cast<uint32_t>(a.name.size())); + out.insert(out.end(), a.name.begin(), a.name.end()); + write_u32(static_cast<uint32_t>(a.value.size())); + out.insert(out.end(), a.value.begin(), a.value.end()); + } + return out; + } + + std::vector<Attribute> Deserialize(const std::vector<uint8_t>& bytes) + { + auto read_u32 = [&](size_t pos) -> uint32_t { + return static_cast<uint32_t>(bytes[pos]) + | (static_cast<uint32_t>(bytes[pos + 1]) << 8) + | (static_cast<uint32_t>(bytes[pos + 2]) << 16) + | (static_cast<uint32_t>(bytes[pos + 3]) << 24); + }; + + std::vector<Attribute> result; + size_t pos = 0; + while (pos + 8 <= bytes.size()) + { + uint32_t name_len = read_u32(pos); pos += 4; + std::string name(reinterpret_cast<const char*>(bytes.data() + pos), name_len); + pos += name_len; + + uint32_t value_len = read_u32(pos); pos += 4; + std::string value(reinterpret_cast<const char*>(bytes.data() + pos), value_len); + pos += value_len; + + result.push_back({ std::move(name), std::move(value) }); + } + return result; + } +} |
