From e11df293fbfd0619a130e1c484a3e6896f6654e2 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Thu, 28 May 2026 21:46:37 +0200 Subject: [PATCH] DPL Analysis: use unsafe cursor when reserving There is no point in using the slow boundary checking / buffer resizing cursor when we reserve, since it's reasonable to expect that the memory will be there. --- .../Core/include/Framework/AnalysisHelpers.h | 3 +++ .../Core/include/Framework/TableBuilder.h | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/Framework/Core/include/Framework/AnalysisHelpers.h b/Framework/Core/include/Framework/AnalysisHelpers.h index cfd2f357ba06f..01d73e729206b 100644 --- a/Framework/Core/include/Framework/AnalysisHelpers.h +++ b/Framework/Core/include/Framework/AnalysisHelpers.h @@ -513,9 +513,12 @@ struct WritingCursor { /// reserve @a size rows when filling, so that we do not /// spend time reallocating the buffers. + /// Switches the internal cursor to UnsafeAppend (no capacity check), + /// which is safe because we just reserved enough space. void reserve(int64_t size) { mBuilder->reserve(typename persistent_table_t::column_types{}, size); + cursor = std::move(FFL(mBuilder->template unsafeCursor())); } void release() diff --git a/Framework/Core/include/Framework/TableBuilder.h b/Framework/Core/include/Framework/TableBuilder.h index 845820dfe4bff..41f6d4ea5dc86 100644 --- a/Framework/Core/include/Framework/TableBuilder.h +++ b/Framework/Core/include/Framework/TableBuilder.h @@ -715,6 +715,18 @@ class TableBuilder }; } + /// Same as persist, but uses UnsafeAppend (no capacity check). + /// Only safe after reserve() has been called with the correct size. + template + requires(sizeof...(ARGS) > 0) || ShouldNotDeconstruct + auto unsafePersist() + { + using FillTuple = std::tuple::FillType, typename BuilderMaker::FillType...>; + return [holders = mHolders](unsigned int /*slot*/, typename BuilderMaker::FillType arg, typename BuilderMaker::FillType... args) -> void { + TableBuilderHelpers::unsafeAppend(*(HoldersTupleIndexed*)holders, std::forward_as_tuple(arg, args...)); + }; + } + // Same as above, but starting from a o2::soa::Table, which has all the // information already available. template @@ -725,6 +737,15 @@ class TableBuilder }(typename T::table_t::persistent_columns_t{}); } + /// Same as cursor(), but uses UnsafeAppend. Only safe after reserve(). + template + auto unsafeCursor() + { + return [this](pack) { + return this->template unsafePersist(); + }(typename T::table_t::persistent_columns_t{}); + } + template auto cursor(framework::pack) {