diff --git a/tree/ntuple/v7/inc/ROOT/RColumn.hxx b/tree/ntuple/v7/inc/ROOT/RColumn.hxx index dc5bb471b0ca7..ee9e875f8a1c7 100644 --- a/tree/ntuple/v7/inc/ROOT/RColumn.hxx +++ b/tree/ntuple/v7/inc/ROOT/RColumn.hxx @@ -75,11 +75,11 @@ private: NTupleSize_t fFirstElementIndex = 0; /// Used to pack and unpack pages on writing/reading std::unique_ptr fElement; - /// The column team is a set of columns that serve the same column index for different representation IDs - /// Initially, the team has only one member, the very column it belongs to. Through MergeTeams(), two column + /// The column team is a set of columns that serve the same column index for different representation IDs. + /// Initially, the team has only one member, the very column it belongs to. Through MergeTeams(), two columns /// can join forces. The team is used to react on suppressed columns: if the current team member has a suppressed /// column for a MapPage() call, it get the page from the active column in the corresponding cluster. - std::shared_ptr> fTeam; + std::vector fTeam; /// Points into fTeam to the column that successfully returned the last page. std::size_t fLastGoodTeamIdx = 0; @@ -117,8 +117,6 @@ private: fWritePage[otherIdx].Reset(0); } - void TeamUp(const RColumn &other) { fTeam = other.fTeam; } - public: template static std::unique_ptr Create(EColumnType type, std::uint32_t columnIdx, std::uint16_t representationIdx) diff --git a/tree/ntuple/v7/src/RColumn.cxx b/tree/ntuple/v7/src/RColumn.cxx index b547c8b9b4f61..ffbd736d11bd6 100644 --- a/tree/ntuple/v7/src/RColumn.cxx +++ b/tree/ntuple/v7/src/RColumn.cxx @@ -19,15 +19,13 @@ #include +#include #include #include ROOT::Experimental::Internal::RColumn::RColumn(EColumnType type, std::uint32_t columnIndex, std::uint16_t representationIndex) - : fType(type), - fIndex(columnIndex), - fRepresentationIndex(representationIndex), - fTeam(std::make_shared>(std::vector{this})) + : fType(type), fIndex(columnIndex), fRepresentationIndex(representationIndex), fTeam({this}) { // TODO(jblomer): fix for column types with configurable bit length once available const auto [minBits, maxBits] = RColumnElementBase::GetValidBitRange(type); @@ -115,10 +113,10 @@ bool ROOT::Experimental::Internal::RColumn::TryMapPage(NTupleSize_t globalIndex) // the page population fails. fReadPage = RPage(); - const auto nTeam = fTeam->size(); + const auto nTeam = fTeam.size(); std::size_t iTeam = 1; do { - fReadPage = fPageSource->PopulatePage(fTeam->at(fLastGoodTeamIdx)->GetHandleSource(), globalIndex); + fReadPage = fPageSource->PopulatePage(fTeam.at(fLastGoodTeamIdx)->GetHandleSource(), globalIndex); if (fReadPage.IsValid()) break; fLastGoodTeamIdx = (fLastGoodTeamIdx + 1) % nTeam; @@ -135,10 +133,10 @@ bool ROOT::Experimental::Internal::RColumn::TryMapPage(RClusterIndex clusterInde // the page population fails. fReadPage = RPage(); - const auto nTeam = fTeam->size(); + const auto nTeam = fTeam.size(); std::size_t iTeam = 1; do { - fReadPage = fPageSource->PopulatePage(fTeam->at(fLastGoodTeamIdx)->GetHandleSource(), clusterIndex); + fReadPage = fPageSource->PopulatePage(fTeam.at(fLastGoodTeamIdx)->GetHandleSource(), clusterIndex); if (fReadPage.IsValid()) break; fLastGoodTeamIdx = (fLastGoodTeamIdx + 1) % nTeam; @@ -150,6 +148,15 @@ bool ROOT::Experimental::Internal::RColumn::TryMapPage(RClusterIndex clusterInde void ROOT::Experimental::Internal::RColumn::MergeTeams(RColumn &other) { - fTeam->emplace_back(&other); - other.TeamUp(*this); + // We are working on very small vectors here, so quadratic complexity works + for (auto *c : other.fTeam) { + if (std::find(fTeam.begin(), fTeam.end(), c) == fTeam.end()) + fTeam.emplace_back(c); + } + + for (auto c : fTeam) { + if (c == this) + continue; + c->fTeam = fTeam; + } }