20#ifndef RIPPLE_NODESTORE_CODEC_H_INCLUDED
21#define RIPPLE_NODESTORE_CODEC_H_INCLUDED
24#define LZ4_DISABLE_DEPRECATE_WARNINGS
26#include <xrpld/nodestore/NodeObject.h>
27#include <xrpld/nodestore/detail/varint.h>
29#include <xrpl/basics/contract.h>
30#include <xrpl/basics/safe_cast.h>
31#include <xrpl/protocol/HashPrefix.h>
33#include <nudb/detail/field.hpp>
44template <
class BufferFactory>
48 if (
static_cast<int>(in_size) < 0)
49 Throw<std::runtime_error>(
"lz4_decompress: integer overflow (input)");
56 if (n == 0 || n >= in_size)
57 Throw<std::runtime_error>(
"lz4_decompress: invalid blob");
59 if (
static_cast<int>(outSize) <= 0)
60 Throw<std::runtime_error>(
"lz4_decompress: integer overflow (output)");
62 void*
const out = bf(outSize);
64 if (LZ4_decompress_safe(
65 reinterpret_cast<char const*
>(
in) + n,
66 reinterpret_cast<char*
>(
out),
67 static_cast<int>(in_size - n),
68 static_cast<int>(outSize)) !=
static_cast<int>(outSize))
69 Throw<std::runtime_error>(
"lz4_decompress: LZ4_decompress_safe");
71 return {
out, outSize};
74template <
class BufferFactory>
79 using namespace nudb::detail;
83 auto const out_max = LZ4_compressBound(in_size);
87 auto const out_size = LZ4_compress_default(
88 reinterpret_cast<char const*
>(
in),
89 reinterpret_cast<char*
>(
out + n),
93 Throw<std::runtime_error>(
"lz4 compress");
94 result.
second = n + out_size;
109template <
class BufferFactory>
113 using namespace nudb::detail;
119 Throw<std::runtime_error>(
"nodeobject decompress");
139 auto const hs = field<std::uint16_t>::size;
140 if (in_size < hs + 32)
141 Throw<std::runtime_error>(
142 "nodeobject codec v1: short inner node size: " +
145 istream is(p, in_size);
147 read<std::uint16_t>(is, mask);
153 write<std::uint32_t>(os, 0);
154 write<std::uint32_t>(os, 0);
156 write<std::uint32_t>(
159 Throw<std::runtime_error>(
160 "nodeobject codec v1: empty inner node");
162 for (
int i = 16; i--; bit >>= 1)
167 Throw<std::runtime_error>(
168 "nodeobject codec v1: short inner node subsize: " +
181 Throw<std::runtime_error>(
182 "nodeobject codec v1: long inner node, in_size = " +
188 if (in_size != 16 * 32)
189 Throw<std::runtime_error>(
190 "nodeobject codec v1: short full inner node, in_size = " +
192 istream is(p, in_size);
197 write<std::uint32_t>(os, 0);
198 write<std::uint32_t>(os, 0);
200 write<std::uint32_t>(
202 write(os, is(512), 512);
206 Throw<std::runtime_error>(
212template <
class =
void>
220template <
class BufferFactory>
225 using namespace nudb::detail;
230 istream is(
in, in_size);
235 read<std::uint32_t>(is, index);
236 read<std::uint32_t>(is, unused);
237 read<std::uint8_t>(is, kind);
238 read<std::uint32_t>(is, prefix);
244 for (
unsigned bit = 0x8000; bit; bit >>= 1)
246 void const*
const h = is(32);
257 auto const type = 2U;
259 result.
second = vs + field<std::uint16_t>::size +
265 write<varint>(os, type);
266 write<std::uint16_t>(os, mask);
271 auto const type = 3U;
273 result.
second = vs + n * 32;
278 write<varint>(os, type);
302 result.
second = vn + lzr.second;
306 Throw<std::logic_error>(
316template <
class =
void>
320 using namespace nudb::detail;
325 istream is(
in, in_size);
330 read<std::uint32_t>(is, index);
331 read<std::uint32_t>(is, unused);
332 read<std::uint8_t>(is, kind);
333 read<std::uint32_t>(is, prefix);
337 write<std::uint32_t>(os, 0);
338 write<std::uint32_t>(os, 0);
std::size_t read_varint(void const *buf, std::size_t buflen, std::size_t &t)
std::size_t size_varint(T v)
void filter_inner(void *in, std::size_t in_size)
std::pair< void const *, std::size_t > lz4_compress(void const *in, std::size_t in_size, BufferFactory &&bf)
void write(nudb::detail::ostream &os, std::size_t t)
std::pair< void const *, std::size_t > nodeobject_decompress(void const *in, std::size_t in_size, BufferFactory &&bf)
std::size_t write_varint(void *p0, std::size_t v)
std::pair< void const *, std::size_t > nodeobject_compress(void const *in, std::size_t in_size, BufferFactory &&bf)
std::pair< void const *, std::size_t > lz4_decompress(void const *in, std::size_t in_size, BufferFactory &&bf)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
@ innerNode
inner node in V1 tree