diff --git a/io/io/inc/TFileMerger.h b/io/io/inc/TFileMerger.h index 339881a42d16406752dec283577322abe69e25c0..a7b04ee9a9433e10590e4d2a461915018a13e578 100644 --- a/io/io/inc/TFileMerger.h +++ b/io/io/inc/TFileMerger.h @@ -66,13 +66,14 @@ public: kIncremental = BIT(1), ///< Merge the input file with the content of the output file (if already exising). kResetable = BIT(2), ///< Only the objects with a MergeAfterReset member function. kNonResetable = BIT(3), ///< Only the objects without a MergeAfterReset member function. + kDelayWrite = BIT(4), ///< Delay the TFile write (to reduce the number of write when reusing the file) kAll = BIT(2)|BIT(3), ///< Merge all type of objects (default) kAllIncremental = kIncremental | kAll, ///< Merge incrementally all type of objects. - kOnlyListed = BIT(4), ///< Only the objects specified in fObjectNames list - kSkipListed = BIT(5), ///< Skip objects specified in fObjectNames list - kKeepCompression= BIT(6) ///< Keep compression level unchanged for each input files + kOnlyListed = BIT(5), ///< Only the objects specified in fObjectNames list + kSkipListed = BIT(6), ///< Skip objects specified in fObjectNames list + kKeepCompression= BIT(7) ///< Keep compression level unchanged for each input files }; TFileMerger(Bool_t isLocal = kTRUE, Bool_t histoOneGo = kTRUE); diff --git a/io/io/src/TBufferMerger.cxx b/io/io/src/TBufferMerger.cxx index c09ceae192e98f98b0bee1128ae2873b3c2272c4..6eae4df2dd5359f0986e442f7cb06ab0799f5531 100644 --- a/io/io/src/TBufferMerger.cxx +++ b/io/io/src/TBufferMerger.cxx @@ -49,6 +49,10 @@ TBufferMerger::~TBufferMerger() if (!fQueue.empty()) Merge(); + + TFile *out = fMerger.GetOutputFile(); + if (out) + out->Write("",TObject::kOverwrite); } std::shared_ptr<TBufferMergerFile> TBufferMerger::GetFile() @@ -121,7 +125,7 @@ void TBufferMerger::Merge() queue.pop(); } - fMerger.PartialMerge(); + fMerger.PartialMerge(TFileMerger::kAll | TFileMerger::kIncremental | TFileMerger::kDelayWrite); fMerger.Reset(); fMergeMutex.unlock(); } diff --git a/io/io/src/TFileMerger.cxx b/io/io/src/TFileMerger.cxx index ef201431a071507e093395f1b978defa5e9d7839..cf8e80d4f564de2fb7c382b7bcb2c834127ce975 100644 --- a/io/io/src/TFileMerger.cxx +++ b/io/io/src/TFileMerger.cxx @@ -512,6 +512,13 @@ Bool_t TFileMerger::MergeRecursive(TDirectory *target, TList *sourcelist, Int_t key->GetName(), key->GetTitle()); continue; } + Bool_t canBeFound = (type & kIncremental) && (current_sourcedir->GetList()->FindObject(key->GetName()) != nullptr); + Bool_t needWriteAnyWay = kFALSE; + if (canBeFound) { + // For now the code require a key (that might be ignored see search through current_sourcedir->GetList()) + // in the output file in order for it to be even considered. + needWriteAnyWay = target->GetListOfKeys()->FindObject(key->GetName()) == nullptr; + } // if (cl->IsTObject()) // obj->ResetBit(kMustCleanup); if (cl->IsTObject() && cl != obj->IsA()) { @@ -790,7 +797,7 @@ Bool_t TFileMerger::MergeRecursive(TDirectory *target, TList *sourcelist, Int_t } ((TCollection*)obj)->SetOwner(); delete obj; - } else { + } else if (!canBeFound) { // Don't write the partial result for TTree and TH1 // Don't overwrite, if the object were not merged. // NOTE: this is probably wrong for emulated objects. if (cl->IsTObject()) { @@ -804,6 +811,17 @@ Bool_t TFileMerger::MergeRecursive(TDirectory *target, TList *sourcelist, Int_t } } cl->Destructor(obj); // just in case the class is not loaded. + } else if (needWriteAnyWay) { + if (cl->IsTObject()) { + if ( obj->Write( oldkeyname, canBeMerged ? TObject::kOverwrite : 0) <= 0) { + status = kFALSE; + } + obj->ResetBit(kMustCleanup); + } else { + if ( target->WriteObjectAny( (void*)obj, cl, oldkeyname, canBeMerged ? "OverWrite" : "" ) <= 0) { + status = kFALSE; + } + } } info.Reset(); } // while ( ( TKey *key = (TKey*)nextkey() ) ) @@ -921,8 +939,11 @@ Bool_t TFileMerger::PartialMerge(Int_t in_type) } else { // Close or write is required so the file is complete. if (in_type & kIncremental) { - fOutputFile->Write("",TObject::kOverwrite); + if (!(in_type & kDelayWrite)) + fOutputFile->Write("",TObject::kOverwrite); } else { + if (type & kIncremental) + fOutputFile->Write("",TObject::kOverwrite); gROOT->GetListOfFiles()->Remove(fOutputFile); fOutputFile->Close(); }