diff --git a/roottest/root/tree/basket/CMakeLists.txt b/roottest/root/tree/basket/CMakeLists.txt index 961c7ad24ffc0..34d1d082309f7 100644 --- a/roottest/root/tree/basket/CMakeLists.txt +++ b/roottest/root/tree/basket/CMakeLists.txt @@ -14,5 +14,15 @@ ROOTTEST_ADD_TEST(basket # Verify that it does. ROOTTEST_ADD_TEST(corrupted_basket COPY_TO_BUILDDIR corrupted.root - COMMAND ${ROOT_root_CMD} -q -l -e "(new TFile(\"corrupted.root\"))->template Get(\"tree\")->GetEntry(0)" + COMMAND ${ROOT_root_CMD} -b -q -l -e "(new TFile(\"corrupted.root\"))->template Get(\"tree\")->GetEntry(0)" PASSREGEX "Inconsistent length for the entry offset buffer \\(4210752 events for a buffer size of 4\\)") + +ROOT_ADD_TEST(test_TBasket_Resize + COMMAND ${ROOT_root_CMD} -b -q -l ${CMAKE_CURRENT_SOURCE_DIR}/test_basket_resize.C + OUTREF basketresize.ref +) + +ROOT_ADD_TEST(test_TBasket_ReadResetBuffer + COMMAND ${ROOT_root_CMD} -b -q -l ${CMAKE_CURRENT_SOURCE_DIR}/test_basket_readreset.C + OUTREF basketreadreset.ref +) diff --git a/roottest/root/tree/basket/basketreadreset.ref b/roottest/root/tree/basket/basketreadreset.ref new file mode 100644 index 0000000000000..45abed7530b75 --- /dev/null +++ b/roottest/root/tree/basket/basketreadreset.ref @@ -0,0 +1,4 @@ +Processing test_basket_readreset.C... +Initial buffer size: 500000 +Post-reset buffer size is smaller than initial: YES +Post-reset buffer satisfies safety floor requirement: YES diff --git a/roottest/root/tree/basket/basketresize.ref b/roottest/root/tree/basket/basketresize.ref new file mode 100644 index 0000000000000..f96161d3bc315 --- /dev/null +++ b/roottest/root/tree/basket/basketresize.ref @@ -0,0 +1,2 @@ +Processing test_basket_resize.C... +Basket buffer size: 100 diff --git a/roottest/root/tree/basket/test_basket_readreset.C b/roottest/root/tree/basket/test_basket_readreset.C new file mode 100644 index 0000000000000..12b2d26115308 --- /dev/null +++ b/roottest/root/tree/basket/test_basket_readreset.C @@ -0,0 +1,61 @@ +#include "TBasket.h" +#include "TBranch.h" +#include "TBufferFile.h" +#include + +// Subclass to bypass the protected visibility of ReadResetBuffer +class TestBasket : public TBasket { +public: + TestBasket(TBranch *branch) { + fBranch = branch; + } + + void InvokeReadResetBuffer(Int_t basketnumber) { + ReadResetBuffer(basketnumber); + } + + void SetBufferForTesting(TBuffer *buf) { + fBuffer = buf; + } +}; + +void testTBasketReset() { + // Initialize mock environment + TBranch dummyBranch; + Int_t totalBaskets = 15; + dummyBranch.SetBufferEntries(totalBaskets); + + Int_t currentBasketIdx = 2; + Int_t maximumNeededInWindow = 2000; + + // Setup lookahead window metadata for the next 10 baskets + for (int i = 0; i < totalBaskets; ++i) { + if (i >= currentBasketIdx && i <= (currentBasketIdx + 10)) { + dummyBranch.GetBasketBytes()[i] = maximumNeededInWindow; + } else { + dummyBranch.GetBasketBytes()[i] = 1000; + } + } + + TestBasket basket(&dummyBranch); + + // Allocate heavily bloated buffer + Int_t massiveBufferSize = 500000; + TBufferFile* bloatedBuffer = new TBufferFile(TBuffer::kRead, massiveBufferSize); + bloatedBuffer->SetBufferOffset(massiveBufferSize); + basket.SetBufferForTesting(bloatedBuffer); + + std::cout << "Initial buffer size: " << bloatedBuffer->BufferSize() << std::endl; + + // Trigger the shrinking behavior + basket.InvokeReadResetBuffer(currentBasketIdx); + + Int_t postResetSize = bloatedBuffer->BufferSize(); + std::cout << "Post-reset buffer size is smaller than initial: " + << (postResetSize < massiveBufferSize ? "YES" : "NO") << std::endl; + + std::cout << "Post-reset buffer satisfies safety floor requirement: " + << (postResetSize >= maximumNeededInWindow ? "YES" : "NO") << std::endl; + + delete bloatedBuffer; +} diff --git a/roottest/root/tree/basket/test_basket_resize.C b/roottest/root/tree/basket/test_basket_resize.C new file mode 100644 index 0000000000000..5689c03076de8 --- /dev/null +++ b/roottest/root/tree/basket/test_basket_resize.C @@ -0,0 +1,25 @@ +#include "TTree.h" +#include "TMemFile.h" +#include "TBranch.h" +#include "TBasket.h" +#include + +void test_basket_resize() { + TMemFile f("test_resize.root", "RECREATE"); + TTree tree("T", "Tree for testing basket resizing"); + + int value; + // Set small initial basket size to force automatic buffer resizing + TBranch *branch = tree.Branch("b", &value, "value/I", 64); + for (int i = 0; i < 100; ++i) { + value = i; + tree.Fill(); + } + tree.Write(); + TBasket *basket = branch->GetBasket(0); + if (basket) { + Int_t newSize = basket->GetBufferSize(); + std::cout << "Basket buffer size: " << newSize << std::endl; + } + f.Close(); +}