-
Notifications
You must be signed in to change notification settings - Fork 1.4k
[cont] Clear "C" TClonesArray: Remove object from TProcessID-table ; Allow removing without destructing #18439
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
ferdymercury
wants to merge
13
commits into
root-project:master
Choose a base branch
from
ferdymercury:clearc
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
ced4058
[cont] Clear "C" TClonesArray: Remove object from TProcessID-table
ferdymercury 9ac9723
[cont] declare new clearslot function
ferdymercury b778609
[cont] try to fix test failures
ferdymercury 118d9e2
[cont] Apriori we want the expansive part of the operation (Compress)…
ferdymercury f8fd22b
[test] implement tests for ClearSlot and RefArray clear
ferdymercury c8b5dd2
[nfc] clang-format and compiler error fixes
ferdymercury 195634d
[nfc] fix more clangf and warnings
ferdymercury 6373748
[nfc] clangformat and dependency fix
ferdymercury 63c7edf
[test] move to tree folder
ferdymercury 2d728f7
[test] fix dictionary generation
ferdymercury e6ba89c
[nfc] try fix dict generation
ferdymercury f712fe9
[nfc] clangf
ferdymercury b952a63
Apply suggestion from @ferdymercury
ferdymercury File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| #include "TestRefObj.h" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| #ifndef TESTREFOBJ_H | ||
| #define TESTREFOBJ_H | ||
|
|
||
| #include "TRef.h" | ||
| #include "TRefArray.h" | ||
|
|
||
| // https://its.cern.ch/jira/browse/ROOT-7249 | ||
| class TestRefObj : public TObject { | ||
| protected: | ||
| TRefArray lChildren; | ||
|
|
||
| public: | ||
| TestRefObj() : lChildren() {} | ||
| virtual ~TestRefObj() {} | ||
| virtual void Clear(Option_t *opt = "C") { lChildren.Clear(opt); } | ||
|
Check failure on line 15 in tree/tree/test/TestRefObj.h
|
||
| virtual void SetChild(TestRefObj *aChild) { lChildren.Add(aChild); } | ||
| virtual const TestRefObj *GetChild(Int_t idx = 0) const { return static_cast<TestRefObj *>(lChildren.At(idx)); } | ||
| virtual Bool_t HasChild() const { return (lChildren.GetEntriesFast() > 0); } | ||
| ClassDef(TestRefObj, 1); | ||
| }; | ||
|
|
||
| #endif | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| #ifdef __CLING__ | ||
|
|
||
| #pragma link off all globals; | ||
| #pragma link off all classes; | ||
| #pragma link off all functions; | ||
|
|
||
| #pragma link C++ class TestRefObj+; | ||
|
|
||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| #include "TObject.h" | ||
| #include "TestRefObj.h" | ||
| #include "TFile.h" | ||
| #include "TTree.h" | ||
| #include "TRandom.h" | ||
| #include "TClonesArray.h" | ||
| #include "TProcessID.h" | ||
| #include "TSystem.h" | ||
|
|
||
| #include "gtest/gtest.h" | ||
|
|
||
| // https://its.cern.ch/jira/browse/ROOT-7249 | ||
| TEST(TClonesArray, RefArrayClearChildren) | ||
| { | ||
| Bool_t resetObjectCount = kTRUE; | ||
| Bool_t activateBranchRef = kFALSE; | ||
| Int_t splitLevel = 1; | ||
| Bool_t pruneSecondChildren = kTRUE; | ||
| auto filename = "test7249.root"; | ||
| auto treename = "tree"; | ||
| // streamwithrefs | ||
| { | ||
| TFile testFile(filename, "RECREATE"); | ||
| TTree dataTree(treename, treename); | ||
|
|
||
| TClonesArray particles(TestRefObj::Class(), 100); | ||
| TClonesArray children(TestRefObj::Class(), 100); | ||
|
|
||
| dataTree.Branch("particles", &particles, 32768, splitLevel); | ||
| dataTree.Branch("children", &children, 32768, splitLevel); | ||
| if (activateBranchRef) { | ||
| dataTree.BranchRef(); | ||
| } | ||
|
|
||
| for (Int_t e = 0; e < 1000; e++) { | ||
| // For each "event". | ||
| UInt_t objCount = TProcessID::GetObjectCount(); | ||
|
|
||
| TestRefObj *motherPart = static_cast<TestRefObj *>(particles.ConstructedAt(0)); | ||
| TestRefObj *childPart = static_cast<TestRefObj *>(children.ConstructedAt(0)); | ||
| motherPart->SetChild(childPart); | ||
|
|
||
| // Prune all children if requested and event odd. | ||
| if (pruneSecondChildren && (e % 2 != 0)) { | ||
| children.Clear("C"); | ||
| } | ||
|
|
||
| dataTree.Fill(); | ||
|
|
||
| children.Clear("C"); | ||
| particles.Clear("C"); | ||
|
|
||
| if (resetObjectCount) { | ||
| TProcessID::SetObjectCount(objCount); | ||
| } | ||
| } | ||
| dataTree.Write(); | ||
| testFile.Close(); | ||
| } | ||
| // readwithrefs | ||
| { | ||
| TFile testFile(filename, "READ"); | ||
| TTree *dataTree = testFile.Get<TTree>(treename); | ||
|
|
||
| TClonesArray *particles = nullptr; | ||
| TClonesArray *children = nullptr; | ||
|
|
||
| dataTree->SetBranchAddress("particles", &particles); | ||
| dataTree->SetBranchAddress("children", &children); | ||
|
|
||
| if (activateBranchRef) { | ||
| dataTree->BranchRef(); | ||
| } | ||
| const Long64_t entries = dataTree->GetEntriesFast(); | ||
| for (Long64_t e = 0; e < entries; e++) { | ||
| dataTree->GetEntry(e); | ||
|
|
||
| // For each "event". | ||
| UInt_t objCount = TProcessID::GetObjectCount(); | ||
|
|
||
| // UInt_t parts = particles->GetEntries(); | ||
| UInt_t childs = children->GetEntries(); | ||
|
|
||
| auto parti = static_cast<TestRefObj *>(particles->UncheckedAt(0)); | ||
| if (pruneSecondChildren && (e % 2 != 0)) { | ||
| ASSERT_EQ(childs, 0); | ||
| ASSERT_FALSE(parti->HasChild()); | ||
| } else { | ||
| ASSERT_NE(childs, 0); | ||
| ASSERT_TRUE(parti->HasChild()); | ||
| } | ||
|
|
||
| children->Clear("C"); | ||
| particles->Clear("C"); | ||
|
|
||
| if (resetObjectCount) { | ||
| TProcessID::SetObjectCount(objCount); | ||
| } | ||
| } | ||
|
|
||
| delete dataTree; | ||
| testFile.Close(); | ||
| } | ||
| gSystem->Unlink(filename); | ||
| } | ||
|
|
||
| // https://its.cern.ch/jira/browse/ROOT-7473 | ||
| TEST(TClonesArray, ClearSlot) | ||
| { | ||
| TClonesArray particles(TestRefObj::Class(), 100); | ||
| TClonesArray children(TestRefObj::Class(), 100); | ||
| TestRefObj *motherPart = static_cast<TestRefObj *>(particles.ConstructedAt(0)); | ||
| TestRefObj *childPart = static_cast<TestRefObj *>(children.ConstructedAt(0)); | ||
| motherPart->SetChild(childPart); | ||
| particles.ClearSlot(0, "C"); | ||
| auto parti = static_cast<TestRefObj *>(particles.UncheckedAt(0)); | ||
| ASSERT_EQ(parti, nullptr); | ||
| auto child = static_cast<TestRefObj *>(children.UncheckedAt(0)); | ||
| ASSERT_NE(child, nullptr); | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@olifre could you explain at this line how your "second workaround" was working? I guess that, before calling dataTree.Fill(), you were walking in a for-loop the motherPart.GetChild() checking whether the stored process ID still existed in the static TProcess table ?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ferdymercury Actually, since this was in an experiment-specific framework and I did not trust all users to do it right, I chose the following approach:
TRefandTRefArray.TRefArray:(and the same without loop for
TRef).So in the end, it was the loop you described, but actually the
TRefclasses themselves were checking their reference targets and in case these had becomenullptrthey adapted their internally stored UID before writeout.I'm not sure this can realistically be put into the Streamers, as the reference target may have been written out and deleted from memory already, which is why I used a "user hook before writeout" to trigger this check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
A bit related issue: https://its.cern.ch/jira/browse/ROOT-6077