28#include <unordered_map>
36std::uint32_t SerializeFieldV1(
41 auto base =
reinterpret_cast<unsigned char *
>(buffer);
43 void** where = (buffer ==
nullptr) ? &buffer :
reinterpret_cast<void**
>(&pos);
45 pos += RNTupleSerializer::SerializeRecordFramePreamble(*where);
49 pos += RNTupleSerializer::SerializeUInt32(physParentId, *where);
50 pos += RNTupleSerializer::SerializeFieldStructure(fieldDesc.
GetStructure(), *where);
52 pos += RNTupleSerializer::SerializeUInt16(RNTupleSerializer::kFlagRepetitiveField, *where);
53 pos += RNTupleSerializer::SerializeUInt64(fieldDesc.
GetNRepetitions(), *where);
55 pos += RNTupleSerializer::SerializeUInt16(0, *where);
57 pos += RNTupleSerializer::SerializeString(fieldDesc.
GetFieldName(), *where);
58 pos += RNTupleSerializer::SerializeString(fieldDesc.
GetTypeName(), *where);
59 pos += RNTupleSerializer::SerializeString(
"" , *where);
62 auto size = pos - base;
63 RNTupleSerializer::SerializeFramePostscript(base,
size);
69std::uint32_t SerializeFieldTree(
74 auto base =
reinterpret_cast<unsigned char *
>(buffer);
76 void** where = (buffer ==
nullptr) ? &buffer :
reinterpret_cast<void**
>(&pos);
78 std::deque<ROOT::Experimental::DescriptorId_t> idQueue{desc.
GetFieldZeroId()};
80 while (!idQueue.empty()) {
81 auto parentId = idQueue.front();
87 pos += SerializeFieldV1(
f, physParentId, *where);
88 idQueue.push_back(
f.GetId());
97 std::uint32_t bufSize,
103 auto base =
reinterpret_cast<const unsigned char *
>(buffer);
105 std::uint32_t frameSize;
106 auto fnFrameSizeLeft = [&]() {
return frameSize -
static_cast<std::uint32_t
>(bytes - base); };
107 auto result = RNTupleSerializer::DeserializeFrameHeader(bytes, bufSize, frameSize);
110 bytes += result.Unwrap();
112 std::uint32_t fieldVersion;
113 std::uint32_t typeVersion;
114 std::uint32_t parentId;
116 ENTupleStructure structure{ENTupleStructure::kLeaf};
118 if (fnFrameSizeLeft() < 3 *
sizeof(std::uint32_t) +
119 RNTupleSerializer::SerializeFieldStructure(structure,
nullptr) +
120 sizeof(std::uint16_t))
122 return R__FAIL(
"field record frame too short");
124 bytes += RNTupleSerializer::DeserializeUInt32(bytes, fieldVersion);
125 bytes += RNTupleSerializer::DeserializeUInt32(bytes, typeVersion);
126 bytes += RNTupleSerializer::DeserializeUInt32(bytes, parentId);
127 auto res16 = RNTupleSerializer::DeserializeFieldStructure(bytes, structure);
130 bytes += res16.Unwrap();
131 bytes += RNTupleSerializer::DeserializeUInt16(bytes, flags);
137 if (flags & RNTupleSerializer::kFlagRepetitiveField) {
138 if (fnFrameSizeLeft() <
sizeof(std::uint64_t))
139 return R__FAIL(
"field record frame too short");
140 std::uint64_t nRepetitions;
141 bytes += RNTupleSerializer::DeserializeUInt64(bytes, nRepetitions);
145 std::string fieldName;
146 std::string typeName;
147 std::string aliasName;
148 std::string description;
149 result = RNTupleSerializer::DeserializeString(bytes, fnFrameSizeLeft(), fieldName).Unwrap();
152 bytes += result.Unwrap();
153 result = RNTupleSerializer::DeserializeString(bytes, fnFrameSizeLeft(), typeName).Unwrap();
156 bytes += result.Unwrap();
157 result = RNTupleSerializer::DeserializeString(bytes, fnFrameSizeLeft(), aliasName).Unwrap();
160 bytes += result.Unwrap();
161 result = RNTupleSerializer::DeserializeString(bytes, fnFrameSizeLeft(), description).Unwrap();
164 bytes += result.Unwrap();
170std::uint32_t SerializeColumnListV1(
178 auto base =
reinterpret_cast<unsigned char *
>(buffer);
180 void** where = (buffer ==
nullptr) ? &buffer :
reinterpret_cast<void**
>(&pos);
182 std::deque<ROOT::Experimental::DescriptorId_t> idQueue{desc.
GetFieldZeroId()};
184 while (!idQueue.empty()) {
185 auto parentId = idQueue.front();
190 pos += RNTupleSerializer::SerializeRecordFramePreamble(*where);
192 auto type =
c.GetModel().GetType();
193 pos += RNTupleSerializer::SerializeColumnType(
type, *where);
194 pos += RNTupleSerializer::SerializeUInt16(RColumnElementBase::GetBitsOnStorage(
type), *where);
195 pos += RNTupleSerializer::SerializeUInt32(context.
GetPhysFieldId(
c.GetFieldId()), *where);
196 std::uint32_t flags = 0;
198 if (
c.GetModel().GetIsSorted())
199 flags |= RNTupleSerializer::kFlagSortAscColumn;
202 flags |= RNTupleSerializer::kFlagNonNegativeColumn;
203 pos += RNTupleSerializer::SerializeUInt32(flags, *where);
205 pos += RNTupleSerializer::SerializeFramePostscript(buffer ? frame :
nullptr, pos - frame);
211 idQueue.push_back(
f.GetId());
219 std::uint32_t bufSize,
225 auto base =
reinterpret_cast<const unsigned char *
>(buffer);
227 std::uint32_t frameSize;
228 auto fnFrameSizeLeft = [&]() {
return frameSize -
static_cast<std::uint32_t
>(bytes - base); };
229 auto result = RNTupleSerializer::DeserializeFrameHeader(bytes, bufSize, frameSize);
232 bytes += result.Unwrap();
236 std::uint16_t bitsOnStorage;
237 std::uint32_t fieldId;
239 if (fnFrameSizeLeft() < RNTupleSerializer::SerializeColumnType(
type,
nullptr) +
240 sizeof(std::uint16_t) + 2 *
sizeof(std::uint32_t))
242 return R__FAIL(
"column record frame too short");
244 auto res16 = RNTupleSerializer::DeserializeColumnType(bytes,
type);
247 bytes += res16.Unwrap();
248 bytes += RNTupleSerializer::DeserializeUInt16(bytes, bitsOnStorage);
249 bytes += RNTupleSerializer::DeserializeUInt32(bytes, fieldId);
250 bytes += RNTupleSerializer::DeserializeUInt32(bytes, flags);
253 return R__FAIL(
"column element size mismatch");
255 const bool isSorted = (flags & (RNTupleSerializer::kFlagSortAscColumn | RNTupleSerializer::kFlagSortDesColumn));
265 const unsigned char *data, std::uint32_t length, std::uint32_t &crc32,
void *buffer)
267 if (buffer !=
nullptr) {
268 crc32 = R__crc32(0,
nullptr, 0);
269 crc32 = R__crc32(crc32, data, length);
276 const unsigned char *data, std::uint32_t length, std::uint32_t &crc32)
278 auto checksumReal = R__crc32(0,
nullptr, 0);
279 checksumReal = R__crc32(checksumReal, data, length);
280 DeserializeUInt32(data + length, crc32);
281 if (crc32 != checksumReal)
282 return R__FAIL(
"CRC32 checksum mismatch");
288 const unsigned char *data, std::uint32_t length)
297 if (buffer !=
nullptr) {
298 auto bytes =
reinterpret_cast<unsigned char *
>(buffer);
299 bytes[0] = (val & 0x00FF);
300 bytes[1] = (val & 0xFF00) >> 8;
307 auto bytes =
reinterpret_cast<const unsigned char *
>(buffer);
308 val = std::int16_t(bytes[0]) + (std::int16_t(bytes[1]) << 8);
314 return SerializeInt16(val, buffer);
319 return DeserializeInt16(buffer, *
reinterpret_cast<std::int16_t *
>(&val));
324 if (buffer !=
nullptr) {
325 auto bytes =
reinterpret_cast<unsigned char *
>(buffer);
326 bytes[0] = (val & 0x000000FF);
327 bytes[1] = (val & 0x0000FF00) >> 8;
328 bytes[2] = (val & 0x00FF0000) >> 16;
329 bytes[3] = (val & 0xFF000000) >> 24;
336 auto bytes =
reinterpret_cast<const unsigned char *
>(buffer);
337 val = std::int32_t(bytes[0]) + (std::int32_t(bytes[1]) << 8) +
338 (std::int32_t(bytes[2]) << 16) + (std::int32_t(bytes[3]) << 24);
344 return SerializeInt32(val, buffer);
349 return DeserializeInt32(buffer, *
reinterpret_cast<std::int32_t *
>(&val));
354 if (buffer !=
nullptr) {
355 auto bytes =
reinterpret_cast<unsigned char *
>(buffer);
356 bytes[0] = (val & 0x00000000000000FF);
357 bytes[1] = (val & 0x000000000000FF00) >> 8;
358 bytes[2] = (val & 0x0000000000FF0000) >> 16;
359 bytes[3] = (val & 0x00000000FF000000) >> 24;
360 bytes[4] = (val & 0x000000FF00000000) >> 32;
361 bytes[5] = (val & 0x0000FF0000000000) >> 40;
362 bytes[6] = (val & 0x00FF000000000000) >> 48;
363 bytes[7] = (val & 0xFF00000000000000) >> 56;
370 auto bytes =
reinterpret_cast<const unsigned char *
>(buffer);
371 val = std::int64_t(bytes[0]) + (std::int64_t(bytes[1]) << 8) +
372 (std::int64_t(bytes[2]) << 16) + (std::int64_t(bytes[3]) << 24) +
373 (std::int64_t(bytes[4]) << 32) + (std::int64_t(bytes[5]) << 40) +
374 (std::int64_t(bytes[6]) << 48) + (std::int64_t(bytes[7]) << 56);
380 return SerializeInt64(val, buffer);
385 return DeserializeInt64(buffer, *
reinterpret_cast<std::int64_t *
>(&val));
391 auto pos =
reinterpret_cast<unsigned char *
>(buffer);
392 pos += SerializeUInt32(val.length(), pos);
393 memcpy(pos, val.data(), val.length());
395 return sizeof(std::uint32_t) + val.length();
399 const void *buffer, std::uint32_t bufSize, std::string &val)
401 if (bufSize <
sizeof(std::uint32_t))
402 return R__FAIL(
"string buffer too short");
403 bufSize -=
sizeof(std::uint32_t);
405 auto base =
reinterpret_cast<const unsigned char *
>(buffer);
407 std::uint32_t length;
408 bytes += DeserializeUInt32(buffer, length);
409 if (bufSize < length)
410 return R__FAIL(
"string buffer too short");
413 memcpy(&val[0], bytes, length);
414 return sizeof(std::uint32_t) + length;
424 return SerializeUInt16(0x02, buffer);
426 return SerializeUInt16(0x03, buffer);
428 return SerializeUInt16(0x04, buffer);
430 return SerializeUInt16(0x05, buffer);
432 return SerializeUInt16(0x06, buffer);
434 return SerializeUInt16(0x07, buffer);
436 return SerializeUInt16(0x08, buffer);
438 return SerializeUInt16(0x09, buffer);
440 return SerializeUInt16(0x0A, buffer);
442 return SerializeUInt16(0x0B, buffer);
444 return SerializeUInt16(0x0C, buffer);
446 return SerializeUInt16(0x0D, buffer);
457 std::uint16_t onDiskType;
458 auto result = DeserializeUInt16(buffer, onDiskType);
459 switch (onDiskType) {
497 return R__FAIL(
"unexpected on-disk column type");
509 return SerializeUInt16(0x00, buffer);
511 return SerializeUInt16(0x01, buffer);
513 return SerializeUInt16(0x02, buffer);
515 return SerializeUInt16(0x03, buffer);
517 return SerializeUInt16(0x04, buffer);
528 std::uint16_t onDiskValue;
529 auto result = DeserializeUInt16(buffer, onDiskValue);
530 switch (onDiskValue) {
547 return R__FAIL(
"unexpected on-disk field structure value");
557 auto base =
reinterpret_cast<unsigned char *
>(buffer);
559 void** where = (buffer ==
nullptr) ? &buffer :
reinterpret_cast<void**
>(&pos);
561 pos += SerializeUInt16(kEnvelopeCurrentVersion, *where);
562 pos += SerializeUInt16(kEnvelopeMinVersion, *where);
568 const unsigned char *envelope, std::uint32_t
size, std::uint32_t &crc32,
void *buffer)
570 return SerializeCRC32(envelope,
size, crc32, buffer);
574 const unsigned char *envelope, std::uint32_t
size,
void *buffer)
577 return SerializeEnvelopePostscript(envelope,
size, crc32, buffer);
583 const void *buffer, std::uint32_t bufSize, std::uint32_t &crc32)
585 if (bufSize < (2 *
sizeof(std::uint16_t) +
sizeof(std::uint32_t)))
586 return R__FAIL(
"invalid envelope, too short");
588 auto bytes =
reinterpret_cast<const unsigned char *
>(buffer);
591 std::uint16_t protocolVersionAtWrite;
592 std::uint16_t protocolVersionMinRequired;
593 bytes += DeserializeUInt16(bytes, protocolVersionAtWrite);
595 if (protocolVersionAtWrite < 1)
596 return R__FAIL(
"The RNTuple format is too old (version 0)");
598 bytes += DeserializeUInt16(bytes, protocolVersionMinRequired);
599 if (protocolVersionMinRequired > kEnvelopeCurrentVersion) {
600 return R__FAIL(std::string(
"The RNTuple format is too new (version ") +
601 std::to_string(protocolVersionMinRequired) +
")");
605 auto result = VerifyCRC32(base, bufSize - 4, crc32);
609 return sizeof(protocolVersionAtWrite) +
sizeof(protocolVersionMinRequired);
614 const void *buffer, std::uint32_t bufSize)
624 return SerializeInt32(1, buffer);
629 std::uint32_t nitems,
void *buffer)
631 if (nitems >= (1 << 28))
634 auto base =
reinterpret_cast<unsigned char *
>(buffer);
636 void** where = (buffer ==
nullptr) ? &buffer :
reinterpret_cast<void**
>(&pos);
640 pos += SerializeUInt32(nitems, *where);
645 void *frame, std::int32_t
size)
649 if (
size <
static_cast<std::int32_t
>(
sizeof(std::int32_t)))
653 DeserializeInt32(frame, marker);
654 if ((marker < 0) && (
size <
static_cast<std::int32_t
>(2 *
sizeof(std::int32_t))))
657 SerializeInt32(marker *
size, frame);
663 const void *buffer, std::uint32_t bufSize, std::uint32_t &frameSize, std::uint32_t &nitems)
665 if (bufSize <
sizeof(std::int32_t))
666 return R__FAIL(
"frame too short");
668 std::int32_t *ssize =
reinterpret_cast<std::int32_t *
>(&frameSize);
669 auto bytes =
reinterpret_cast<const unsigned char *
>(buffer);
670 bytes += DeserializeInt32(bytes, *ssize);
674 if (frameSize <
sizeof(std::int32_t))
675 return R__FAIL(
"corrupt record frame size");
678 if (bufSize < 2 *
sizeof(std::int32_t))
679 return R__FAIL(
"frame too short");
680 bytes += DeserializeUInt32(bytes, nitems);
681 nitems &= (2 << 28) - 1;
683 if (frameSize < 2 *
sizeof(std::int32_t))
684 return R__FAIL(
"corrupt list frame size");
687 if (bufSize < frameSize)
688 return R__FAIL(
"frame too short");
690 return bytes -
reinterpret_cast<const unsigned char *
>(buffer);
694 const void *buffer, std::uint32_t bufSize, std::uint32_t &frameSize)
696 std::uint32_t nitems;
697 return R__FORWARD_RESULT(DeserializeFrameHeader(buffer, bufSize, frameSize, nitems));
701 const std::vector<std::int64_t> &flags,
void *buffer)
704 return SerializeInt64(0, buffer);
707 auto bytes =
reinterpret_cast<unsigned char *
>(buffer);
709 for (
unsigned i = 0; i < flags.size(); ++i) {
714 if (i == (flags.size() - 1))
715 SerializeInt64(flags[i], bytes);
717 bytes += SerializeInt64(flags[i] | 0x8000000000000000, bytes);
720 return (flags.size() *
sizeof(std::int64_t));
724 const void *buffer, std::uint32_t bufSize, std::vector<std::int64_t> &flags)
726 auto bytes =
reinterpret_cast<const unsigned char *
>(buffer);
731 if (bufSize <
sizeof(std::int64_t))
732 return R__FAIL(
"feature flag buffer too short");
733 bytes += DeserializeInt64(bytes,
f);
734 bufSize -=
sizeof(std::int64_t);
735 flags.emplace_back(
f & ~0x8000000000000000);
738 return (flags.size() *
sizeof(std::int64_t));
744 std::uint32_t
size = 0;
745 if (!locator.
fUrl.empty()) {
746 if (locator.
fUrl.length() >= (1 << 24))
748 std::int32_t head = locator.
fUrl.length();
751 size += SerializeInt32(head, buffer);
753 memcpy(
reinterpret_cast<unsigned char *
>(buffer) +
size, locator.
fUrl.data(), locator.
fUrl.length());
761 size += SerializeUInt64(locator.
fPosition, buffer ?
reinterpret_cast<unsigned char *
>(buffer) +
size :
nullptr);
766 const void *buffer, std::uint32_t bufSize,
RNTupleLocator &locator)
768 if (bufSize <
sizeof(std::int32_t))
769 return R__FAIL(
"too short locator");
771 auto bytes =
reinterpret_cast<const unsigned char *
>(buffer);
774 bytes += DeserializeInt32(bytes, head);
775 bufSize -=
sizeof(std::int32_t);
778 int type = head >> 24;
780 return R__FAIL(
"unsupported locator type: " + std::to_string(
type));
781 std::uint32_t locatorSize =
static_cast<std::uint32_t
>(head) & 0x00FFFFFF;
782 if (bufSize < locatorSize)
783 return R__FAIL(
"too short locator");
786 locator.
fUrl.resize(locatorSize);
787 memcpy(&locator.
fUrl[0], bytes, locatorSize);
788 bytes += locatorSize;
790 if (bufSize <
sizeof(std::uint64_t))
791 return R__FAIL(
"too short locator");
792 std::uint64_t offset;
793 bytes += DeserializeUInt64(bytes, offset);
794 locator.
fUrl.clear();
799 return bytes -
reinterpret_cast<const unsigned char *
>(buffer);
807 buffer ?
reinterpret_cast<unsigned char *
>(buffer) +
size :
nullptr);
812 const void *buffer, std::uint32_t bufSize,
REnvelopeLink &envelopeLink)
814 if (bufSize <
sizeof(std::int32_t))
815 return R__FAIL(
"too short envelope link");
817 auto bytes =
reinterpret_cast<const unsigned char *
>(buffer);
818 bytes += DeserializeUInt32(bytes, envelopeLink.
fUnzippedSize);
819 bufSize -=
sizeof(std::uint32_t);
820 auto result = DeserializeLocator(bytes, bufSize, envelopeLink.
fLocator);
823 bytes += result.Unwrap();
824 return bytes -
reinterpret_cast<const unsigned char *
>(buffer);
831 auto base =
reinterpret_cast<unsigned char *
>(buffer);
833 void** where = (buffer ==
nullptr) ? &buffer :
reinterpret_cast<void**
>(&pos);
836 pos += SerializeRecordFramePreamble(*where);
837 pos += SerializeUInt64(clusterSummary.
fFirstEntry, *where);
839 pos += SerializeInt64(-
static_cast<int64_t
>(clusterSummary.
fNEntries), *where);
842 pos += SerializeInt64(
static_cast<int64_t
>(clusterSummary.
fNEntries), *where);
844 auto size = pos - frame;
845 pos += SerializeFramePostscript(frame,
size);
851 const void *buffer, std::uint32_t bufSize,
RClusterSummary &clusterSummary)
853 auto base =
reinterpret_cast<const unsigned char *
>(buffer);
855 std::uint32_t frameSize;
856 auto result = DeserializeFrameHeader(bytes, bufSize, frameSize);
859 bytes += result.Unwrap();
861 auto fnBufSizeLeft = [&]() {
return frameSize -
static_cast<std::uint32_t
>(bytes - base); };
862 if (fnBufSizeLeft() < 2 *
sizeof(std::uint64_t))
863 return R__FAIL(
"too short cluster summary");
865 bytes += DeserializeUInt64(bytes, clusterSummary.
fFirstEntry);
866 std::int64_t nEntries;
867 bytes += DeserializeInt64(bytes, nEntries);
870 if (fnBufSizeLeft() <
sizeof(std::uint32_t))
871 return R__FAIL(
"too short cluster summary");
873 std::uint32_t columnGroupID;
874 bytes += DeserializeUInt32(bytes, columnGroupID);
888 auto base =
reinterpret_cast<unsigned char *
>(buffer);
890 void** where = (buffer ==
nullptr) ? &buffer :
reinterpret_cast<void**
>(&pos);
893 pos += SerializeRecordFramePreamble(*where);
894 pos += SerializeUInt32(clusterGroup.
fNClusters, *where);
896 auto size = pos - frame;
897 pos += SerializeFramePostscript(frame,
size);
903 const void *buffer, std::uint32_t bufSize,
RClusterGroup &clusterGroup)
905 auto base =
reinterpret_cast<const unsigned char *
>(buffer);
908 std::uint32_t frameSize;
909 auto result = DeserializeFrameHeader(bytes, bufSize, frameSize);
912 bytes += result.Unwrap();
914 auto fnFrameSizeLeft = [&]() {
return frameSize -
static_cast<std::uint32_t
>(bytes - base); };
915 if (fnFrameSizeLeft() <
sizeof(std::uint32_t))
916 return R__FAIL(
"too short cluster group");
918 bytes += DeserializeUInt32(bytes, clusterGroup.
fNClusters);
933 auto base =
reinterpret_cast<unsigned char *
>(buffer);
935 void** where = (buffer ==
nullptr) ? &buffer :
reinterpret_cast<void**
>(&pos);
937 pos += SerializeEnvelopePreamble(*where);
939 pos += SerializeFeatureFlags(std::vector<std::int64_t>(), *where);
940 pos += SerializeUInt32(kReleaseCandidateTag, *where);
941 pos += SerializeString(desc.
GetName(), *where);
943 pos += SerializeString(std::string(
"ROOT v") +
ROOT_RELEASE, *where);
947 pos += SerializeListFramePreamble(desc.
GetNFields() - 1, *where);
948 pos += SerializeFieldTree(desc, context, *where);
949 pos += SerializeFramePostscript(buffer ? frame :
nullptr, pos - frame);
952 pos += SerializeListFramePreamble(desc.
GetNColumns(), *where);
953 pos += SerializeColumnListV1(desc, context, *where);
954 pos += SerializeFramePostscript(buffer ? frame :
nullptr, pos - frame);
958 pos += SerializeListFramePreamble(0, *where);
959 pos += SerializeFramePostscript(buffer ? frame :
nullptr, pos - frame);
963 pos += SerializeListFramePreamble(0, *where);
964 pos += SerializeFramePostscript(buffer ? frame :
nullptr, pos - frame);
966 std::uint32_t
size = pos - base;
967 std::uint32_t crc32 = 0;
968 size += SerializeEnvelopePostscript(base,
size, crc32, *where);
978 auto base =
reinterpret_cast<unsigned char *
>(buffer);
980 void** where = (buffer ==
nullptr) ? &buffer :
reinterpret_cast<void**
>(&pos);
982 pos += SerializeEnvelopePreamble(*where);
983 auto topMostFrame = pos;
984 pos += SerializeListFramePreamble(physClusterIDs.size(), *where);
986 for (
auto clusterId : physClusterIDs) {
989 std::set<DescriptorId_t> physColumnIds;
990 for (
auto column : clusterDesc.GetColumnIds())
993 auto outerFrame = pos;
994 pos += SerializeListFramePreamble(physColumnIds.size(), *where);
995 for (
auto physId : physColumnIds) {
997 const auto &columnRange = clusterDesc.GetColumnRange(memId);
998 const auto &pageRange = clusterDesc.GetPageRange(memId);
1000 auto innerFrame = pos;
1001 pos += SerializeListFramePreamble(pageRange.fPageInfos.size(), *where);
1003 for (
const auto &pi : pageRange.fPageInfos) {
1004 pos += SerializeUInt32(pi.fNElements, *where);
1005 pos += SerializeLocator(pi.fLocator, *where);
1007 pos += SerializeUInt64(columnRange.fFirstElementIndex, *where);
1008 pos += SerializeUInt32(columnRange.fCompressionSettings, *where);
1010 pos += SerializeFramePostscript(buffer ? innerFrame :
nullptr, pos - innerFrame);
1012 pos += SerializeFramePostscript(buffer ? outerFrame :
nullptr, pos - outerFrame);
1015 pos += SerializeFramePostscript(buffer ? topMostFrame :
nullptr, pos - topMostFrame);
1016 std::uint32_t
size = pos - base;
1017 size += SerializeEnvelopePostscript(base,
size, *where);
1024 auto base =
reinterpret_cast<unsigned char *
>(buffer);
1026 void** where = (buffer ==
nullptr) ? &buffer :
reinterpret_cast<void**
>(&pos);
1028 pos += SerializeEnvelopePreamble(*where);
1031 pos += SerializeFeatureFlags(std::vector<std::int64_t>(), *where);
1036 pos += SerializeListFramePreamble(0, *where);
1037 pos += SerializeFramePostscript(buffer ? frame :
nullptr, pos - frame);
1041 pos += SerializeListFramePreamble(0, *where);
1042 pos += SerializeFramePostscript(buffer ? frame :
nullptr, pos - frame);
1047 pos += SerializeListFramePreamble(nClusters, *where);
1048 for (
unsigned int i = 0; i < nClusters; ++i) {
1050 RClusterSummary summary{clusterDesc.GetFirstEntryIndex(), clusterDesc.GetNEntries(), -1};
1051 pos += SerializeClusterSummary(summary, *where);
1053 pos += SerializeFramePostscript(buffer ? frame :
nullptr, pos - frame);
1057 const auto nClusterGroups = clusterGroups.size();
1059 pos += SerializeListFramePreamble(nClusterGroups, *where);
1060 for (
unsigned int i = 0; i < nClusterGroups; ++i) {
1061 pos += SerializeClusterGroup(clusterGroups[i], *where);
1063 pos += SerializeFramePostscript(buffer ? frame :
nullptr, pos - frame);
1067 pos += SerializeListFramePreamble(0, *where);
1068 pos += SerializeFramePostscript(buffer ? frame :
nullptr, pos - frame);
1070 std::uint32_t
size = pos - base;
1071 size += SerializeEnvelopePostscript(base,
size, *where);
1078 auto base =
reinterpret_cast<const unsigned char *
>(buffer);
1080 auto fnBufSizeLeft = [&]() {
return bufSize - (bytes - base); };
1083 std::uint32_t crc32{0};
1084 result = DeserializeEnvelope(bytes, fnBufSizeLeft(), crc32);
1087 bytes += result.Unwrap();
1090 std::vector<std::int64_t> featureFlags;
1091 result = DeserializeFeatureFlags(bytes, fnBufSizeLeft(), featureFlags);
1094 bytes += result.Unwrap();
1095 for (
auto f: featureFlags) {
1100 std::uint32_t rcTag;
1101 if (fnBufSizeLeft() <
static_cast<int>(
sizeof(std::uint32_t)))
1102 return R__FAIL(
"header too short");
1103 bytes += DeserializeUInt32(bytes, rcTag);
1109 std::string description;
1111 result = DeserializeString(bytes, fnBufSizeLeft(),
name);
1114 bytes += result.Unwrap();
1115 result = DeserializeString(bytes, fnBufSizeLeft(), description);
1118 bytes += result.Unwrap();
1119 result = DeserializeString(bytes, fnBufSizeLeft(),
writer);
1122 bytes += result.Unwrap();
1125 std::uint32_t frameSize;
1127 auto fnFrameSizeLeft = [&]() {
return frameSize - (bytes - frame); };
1129 std::uint32_t nFields;
1130 result = DeserializeFrameHeader(bytes, fnBufSizeLeft(), frameSize, nFields);
1133 bytes += result.Unwrap();
1136 .FieldId(kZeroFieldId)
1140 for (std::uint32_t fieldId = 0; fieldId < nFields; ++fieldId) {
1142 result = DeserializeFieldV1(bytes, fnFrameSizeLeft(), fieldBuilder);
1145 bytes += result.Unwrap();
1147 fieldBuilder.
ParentId(kZeroFieldId);
1151 auto parentId = fieldDesc.Inspect().GetParentId();
1152 descBuilder.
AddField(fieldDesc.Unwrap());
1153 auto resVoid = descBuilder.
AddFieldLink(parentId, fieldId);
1157 bytes = frame + frameSize;
1159 std::uint32_t nColumns;
1161 result = DeserializeFrameHeader(bytes, fnBufSizeLeft(), frameSize, nColumns);
1164 bytes += result.Unwrap();
1165 std::unordered_map<DescriptorId_t, std::uint32_t> maxIndexes;
1166 for (std::uint32_t columnId = 0; columnId < nColumns; ++columnId) {
1168 result = DeserializeColumnV1(bytes, fnFrameSizeLeft(), columnBuilder);
1171 bytes += result.Unwrap();
1173 std::uint32_t idx = 0;
1174 const auto fieldId = columnBuilder.
GetFieldId();
1175 auto maxIdx = maxIndexes.find(fieldId);
1176 if (maxIdx != maxIndexes.end())
1177 idx = maxIdx->second + 1;
1178 maxIndexes[fieldId] = idx;
1183 auto resVoid = descBuilder.
AddColumn(columnDesc.Unwrap());
1187 bytes = frame + frameSize;
1189 std::uint32_t nAliasColumns;
1191 result = DeserializeFrameHeader(bytes, fnBufSizeLeft(), frameSize, nAliasColumns);
1194 bytes += result.Unwrap();
1195 if (nAliasColumns > 0)
1198 std::uint32_t nTypeInfo;
1200 result = DeserializeFrameHeader(bytes, fnBufSizeLeft(), frameSize, nTypeInfo);
1203 bytes += result.Unwrap();
1214 auto base =
reinterpret_cast<const unsigned char *
>(buffer);
1216 auto fnBufSizeLeft = [&]() {
return bufSize - (bytes - base); };
1219 result = DeserializeEnvelope(bytes, fnBufSizeLeft());
1222 bytes += result.Unwrap();
1224 std::vector<std::int64_t> featureFlags;
1225 result = DeserializeFeatureFlags(bytes, fnBufSizeLeft(), featureFlags);
1228 bytes += result.Unwrap();
1229 for (
auto f: featureFlags) {
1234 std::uint32_t crc32{0};
1235 if (fnBufSizeLeft() <
static_cast<int>(
sizeof(std::uint32_t)))
1236 return R__FAIL(
"footer too short");
1237 bytes += DeserializeUInt32(bytes, crc32);
1239 return R__FAIL(
"CRC32 mismatch between header and footer");
1241 std::uint32_t frameSize;
1243 auto fnFrameSizeLeft = [&]() {
return frameSize - (bytes - frame); };
1245 std::uint32_t nXHeaders;
1246 result = DeserializeFrameHeader(bytes, fnBufSizeLeft(), frameSize, nXHeaders);
1251 bytes = frame + frameSize;
1253 std::uint32_t nColumnGroups;
1255 result = DeserializeFrameHeader(bytes, fnBufSizeLeft(), frameSize, nColumnGroups);
1258 if (nColumnGroups > 0)
1259 return R__FAIL(
"sharded clusters are still unsupported");
1260 bytes = frame + frameSize;
1262 std::uint32_t nClusterSummaries;
1264 result = DeserializeFrameHeader(bytes, fnBufSizeLeft(), frameSize, nClusterSummaries);
1267 bytes += result.Unwrap();
1268 for (std::uint32_t clusterId = 0; clusterId < nClusterSummaries; ++clusterId) {
1270 result = DeserializeClusterSummary(bytes, fnFrameSizeLeft(), clusterSummary);
1273 bytes += result.Unwrap();
1275 return R__FAIL(
"sharded clusters are still unsupported");
1278 bytes = frame + frameSize;
1280 std::uint32_t nClusterGroups;
1282 result = DeserializeFrameHeader(bytes, fnBufSizeLeft(), frameSize, nClusterGroups);
1285 bytes += result.Unwrap();
1286 for (std::uint32_t groupId = 0; groupId < nClusterGroups; ++groupId) {
1288 result = DeserializeClusterGroup(bytes, fnFrameSizeLeft(), clusterGroup);
1291 bytes += result.Unwrap();
1294 bytes = frame + frameSize;
1296 std::uint32_t nMDBlocks;
1298 result = DeserializeFrameHeader(bytes, fnBufSizeLeft(), frameSize, nMDBlocks);
1303 bytes = frame + frameSize;
1310 const void *buffer, std::uint32_t bufSize, std::vector<RClusterDescriptorBuilder> &clusters)
1312 auto base =
reinterpret_cast<const unsigned char *
>(buffer);
1314 auto fnBufSizeLeft = [&]() {
return bufSize - (bytes - base); };
1317 result = DeserializeEnvelope(bytes, fnBufSizeLeft());
1320 bytes += result.Unwrap();
1322 std::uint32_t topMostFrameSize;
1323 auto topMostFrame = bytes;
1324 auto fnTopMostFrameSizeLeft = [&]() {
return topMostFrameSize - (bytes - topMostFrame); };
1326 std::uint32_t nClusters;
1327 result = DeserializeFrameHeader(bytes, fnBufSizeLeft(), topMostFrameSize, nClusters);
1330 bytes += result.Unwrap();
1332 for (std::uint32_t i = 0; i < nClusters; ++i) {
1333 std::uint32_t outerFrameSize;
1334 auto outerFrame = bytes;
1335 auto fnOuterFrameSizeLeft = [&]() {
return outerFrameSize - (bytes - outerFrame); };
1339 std::uint32_t nColumns;
1340 result = DeserializeFrameHeader(bytes, fnTopMostFrameSizeLeft(), outerFrameSize, nColumns);
1343 bytes += result.Unwrap();
1345 for (std::uint32_t j = 0; j < nColumns; ++j) {
1346 std::uint32_t innerFrameSize;
1347 auto innerFrame = bytes;
1348 auto fnInnerFrameSizeLeft = [&]() {
return innerFrameSize - (bytes - innerFrame); };
1350 std::uint32_t nPages;
1351 result = DeserializeFrameHeader(bytes, fnOuterFrameSizeLeft(), innerFrameSize, nPages);
1354 bytes += result.Unwrap();
1358 for (std::uint32_t k = 0; k < nPages; ++k) {
1359 if (fnInnerFrameSizeLeft() <
static_cast<int>(
sizeof(std::uint32_t)))
1360 return R__FAIL(
"inner frame too short");
1361 std::uint32_t nElements;
1363 bytes += DeserializeUInt32(bytes, nElements);
1364 result = DeserializeLocator(bytes, fnInnerFrameSizeLeft(), locator);
1368 bytes += result.Unwrap();
1371 if (fnInnerFrameSizeLeft() <
static_cast<int>(
sizeof(std::uint32_t) +
sizeof(std::uint64_t)))
1372 return R__FAIL(
"page list frame too short");
1373 std::uint64_t columnOffset;
1374 bytes += DeserializeUInt64(bytes, columnOffset);
1375 std::uint32_t compressionSettings;
1376 bytes += DeserializeUInt32(bytes, compressionSettings);
1378 clusterBuilder.
CommitColumnRange(j, columnOffset, compressionSettings, pageRange);
1379 bytes = innerFrame + innerFrameSize;
1382 clusters.emplace_back(std::move(clusterBuilder));
1383 bytes = outerFrame + outerFrameSize;
#define R__FORWARD_ERROR(res)
Short-hand to return an RResult<T> in an error state (i.e. after checking)
#define R__FORWARD_RESULT(res)
Short-hand to return an RResult<T> value from a subroutine to the calling stack frame.
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
#define R__LOG_WARNING(...)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
virtual std::size_t GetBitsOnStorage() const
The available trivial, native content types of a column.
The serialization context is used for the piecewise serialization of a descriptor.
void SetHeaderCRC32(std::uint32_t crc32)
void SetHeaderSize(std::uint32_t size)
std::uint32_t GetHeaderCRC32() const
DescriptorId_t MapColumnId(DescriptorId_t memId)
DescriptorId_t MapFieldId(DescriptorId_t memId)
DescriptorId_t GetMemClusterId(DescriptorId_t physId) const
const std::vector< RClusterGroup > & GetClusterGroups() const
DescriptorId_t GetPhysColumnId(DescriptorId_t memId) const
DescriptorId_t GetPhysFieldId(DescriptorId_t memId) const
DescriptorId_t GetMemColumnId(DescriptorId_t physId) const
A helper class for serializing and deserialization of the RNTuple binary format.
static RResult< std::uint32_t > DeserializeString(const void *buffer, std::uint32_t bufSize, std::string &val)
static std::uint32_t SerializeFeatureFlags(const std::vector< std::int64_t > &flags, void *buffer)
static std::uint32_t SerializePageListV1(void *buffer, const RNTupleDescriptor &desc, std::span< DescriptorId_t > physClusterIDs, const RContext &context)
static std::uint32_t SerializeListFramePreamble(std::uint32_t nitems, void *buffer)
static RResult< std::uint32_t > DeserializeLocator(const void *buffer, std::uint32_t bufSize, RNTupleLocator &locator)
static std::uint32_t SerializeCRC32(const unsigned char *data, std::uint32_t length, std::uint32_t &crc32, void *buffer)
Writes a CRC32 checksum of the byte range given by data and length.
static std::uint16_t SerializeColumnType(ROOT::Experimental::EColumnType type, void *buffer)
static std::uint32_t DeserializeUInt16(const void *buffer, std::uint16_t &val)
static RResult< void > DeserializePageListV1(const void *buffer, std::uint32_t bufSize, std::vector< RClusterDescriptorBuilder > &clusters)
static std::uint32_t SerializeString(const std::string &val, void *buffer)
static RResult< std::uint32_t > DeserializeEnvelope(const void *buffer, std::uint32_t bufSize)
static std::uint32_t DeserializeUInt32(const void *buffer, std::uint32_t &val)
static std::uint32_t SerializeUInt64(std::uint64_t val, void *buffer)
static std::uint32_t DeserializeInt16(const void *buffer, std::int16_t &val)
static std::uint32_t SerializeClusterSummary(const RClusterSummary &clusterSummary, void *buffer)
static RContext SerializeHeaderV1(void *buffer, const RNTupleDescriptor &desc)
static RResult< void > DeserializeFooterV1(const void *buffer, std::uint32_t bufSize, RNTupleDescriptorBuilder &descBuilder)
static std::uint32_t SerializeInt16(std::int16_t val, void *buffer)
static std::uint32_t SerializeLocator(const RNTupleLocator &locator, void *buffer)
static std::uint32_t SerializeInt32(std::int32_t val, void *buffer)
static std::uint32_t SerializeEnvelopePreamble(void *buffer)
Currently all enevelopes have the same version number (1).
static RResult< std::uint16_t > DeserializeColumnType(const void *buffer, ROOT::Experimental::EColumnType &type)
static RResult< std::uint32_t > DeserializeClusterGroup(const void *buffer, std::uint32_t bufSize, RClusterGroup &clusterGroup)
static std::uint32_t DeserializeUInt64(const void *buffer, std::uint64_t &val)
static std::uint32_t DeserializeInt32(const void *buffer, std::int32_t &val)
static std::uint32_t DeserializeInt64(const void *buffer, std::int64_t &val)
static RResult< std::uint32_t > DeserializeEnvelopeLink(const void *buffer, std::uint32_t bufSize, REnvelopeLink &envelopeLink)
static std::uint32_t SerializeEnvelopePostscript(const unsigned char *envelope, std::uint32_t size, void *buffer)
static RResult< std::uint16_t > DeserializeFieldStructure(const void *buffer, ROOT::Experimental::ENTupleStructure &structure)
static std::uint32_t SerializeEnvelopeLink(const REnvelopeLink &envelopeLink, void *buffer)
static std::uint32_t SerializeRecordFramePreamble(void *buffer)
static std::uint32_t SerializeUInt16(std::uint16_t val, void *buffer)
static RResult< std::uint32_t > DeserializeFrameHeader(const void *buffer, std::uint32_t bufSize, std::uint32_t &frameSize, std::uint32_t &nitems)
static RResult< std::uint32_t > DeserializeFeatureFlags(const void *buffer, std::uint32_t bufSize, std::vector< std::int64_t > &flags)
static std::uint32_t SerializeClusterGroup(const RClusterGroup &clusterGroup, void *buffer)
static std::uint32_t SerializeFramePostscript(void *frame, std::int32_t size)
static std::uint32_t SerializeFooterV1(void *buffer, const RNTupleDescriptor &desc, const RContext &context)
static std::uint32_t SerializeInt64(std::int64_t val, void *buffer)
static RResult< void > VerifyCRC32(const unsigned char *data, std::uint32_t length, std::uint32_t &crc32)
Expects a CRC32 checksum in the 4 bytes following data + length and verifies it.
static std::uint16_t SerializeFieldStructure(ROOT::Experimental::ENTupleStructure structure, void *buffer)
While we could just interpret the enums as ints, we make the translation explicit in order to avoid a...
static std::uint32_t SerializeUInt32(std::uint32_t val, void *buffer)
static RResult< void > DeserializeHeaderV1(const void *buffer, std::uint32_t bufSize, RNTupleDescriptorBuilder &descBuilder)
static RResult< std::uint32_t > DeserializeClusterSummary(const void *buffer, std::uint32_t bufSize, RClusterSummary &clusterSummary)
A helper class for piece-wise construction of an RClusterDescriptor.
RResult< void > CommitColumnRange(DescriptorId_t columnId, std::uint64_t firstElementIndex, std::uint32_t compressionSettings, const RClusterDescriptor::RPageRange &pageRange)
A helper class for piece-wise construction of an RColumnDescriptor.
RColumnDescriptorBuilder & Model(const RColumnModel &model)
RResult< RColumnDescriptor > MakeDescriptor() const
Attempt to make a column descriptor.
RColumnDescriptorBuilder & FieldId(DescriptorId_t fieldId)
DescriptorId_t GetFieldId() const
RColumnDescriptorBuilder & Index(std::uint32_t index)
RColumnDescriptorBuilder & ColumnId(DescriptorId_t columnId)
Base class for all ROOT issued exceptions.
A helper class for piece-wise construction of an RFieldDescriptor.
RFieldDescriptorBuilder & FieldName(const std::string &fieldName)
RFieldDescriptorBuilder & NRepetitions(std::uint64_t nRepetitions)
RFieldDescriptorBuilder & FieldVersion(const RNTupleVersion &fieldVersion)
DescriptorId_t GetParentId() const
RFieldDescriptorBuilder & Structure(const ENTupleStructure &structure)
RResult< RFieldDescriptor > MakeDescriptor() const
Attempt to make a field descriptor.
RFieldDescriptorBuilder & TypeName(const std::string &typeName)
RFieldDescriptorBuilder & ParentId(DescriptorId_t id)
RFieldDescriptorBuilder & FieldDescription(const std::string &fieldDescription)
RFieldDescriptorBuilder & TypeVersion(const RNTupleVersion &typeVersion)
RFieldDescriptorBuilder & FieldId(DescriptorId_t fieldId)
Meta-data stored for every field of an ntuple.
RNTupleVersion GetTypeVersion() const
RNTupleVersion GetFieldVersion() const
std::string GetFieldName() const
std::string GetFieldDescription() const
std::string GetTypeName() const
std::uint64_t GetNRepetitions() const
ENTupleStructure GetStructure() const
A helper class for piece-wise construction of an RNTupleDescriptor.
void AddClusterSummary(Internal::RNTupleSerializer::RClusterSummary &clusterSummary)
std::uint32_t GetHeaderCRC32() const
RResult< void > AddFieldLink(DescriptorId_t fieldId, DescriptorId_t linkId)
void SetHeaderCRC32(std::uint32_t crc32)
void AddColumn(DescriptorId_t columnId, DescriptorId_t fieldId, const RNTupleVersion &version, const RColumnModel &model, std::uint32_t index)
void AddClusterGroup(Internal::RNTupleSerializer::RClusterGroup &clusterGroup)
void SetNTuple(const std::string_view name, const std::string_view description, const std::string_view author, const RNTupleVersion &version, const RNTupleUuid &uuid)
void AddField(const RFieldDescriptor &fieldDesc)
The on-storage meta-data of an ntuple.
std::string GetDescription() const
std::string GetName() const
std::size_t GetNClusters() const
DescriptorId_t GetFieldZeroId() const
Returns the logical parent of all top-level NTuple data fields.
RColumnDescriptorIterable GetColumnIterable(const RFieldDescriptor &fieldDesc) const
const RClusterDescriptor & GetClusterDescriptor(DescriptorId_t clusterId) const
RFieldDescriptorIterable GetFieldIterable(const RFieldDescriptor &fieldDesc) const
std::size_t GetNFields() const
std::size_t GetNColumns() const
For forward and backward compatibility, attach version information to the consitituents of the file f...
std::uint32_t GetVersionUse() const
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
RLogChannel & NTupleLog()
Log channel for RNTuple diagnostics.
RClusterSize ClusterSize_t
ENTupleStructure
The fields in the ntuple model tree can carry different structural information about the type system.
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
std::string RNTupleUuid
Every NTuple is identified by a UUID. TODO(jblomer): should this be a TUUID?
REnvelopeLink fPageListEnvelopeLink
std::uint64_t fFirstEntry
std::int32_t fColumnGroupID
-1 for "all columns"
std::uint32_t fUnzippedSize
Generic information about the physical location of data.
std::uint32_t fBytesOnStorage