Skip to content

Commit 2e35557

Browse files
committed
Add support for Bulk I/O with SetClusterPrefetch
This fixes #8962 The code pattern is similar to 0987896 Add infrastructure for sharing memory in a TBuffer.
1 parent 13d8c8a commit 2e35557

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

tree/tree/inc/TBranch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ class TBranch : public TNamed, public TAttFill {
167167
void Init(const char *name, const char *leaflist, Int_t compress);
168168

169169
TBasket *GetFreshBasket(Int_t basketnumber, TBuffer *user_buffer);
170-
TBasket *GetFreshCluster();
170+
TBasket *GetFreshCluster(TBuffer *user_buffer);
171171
Int_t WriteBasket(TBasket* basket, Int_t where) { return WriteBasketImpl(basket, where, nullptr); }
172172

173173
TString GetRealFileName() const;

tree/tree/src/TBranch.cxx

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,7 +1243,7 @@ TBasket* TBranch::GetBasketImpl(Int_t basketnumber, TBuffer *user_buffer)
12431243
// if cluster pre-fetching or retaining is on, do not re-use existing baskets
12441244
// unless a new cluster is used.
12451245
if (fTree->GetMaxVirtualSize() < 0 || fTree->GetClusterPrefetch())
1246-
basket = GetFreshCluster();
1246+
basket = GetFreshCluster(user_buffer);
12471247
else
12481248
basket = GetFreshBasket(basketnumber, user_buffer);
12491249

@@ -1888,23 +1888,36 @@ TBasket* TBranch::GetFreshBasket(Int_t basketnumber, TBuffer* user_buffer)
18881888
/// Drops the cluster two behind the current cluster and returns a fresh basket
18891889
/// by either reusing or creating a new one
18901890

1891-
TBasket *TBranch::GetFreshCluster()
1891+
TBasket *TBranch::GetFreshCluster(TBuffer* user_buffer)
18921892
{
18931893
TBasket *basket = 0;
18941894

1895+
auto CreateOrReuseBasket = [this, user_buffer]() -> TBasket* {
1896+
TBasket *newbasket = nullptr;
1897+
if (fExtraBasket) {
1898+
newbasket = fExtraBasket;
1899+
fExtraBasket = nullptr;
1900+
} else {
1901+
newbasket = fTree->CreateBasket(this);
1902+
}
1903+
if (user_buffer)
1904+
newbasket->AdoptBuffer(user_buffer);
1905+
return newbasket;
1906+
};
1907+
18951908
// If GetClusterIterator is called with a negative entry then GetStartEntry will be 0
18961909
// So we need to check if we reach the zero before we have gone back (1-VirtualSize) clusters
18971910
// if this is the case, we want to keep everything in memory so we return a new basket
18981911
TTree::TClusterIterator iter = fTree->GetClusterIterator(fBasketEntry[fReadBasket]);
18991912
if (iter.GetStartEntry() == 0) {
1900-
return fTree->CreateBasket(this);
1913+
return CreateOrReuseBasket();
19011914
}
19021915

19031916
// Iterate backwards (1-VirtualSize) clusters to reach cluster to be unloaded from memory,
19041917
// skipped if VirtualSize > 0.
19051918
for (Int_t j = 0; j < -fTree->GetMaxVirtualSize(); j++) {
19061919
if (iter.Previous() == 0) {
1907-
return fTree->CreateBasket(this);
1920+
return CreateOrReuseBasket();
19081921
}
19091922
}
19101923

@@ -1916,7 +1929,7 @@ TBasket *TBranch::GetFreshCluster()
19161929
while (fBasketEntry[basketToUnload] != entryToUnload) {
19171930
basketToUnload--;
19181931
if (basketToUnload < 0) {
1919-
return fTree->CreateBasket(this);
1932+
return CreateOrReuseBasket();
19201933
}
19211934
}
19221935

@@ -1927,7 +1940,7 @@ TBasket *TBranch::GetFreshCluster()
19271940
fBaskets.AddAt(0, basketToUnload);
19281941
--fNBaskets;
19291942
} else {
1930-
basket = fTree->CreateBasket(this);
1943+
basket = CreateOrReuseBasket();
19311944
}
19321945
++basketToUnload;
19331946

0 commit comments

Comments
 (0)