3535#include < cstdlib>
3636#include < cstring>
3737#include < limits>
38+ #include < tuple>
3839#include < utility>
3940#include < regex>
4041#include < cassert>
@@ -129,7 +130,7 @@ struct RDaosContainerNTupleLocator {
129130 int InitNTupleDescriptorBuilder (ROOT ::Experimental::Internal::RDaosContainer &cont,
130131 ROOT ::Internal::RNTupleDescriptorBuilder &builder)
131132 {
132- std::unique_ptr<unsigned char []> buffer, zipBuffer ;
133+ std::unique_ptr<unsigned char []> buffer;
133134 auto &anchor = fAnchor .emplace ();
134135 int err;
135136
@@ -146,22 +147,7 @@ struct RDaosContainerNTupleLocator {
146147
147148 builder.SetVersion (anchor.fVersionEpoch , anchor.fVersionMajor , anchor.fVersionMinor , anchor.fVersionPatch );
148149 builder.SetOnDiskHeaderSize (anchor.fNBytesHeader );
149- buffer = MakeUninitArray<unsigned char >(anchor.fLenHeader );
150- zipBuffer = MakeUninitArray<unsigned char >(anchor.fNBytesHeader );
151- if ((err = cont.ReadSingleAkey (zipBuffer.get (), anchor.fNBytesHeader , oidMetadata, kDistributionKeyDefault ,
152- kAttributeKeyHeader , kCidMetadata )))
153- return err;
154- RNTupleDecompressor::Unzip (zipBuffer.get (), anchor.fNBytesHeader , anchor.fLenHeader , buffer.get ());
155- RNTupleSerializer::DeserializeHeader (buffer.get (), anchor.fLenHeader , builder);
156-
157150 builder.AddToOnDiskFooterSize (anchor.fNBytesFooter );
158- buffer = MakeUninitArray<unsigned char >(anchor.fLenFooter );
159- zipBuffer = MakeUninitArray<unsigned char >(anchor.fNBytesFooter );
160- if ((err = cont.ReadSingleAkey (zipBuffer.get (), anchor.fNBytesFooter , oidMetadata, kDistributionKeyDefault ,
161- kAttributeKeyFooter , kCidMetadata )))
162- return err;
163- RNTupleDecompressor::Unzip (zipBuffer.get (), anchor.fNBytesFooter , anchor.fLenFooter , buffer.get ());
164- RNTupleSerializer::DeserializeFooter (buffer.get (), anchor.fLenFooter , builder);
165151
166152 return 0 ;
167153 }
@@ -174,13 +160,7 @@ struct RDaosContainerNTupleLocator {
174160 auto &loc = result.first ;
175161 auto &builder = result.second ;
176162
177- if (int err = loc.InitNTupleDescriptorBuilder (cont, builder); !err) {
178- if (ntupleName.empty () || ntupleName != builder.GetDescriptor ().GetName ()) {
179- // Hash already taken by a differently-named ntuple.
180- throw ROOT::RException (
181- R__FAIL (" LocateNTuple: ntuple name '" + ntupleName + " ' unavailable in this container." ));
182- }
183- }
163+ loc.InitNTupleDescriptorBuilder (cont, builder);
184164 return result;
185165 }
186166};
@@ -455,27 +435,64 @@ ROOT::Experimental::Internal::RPageSourceDaos::~RPageSourceDaos()
455435 StopClusterPoolBackgroundThread ();
456436}
457437
438+ void ROOT::Experimental::Internal::RPageSourceDaos::LoadStructureImpl ()
439+ {
440+ RDaosContainerNTupleLocator ntupleLocator;
441+ std::tie (ntupleLocator, fDescriptorBuilder ) =
442+ RDaosContainerNTupleLocator::LocateNTuple (*fDaosContainer , fNTupleName );
443+ if (!ntupleLocator.IsValid ()) {
444+ throw ROOT::RException (
445+ R__FAIL (" LoadStructureImpl: requested ntuple '" + fNTupleName + " ' is not present in DAOS container." ));
446+ }
447+ fAnchor = *ntupleLocator.fAnchor ;
448+ fNTupleIndex = ntupleLocator.GetIndex ();
449+
450+ auto oclass = RDaosObject::ObjClassId (fAnchor .fObjClass );
451+ if (oclass.IsUnknown ())
452+ throw ROOT::RException (R__FAIL (" LoadStructureImpl: unknown object class " + fAnchor .fObjClass ));
453+ fDaosContainer ->SetDefaultObjectClass (oclass);
454+
455+ // Reserve enough space for the compressed and the uncompressed header/footer (see AttachImpl)
456+ const auto bufSize =
457+ fAnchor .fNBytesHeader + fAnchor .fNBytesFooter + std::max (fAnchor .fLenHeader , fAnchor .fLenFooter );
458+ fStructureBuffer .fBuffer = MakeUninitArray<unsigned char >(bufSize);
459+ fStructureBuffer .fPtrHeader = fStructureBuffer .fBuffer .get ();
460+ fStructureBuffer .fPtrFooter = fStructureBuffer .fBuffer .get () + fAnchor .fNBytesHeader ;
461+
462+ int err;
463+ daos_obj_id_t oidMetadata{kOidLowMetadata , static_cast <decltype (daos_obj_id_t ::hi)>(fNTupleIndex )};
464+
465+ if ((err = fDaosContainer ->ReadSingleAkey (fStructureBuffer .fPtrHeader , fAnchor .fNBytesHeader , oidMetadata,
466+ kDistributionKeyDefault , kAttributeKeyHeader , kCidMetadata ))) {
467+ throw ROOT::RException (R__FAIL (" LoadStructureImpl: cannot load header: " + std::to_string (err)));
468+ }
469+
470+ if ((err = fDaosContainer ->ReadSingleAkey (fStructureBuffer .fPtrFooter , fAnchor .fNBytesFooter , oidMetadata,
471+ kDistributionKeyDefault , kAttributeKeyFooter , kCidMetadata ))) {
472+ throw ROOT::RException (R__FAIL (" LoadStructureImpl: cannot load footer: " + std::to_string (err)));
473+ }
474+ }
475+
458476ROOT ::RNTupleDescriptor
459477ROOT ::Experimental::Internal::RPageSourceDaos::AttachImpl(RNTupleSerializer::EDescriptorDeserializeMode mode)
460478{
461- ROOT ::RNTupleDescriptor ntplDesc;
462- std::unique_ptr<unsigned char []> buffer, zipBuffer;
479+ auto unzipBuf = reinterpret_cast <unsigned char *>(fStructureBuffer .fPtrFooter ) + fAnchor .fNBytesFooter ;
463480
464- auto [locator, descBuilder] = RDaosContainerNTupleLocator::LocateNTuple (*fDaosContainer , fNTupleName );
465- if (!locator.IsValid ())
466- throw ROOT::RException (
467- R__FAIL (" Attach: requested ntuple '" + fNTupleName + " ' is not present in DAOS container." ));
481+ RNTupleDecompressor::Unzip (fStructureBuffer .fPtrHeader , fAnchor .fNBytesHeader , fAnchor .fLenHeader , unzipBuf);
482+ RNTupleSerializer::DeserializeHeader (unzipBuf, fAnchor .fLenHeader , fDescriptorBuilder );
468483
469- auto oclass = RDaosObject::ObjClassId (locator.fAnchor ->fObjClass );
470- if (oclass.IsUnknown ())
471- throw ROOT::RException (R__FAIL (" Attach: unknown object class " + locator.fAnchor ->fObjClass ));
484+ RNTupleDecompressor::Unzip (fStructureBuffer .fPtrFooter , fAnchor .fNBytesFooter , fAnchor .fLenFooter , unzipBuf);
485+ RNTupleSerializer::DeserializeFooter (unzipBuf, fAnchor .fLenFooter , fDescriptorBuilder );
472486
473- fDaosContainer ->SetDefaultObjectClass (oclass);
474- fNTupleIndex = locator.GetIndex ();
475- daos_obj_id_t oidPageList{kOidLowPageList , static_cast <decltype (daos_obj_id_t ::hi)>(fNTupleIndex )};
487+ if (fDescriptorBuilder .GetDescriptor ().GetName () != fNTupleName ) {
488+ // Hash already taken by a differently-named ntuple.
489+ throw ROOT::RException (R__FAIL (" LocateNTuple: ntuple name '" + fNTupleName + " ' unavailable in this container." ));
490+ }
476491
477- auto desc = descBuilder .MoveDescriptor ();
492+ auto desc = fDescriptorBuilder .MoveDescriptor ();
478493
494+ std::unique_ptr<unsigned char []> buffer, zipBuffer;
495+ daos_obj_id_t oidPageList{kOidLowPageList , static_cast <decltype (daos_obj_id_t ::hi)>(fNTupleIndex )};
479496 for (const auto &cgDesc : desc.GetClusterGroupIterable ()) {
480497 buffer = MakeUninitArray<unsigned char >(cgDesc.GetPageListLength ());
481498 zipBuffer = MakeUninitArray<unsigned char >(cgDesc.GetPageListLocator ().GetNBytesOnStorage ());
0 commit comments