45 std::string fPoolUuid;
47 std::string fSvcReplicas;
49 std::string fContainerUuid;
55RDaosURI ParseDaosURI(std::string_view uri)
57 std::regex re(
"daos://([[:xdigit:]-]+):([[:digit:]_]+)/([[:xdigit:]-]+)");
59 if (!std::regex_match(uri.data(),
m, re))
61 return {
m[1],
m[2],
m[3] };
66static constexpr std::uint64_t kDistributionKey = 0x5a3c69f0cafe4a11;
67static constexpr std::uint64_t kAttributeKey = 0x4243544b5344422d;
69static constexpr daos_obj_id_t kOidAnchor{std::uint64_t(-1), 0};
70static constexpr daos_obj_id_t kOidHeader{std::uint64_t(-2), 0};
71static constexpr daos_obj_id_t kOidFooter{std::uint64_t(-3), 0};
76static constexpr daos_obj_id_t kOidPageList{std::numeric_limits<int64_t>::max(), 0};
89 if (buffer !=
nullptr) {
90 auto bytes =
reinterpret_cast<unsigned char *
>(buffer);
91 bytes += RNTupleSerializer::SerializeUInt32(
fVersion, bytes);
92 bytes += RNTupleSerializer::SerializeUInt32(
fNBytesHeader, bytes);
93 bytes += RNTupleSerializer::SerializeUInt32(
fLenHeader, bytes);
94 bytes += RNTupleSerializer::SerializeUInt32(
fNBytesFooter, bytes);
95 bytes += RNTupleSerializer::SerializeUInt32(
fLenFooter, bytes);
96 bytes += RNTupleSerializer::SerializeString(
fObjClass, bytes);
98 return RNTupleSerializer::SerializeString(
fObjClass,
nullptr) + 20;
105 return R__FAIL(
"DAOS anchor too short");
108 auto bytes =
reinterpret_cast<const unsigned char *
>(buffer);
109 bytes += RNTupleSerializer::DeserializeUInt32(bytes, fVersion);
110 bytes += RNTupleSerializer::DeserializeUInt32(bytes, fNBytesHeader);
111 bytes += RNTupleSerializer::DeserializeUInt32(bytes, fLenHeader);
112 bytes += RNTupleSerializer::DeserializeUInt32(bytes, fNBytesFooter);
113 bytes += RNTupleSerializer::DeserializeUInt32(bytes, fLenFooter);
114 auto result = RNTupleSerializer::DeserializeString(bytes, bufSize - 20, fObjClass);
117 return result.Unwrap() + 20;
138 "Do not store real data with this version of RNTuple!";
139 fCompressor = std::make_unique<RNTupleCompressor>();
152 if (oclass.IsUnknown())
155 auto args = ParseDaosURI(fURI);
156 auto pool = std::make_shared<RDaosPool>(args.fPoolUuid, args.fSvcReplicas);
157 fDaosContainer = std::make_unique<RDaosContainer>(pool, args.fContainerUuid,
true);
158 fDaosContainer->SetDefaultObjectClass(oclass);
160 const auto &descriptor = fDescriptorBuilder.GetDescriptor();
162 auto buffer = std::make_unique<unsigned char[]>(fSerializationContext.GetHeaderSize());
165 auto zipBuffer = std::make_unique<unsigned char[]>(fSerializationContext.GetHeaderSize());
167 fCompressor->Zip(buffer.get(), fSerializationContext.GetHeaderSize(), GetWriteOptions().GetCompression(),
168 [&zipBuffer](
const void *
b,
size_t n,
size_t o) { memcpy(zipBuffer.get() + o,
b,
n); });
169 WriteNTupleHeader(zipBuffer.get(), szZipHeader, fSerializationContext.GetHeaderSize());
180 sealedPage = SealPage(page, *element, GetWriteOptions().GetCompression());
184 return CommitSealedPageImpl(columnHandle.
fId, sealedPage);
192 auto offsetData = fOid.fetch_add(1);
195 fDaosContainer->WriteSingleAkey(sealedPage.
fBuffer, sealedPage.
fSize,
196 {offsetData, 0}, kDistributionKey, kAttributeKey);
202 fCounters->fNPageCommitted.Inc();
203 fCounters->fSzWritePayload.Add(sealedPage.
fSize);
204 fNBytesCurrentCluster += sealedPage.
fSize;
212 return std::exchange(fNBytesCurrentCluster, 0);
218 const auto &descriptor = fDescriptorBuilder.GetDescriptor();
220 std::vector<DescriptorId_t> physClusterIDs;
221 for (
const auto &
c : descriptor.GetClusterIterable()) {
222 physClusterIDs.emplace_back(fSerializationContext.MapClusterId(
c.GetId()));
227 auto bufPageList = std::make_unique<unsigned char[]>(szPageList);
229 fSerializationContext);
231 auto bufPageListZip = std::make_unique<unsigned char[]>(szPageList);
232 auto szPageListZip = fCompressor->Zip(bufPageList.get(), szPageList, GetWriteOptions().GetCompression(),
234 fDaosContainer->WriteSingleAkey(bufPageListZip.get(), szPageListZip, kOidPageList, kDistributionKey, kAttributeKey,
241 fSerializationContext.AddClusterGroup(physClusterIDs.size(), pageListEnvelope);
244 auto bufFooter = std::make_unique<unsigned char[]>(szFooter);
247 auto bufFooterZip = std::make_unique<unsigned char[]>(szFooter);
248 auto szFooterZip = fCompressor->Zip(bufFooter.get(), szFooter, GetWriteOptions().GetCompression(),
250 WriteNTupleFooter(bufFooterZip.get(), szFooterZip, szFooter);
256 const void *data,
size_t nbytes,
size_t lenHeader)
258 fDaosContainer->WriteSingleAkey(data, nbytes, kOidHeader, kDistributionKey,
259 kAttributeKey, kCidMetadata);
260 fNTupleAnchor.fLenHeader = lenHeader;
261 fNTupleAnchor.fNBytesHeader = nbytes;
265 const void *data,
size_t nbytes,
size_t lenFooter)
267 fDaosContainer->WriteSingleAkey(data, nbytes, kOidFooter, kDistributionKey,
268 kAttributeKey, kCidMetadata);
269 fNTupleAnchor.fLenFooter = lenFooter;
270 fNTupleAnchor.fNBytesFooter = nbytes;
275 auto buffer = std::make_unique<unsigned char[]>(ntplSize);
276 fNTupleAnchor.Serialize(buffer.get());
277 fDaosContainer->WriteSingleAkey(buffer.get(), ntplSize, kOidAnchor, kDistributionKey,
278 kAttributeKey, kCidMetadata);
287 return fPageAllocator->NewPage(columnHandle.
fId, elementSize, nElements);
292 fPageAllocator->DeletePage(page);
300 ColumnId_t columnId,
void *mem, std::size_t elementSize, std::size_t nElements)
302 RPage newPage(columnId, mem, elementSize, nElements);
311 delete[]
reinterpret_cast<unsigned char *
>(page.
GetBuffer());
322 , fPagePool(std::make_shared<
RPagePool>())
329 auto args = ParseDaosURI(uri);
330 auto pool = std::make_shared<RDaosPool>(args.fPoolUuid, args.fSvcReplicas);
331 fDaosContainer = std::make_unique<RDaosContainer>(pool, args.fContainerUuid);
343 auto buffer = std::make_unique<unsigned char[]>(ntplSize);
344 fDaosContainer->ReadSingleAkey(buffer.get(), ntplSize, kOidAnchor, kDistributionKey,
345 kAttributeKey, kCidMetadata);
349 if (oclass.IsUnknown())
351 fDaosContainer->SetDefaultObjectClass(oclass);
354 buffer = std::make_unique<unsigned char[]>(ntpl.
fLenHeader);
355 auto zipBuffer = std::make_unique<unsigned char[]>(ntpl.
fNBytesHeader);
356 fDaosContainer->ReadSingleAkey(zipBuffer.get(), ntpl.
fNBytesHeader, kOidHeader, kDistributionKey,
357 kAttributeKey, kCidMetadata);
361 buffer = std::make_unique<unsigned char[]>(ntpl.
fLenFooter);
362 zipBuffer = std::make_unique<unsigned char[]>(ntpl.
fNBytesFooter);
363 fDaosContainer->ReadSingleAkey(zipBuffer.get(), ntpl.
fNBytesFooter, kOidFooter, kDistributionKey,
364 kAttributeKey, kCidMetadata);
370 buffer = std::make_unique<unsigned char[]>(cg.fPageListEnvelopeLink.fUnzippedSize);
371 zipBuffer = std::make_unique<unsigned char[]>(cg.fPageListEnvelopeLink.fLocator.fBytesOnStorage);
372 fDaosContainer->ReadSingleAkey(
373 zipBuffer.get(), cg.fPageListEnvelopeLink.fLocator.fBytesOnStorage,
374 {static_cast<decltype(daos_obj_id_t::lo)>(cg.fPageListEnvelopeLink.fLocator.fPosition), 0}, kDistributionKey,
375 kAttributeKey, kCidMetadata);
376 fDecompressor->Unzip(zipBuffer.get(), cg.fPageListEnvelopeLink.fLocator.fBytesOnStorage,
377 cg.fPageListEnvelopeLink.fUnzippedSize, buffer.get());
379 std::vector<RClusterDescriptorBuilder> clusters;
381 for (std::size_t i = 0; i < clusters.size(); ++i) {
382 descBuilder.
AddCluster(i, std::move(clusters[i]));
391 return fDaosContainer->GetDefaultObjectClass().ToString();
399 const auto &clusterDescriptor = fDescriptor.GetClusterDescriptor(clusterId);
401 auto pageInfo = clusterDescriptor.GetPageRange(columnId).Find(clusterIndex.
GetIndex());
403 const auto bytesOnStorage = pageInfo.fLocator.fBytesOnStorage;
404 sealedPage.
fSize = bytesOnStorage;
407 fDaosContainer->ReadSingleAkey(
const_cast<void *
>(sealedPage.
fBuffer), bytesOnStorage,
408 {static_cast<decltype(daos_obj_id_t::lo)>(pageInfo.fLocator.fPosition), 0},
409 kDistributionKey, kAttributeKey);
416 const auto columnId = columnHandle.
fId;
417 const auto clusterId = clusterDescriptor.
GetId();
419 auto pageInfo = clusterDescriptor.
GetPageRange(columnId).
Find(idxInCluster);
422 const auto elementSize = element->
GetSize();
423 const auto bytesOnStorage = pageInfo.fLocator.fBytesOnStorage;
425 const void *sealedPageBuffer =
nullptr;
426 std::unique_ptr<unsigned char []> directReadBuffer;
429 directReadBuffer = std::make_unique<unsigned char[]>(bytesOnStorage);
430 fDaosContainer->ReadSingleAkey(directReadBuffer.get(), bytesOnStorage,
431 {static_cast<decltype(daos_obj_id_t::lo)>(pageInfo.fLocator.fPosition), 0},
432 kDistributionKey, kAttributeKey);
433 fCounters->fNPageLoaded.Inc();
434 fCounters->fNRead.Inc();
435 fCounters->fSzReadPayload.Add(bytesOnStorage);
436 sealedPageBuffer = directReadBuffer.get();
438 if (!fCurrentCluster || (fCurrentCluster->GetId() != clusterId) || !fCurrentCluster->ContainsColumn(columnId))
439 fCurrentCluster = fClusterPool->GetCluster(clusterId, fActiveColumns);
440 R__ASSERT(fCurrentCluster->ContainsColumn(columnId));
442 auto cachedPage = fPagePool->GetPage(columnId,
RClusterIndex(clusterId, idxInCluster));
443 if (!cachedPage.IsNull())
447 auto onDiskPage = fCurrentCluster->GetOnDiskPage(key);
448 R__ASSERT(onDiskPage && (bytesOnStorage == onDiskPage->GetSize()));
449 sealedPageBuffer = onDiskPage->GetAddress();
452 std::unique_ptr<unsigned char []> pageBuffer;
455 pageBuffer = UnsealPage({sealedPageBuffer, bytesOnStorage, pageInfo.fNElements}, *element);
456 fCounters->fSzUnzip.Add(elementSize * pageInfo.fNElements);
460 auto newPage = fPageAllocator->NewPage(columnId, pageBuffer.release(), elementSize, pageInfo.fNElements);
461 newPage.SetWindow(indexOffset + pageInfo.fFirstInPage,
RPage::RClusterInfo(clusterId, indexOffset));
462 fPagePool->RegisterPage(newPage,
467 fCounters->fNPagePopulated.Inc();
475 const auto columnId = columnHandle.
fId;
476 auto cachedPage = fPagePool->GetPage(columnId, globalIndex);
477 if (!cachedPage.IsNull())
480 const auto clusterId = fDescriptor.FindClusterId(columnId, globalIndex);
482 const auto &clusterDescriptor = fDescriptor.GetClusterDescriptor(clusterId);
483 const auto selfOffset = clusterDescriptor.GetColumnRange(columnId).fFirstElementIndex;
485 return PopulatePageFromCluster(columnHandle, clusterDescriptor, globalIndex - selfOffset);
493 const auto idxInCluster = clusterIndex.
GetIndex();
494 const auto columnId = columnHandle.
fId;
495 auto cachedPage = fPagePool->GetPage(columnId, clusterIndex);
496 if (!cachedPage.IsNull())
500 const auto &clusterDescriptor = fDescriptor.GetClusterDescriptor(clusterId);
501 return PopulatePageFromCluster(columnHandle, clusterDescriptor, idxInCluster);
506 fPagePool->ReturnPage(page);
512 return std::unique_ptr<RPageSourceDaos>(clone);
515std::vector<std::unique_ptr<ROOT::Experimental::Detail::RCluster>>
518 std::vector<std::unique_ptr<ROOT::Experimental::Detail::RCluster>> result;
519 for (
const auto &clusterKey : clusterKeys) {
520 auto clusterId = clusterKey.fClusterId;
521 fCounters->fNClusterLoaded.Inc();
523 const auto &clusterDesc = GetDescriptor().GetClusterDescriptor(clusterId);
525 struct RDaosSealedPageLocator {
526 RDaosSealedPageLocator() =
default;
528 : fColumnId(
c), fPageNo(p), fObjectId(o),
fSize(s), fBufPos(
b) {}
531 std::uint64_t fObjectId = 0;
532 std::uint64_t
fSize = 0;
533 std::size_t fBufPos = 0;
537 std::vector<RDaosSealedPageLocator> onDiskPages;
538 std::size_t szPayload = 0;
539 for (
auto columnId : clusterKey.fColumnSet) {
540 const auto &pageRange = clusterDesc.GetPageRange(columnId);
542 for (
const auto &pageInfo : pageRange.fPageInfos) {
543 const auto &pageLocator = pageInfo.fLocator;
544 onDiskPages.emplace_back(RDaosSealedPageLocator(
545 columnId, pageNo, pageLocator.fPosition, pageLocator.fBytesOnStorage, szPayload));
546 szPayload += pageLocator.fBytesOnStorage;
552 std::vector<RDaosContainer::RWOperation> readRequests;
553 auto buffer =
new unsigned char[szPayload];
554 for (
auto &s : onDiskPages) {
555 std::vector<d_iov_t> iovs(1);
556 d_iov_set(&iovs[0], buffer + s.fBufPos, s.fSize);
558 kDistributionKey, kAttributeKey, iovs);
560 fCounters->fSzReadPayload.Add(szPayload);
563 auto pageMap = std::make_unique<ROnDiskPageMapHeap>(std::unique_ptr<
unsigned char []>(buffer));
564 for (
const auto &s : onDiskPages) {
566 pageMap->Register(key,
ROnDiskPage(buffer + s.fBufPos, s.fSize));
568 fCounters->fNPageLoaded.Add(onDiskPages.size());
572 fDaosContainer->ReadV(readRequests);
574 fCounters->fNReadV.Inc();
575 fCounters->fNRead.Add(readRequests.size());
577 auto cluster = std::make_unique<RCluster>(clusterId);
578 cluster->Adopt(std::move(pageMap));
579 for (
auto colId : clusterKey.fColumnSet)
580 cluster->SetColumnAvailable(colId);
582 result.emplace_back(std::move(cluster));
591 fTaskScheduler->Reset();
593 const auto clusterId = cluster->
GetId();
594 const auto &clusterDescriptor = fDescriptor.GetClusterDescriptor(clusterId);
596 std::vector<std::unique_ptr<RColumnElementBase>> allElements;
599 for (
const auto columnId : columnsInCluster) {
600 const auto &columnDesc = fDescriptor.GetColumnDescriptor(columnId);
604 const auto &pageRange = clusterDescriptor.GetPageRange(columnId);
605 std::uint64_t pageNo = 0;
606 std::uint64_t firstInPage = 0;
607 for (
const auto &pi : pageRange.fPageInfos) {
610 R__ASSERT(onDiskPage && (onDiskPage->GetSize() == pi.fLocator.fBytesOnStorage));
613 [
this, columnId, clusterId, firstInPage, onDiskPage,
614 element = allElements.back().get(),
615 nElements = pi.fNElements,
616 indexOffset = clusterDescriptor.GetColumnRange(columnId).fFirstElementIndex
618 auto pageBuffer = UnsealPage({onDiskPage->GetAddress(), onDiskPage->GetSize(), nElements}, *element);
619 fCounters->fSzUnzip.Add(element->GetSize() * nElements);
621 auto newPage = fPageAllocator->NewPage(columnId, pageBuffer.release(), element->GetSize(), nElements);
623 fPagePool->PreloadPage(newPage,
630 fTaskScheduler->AddTask(taskFunc);
632 firstInPage += pi.fNElements;
639 fTaskScheduler->Wait();
#define R__FORWARD_ERROR(res)
Short-hand to return an RResult<T> in an error state (i.e. after checking)
#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(...)
Managed a set of clusters containing compressed and packed pages.
An in-memory subset of the packed and compressed pages of a cluster.
const ColumnSet_t & GetAvailColumns() const
size_t GetNOnDiskPages() const
DescriptorId_t GetId() const
const ROnDiskPage * GetOnDiskPage(const ROnDiskPage::Key &key) const
static std::unique_ptr< RColumnElementBase > Generate(EColumnType type)
std::size_t GetSize() const
RColumnElementBase * GetElement() const
static Writer_t MakeMemCopyWriter(unsigned char *dest)
Record wall time and CPU time between construction and destruction.
A page as being stored on disk, that is packed and compressed.
Manages pages read from a DAOS container.
static RPage NewPage(ColumnId_t columnId, void *mem, std::size_t elementSize, std::size_t nElements)
static void DeletePage(const RPage &page)
Uses standard C++ memory allocation for the column data pages.
A closure that can free the memory associated with a mapped page.
A thread-safe cache of column pages.
void ReleasePage(RPage &page) final
Every page store needs to be able to free pages it handed out.
RPageSinkDaos(std::string_view ntupleName, std::string_view uri, const RNTupleWriteOptions &options)
RNTupleLocator CommitSealedPageImpl(DescriptorId_t columnId, const RPageStorage::RSealedPage &sealedPage) final
void WriteNTupleFooter(const void *data, size_t nbytes, size_t lenFooter)
void WriteNTupleHeader(const void *data, size_t nbytes, size_t lenHeader)
std::uint64_t CommitClusterImpl(NTupleSize_t nEntries) final
Returns the number of bytes written to storage (excluding metadata)
RNTupleLocator CommitPageImpl(ColumnHandle_t columnHandle, const RPage &page) final
void CreateImpl(const RNTupleModel &model) final
RPage ReservePage(ColumnHandle_t columnHandle, std::size_t nElements) final
Get a new, empty page for the given column that can be filled with up to nElements.
void CommitDatasetImpl() final
Abstract interface to write data into an ntuple.
void EnableDefaultMetrics(const std::string &prefix)
Enables the default set of metrics provided by RPageSink.
std::unique_ptr< RNTupleCompressor > fCompressor
Helper to zip pages and header/footer; includes a 16MB (kMAXZIPBUF) zip buffer.
Storage provider that reads ntuple pages from a DAOS container.
std::unique_ptr< RDaosContainer > fDaosContainer
A container that stores object data (header/footer, pages, etc.)
void LoadSealedPage(DescriptorId_t columnId, const RClusterIndex &clusterIndex, RSealedPage &sealedPage) final
Read the packed and compressed bytes of a page into the memory buffer provided by selaedPage.
RPage PopulatePageFromCluster(ColumnHandle_t columnHandle, const RClusterDescriptor &clusterDescriptor, ClusterSize_t::ValueType idxInCluster)
RPageSourceDaos(std::string_view ntupleName, std::string_view uri, const RNTupleReadOptions &options)
void ReleasePage(RPage &page) final
Every page store needs to be able to free pages it handed out.
void UnzipClusterImpl(RCluster *cluster) final
std::vector< std::unique_ptr< RCluster > > LoadClusters(std::span< RCluster::RKey > clusterKeys) final
Populates all the pages of the given cluster ids and columns; it is possible that some columns do not...
RPage PopulatePage(ColumnHandle_t columnHandle, NTupleSize_t globalIndex) final
Allocates and fills a page that contains the index-th element.
std::string GetObjectClass() const
Return the object class used for user data OIDs in this ntuple.
RNTupleDescriptor AttachImpl() final
std::unique_ptr< RPageSource > Clone() const final
The cloned page source creates a new connection to the pool/container.
virtual ~RPageSourceDaos()
Abstract interface to read data from an ntuple.
void EnableDefaultMetrics(const std::string &prefix)
Enables the default set of metrics provided by RPageSource.
std::unique_ptr< RNTupleDecompressor > fDecompressor
Helper to unzip pages and header/footer; comprises a 16MB (kMAXZIPBUF) unzip buffer.
Stores information about the cluster in which this page resides.
A page is a slice of a column that is mapped into memory.
ClusterSize_t::ValueType GetNBytes() const
The space taken by column elements in the buffer.
void * GrowUnchecked(ClusterSize_t::ValueType nElements)
Called during writing: returns a pointer after the last element and increases the element counter in ...
A helper class for serializing and deserialization of the RNTuple binary format.
static std::uint32_t SerializePageListV1(void *buffer, const RNTupleDescriptor &desc, std::span< DescriptorId_t > physClusterIDs, const RContext &context)
static RResult< void > DeserializePageListV1(const void *buffer, std::uint32_t bufSize, std::vector< RClusterDescriptorBuilder > &clusters)
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 SerializeFooterV1(void *buffer, const RNTupleDescriptor &desc, const RContext &context)
static RResult< void > DeserializeHeaderV1(const void *buffer, std::uint32_t bufSize, RNTupleDescriptorBuilder &descBuilder)
Meta-data for a set of ntuple clusters.
const RPageRange & GetPageRange(DescriptorId_t columnId) const
const RColumnRange & GetColumnRange(DescriptorId_t columnId) const
DescriptorId_t GetId() const
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
DescriptorId_t GetClusterId() const
ClusterSize_t::ValueType GetIndex() const
Base class for all ROOT issued exceptions.
A helper class for piece-wise construction of an RNTupleDescriptor.
RNTupleDescriptor MoveDescriptor()
Internal::RNTupleSerializer::RClusterGroup GetClusterGroup(std::uint32_t id) const
void SetOnDiskFooterSize(std::uint64_t size)
void AddCluster(DescriptorId_t clusterId, RNTupleVersion version, NTupleSize_t firstEntryIndex, ClusterSize_t nEntries)
void SetOnDiskHeaderSize(std::uint64_t size)
The on-storage meta-data of an ntuple.
The RNTupleModel encapulates the schema of an ntuple.
Common user-tunable settings for reading ntuples.
DAOS-specific user-tunable settings for storing ntuples.
const std::string & GetObjectClass() const
Common user-tunable settings for storing ntuples.
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
static void d_iov_set(d_iov_t *iov, void *buf, size_t size)
uint16_t daos_oclass_id_t
RLogChannel & NTupleLog()
Log channel for RNTuple diagnostics.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
std::int64_t ColumnId_t
Uniquely identifies a physical column within the scope of the current process, used to tag pages.
constexpr DescriptorId_t kInvalidDescriptorId
Entry point for an RNTuple in a DAOS container.
std::uint32_t fNBytesFooter
The size of the compressed ntuple footer.
std::uint32_t fNBytesHeader
The size of the compressed ntuple header.
std::string fObjClass
The object class for user data OIDs, e.g. SX
std::uint32_t fVersion
Allows for evolving the struct in future versions.
RResult< std::uint32_t > Deserialize(const void *buffer, std::uint32_t bufSize)
std::uint32_t fLenHeader
The size of the uncompressed ntuple header.
static std::uint32_t GetSize()
std::uint32_t Serialize(void *buffer) const
std::uint32_t fLenFooter
The size of the uncompressed ntuple footer.
Wrap around a daos_oclass_id_t.
static constexpr std::size_t kOCNameMaxLength
This limit is currently not defined in any header and any call to daos_oclass_id2name() within DAOS u...
On-disk pages within a page source are identified by the column and page number.
A sealed page contains the bytes of a page as written to storage (packed & compressed).
std::uint32_t fUnzippedSize
NTupleSize_t fFirstElementIndex
A 64bit element index.
Generic information about the physical location of data.
std::uint32_t fBytesOnStorage