Project
Loading...
Searching...
No Matches
AnalysisHelpers.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#ifndef o2_framework_AnalysisHelpers_H_DEFINED
12#define o2_framework_AnalysisHelpers_H_DEFINED
13
14#include "ConfigParamSpec.h"
15#include "Framework/ASoA.h"
18#include "Framework/InputSpec.h"
19#include "Framework/Logger.h"
21#include "Framework/OutputRef.h"
23#include "Framework/Plugins.h"
26#include "Framework/Traits.h"
27
28#include <fmt/format.h>
29#include <string>
30namespace o2::framework
31{
36struct InputInfo {
37 uint32_t hash;
38 std::vector<std::pair<int, ConcreteDataMatcher>> matchers;
39};
40} // namespace o2::framework
41
42namespace o2::soa
43{
45 std::string label;
47 std::string columnLabel;
49 int pos;
50 std::shared_ptr<arrow::DataType> type = [](IndexKind kind) -> std::shared_ptr<arrow::DataType> {
51 switch (kind) {
54 return arrow::int32();
56 return arrow::fixed_size_list(arrow::int32(), 2);
58 return arrow::list(arrow::int32());
59 default:
60 return {nullptr};
61 }
62 }(kind);
63
64 auto operator==(IndexRecord const& other) const
65 {
66 return (this->label == other.label) && (this->columnLabel == other.columnLabel) && (this->kind == other.kind) && (this->pos == other.pos);
67 }
68
69 std::shared_ptr<arrow::Field> field() const
70 {
71 return std::make_shared<arrow::Field>(columnLabel, type);
72 }
73};
74
76 static std::vector<framework::IndexColumnBuilder> makeBuilders(std::vector<std::shared_ptr<arrow::Table>>&& tables, std::vector<soa::IndexRecord> const& records);
77 static void resetBuilders(std::vector<framework::IndexColumnBuilder>& builders, std::vector<std::shared_ptr<arrow::Table>>&& tables);
78
79 static std::shared_ptr<arrow::Table> materialize(std::vector<framework::IndexColumnBuilder>& builders, std::vector<std::shared_ptr<arrow::Table>>&& tables, std::vector<soa::IndexRecord> const& records, std::shared_ptr<arrow::Schema> const& schema, bool exclusive);
80};
81} // namespace o2::soa
82
83namespace o2::framework
84{
85void wrongOriginReplacement(std::string_view replacement);
86std::shared_ptr<arrow::Table> makeEmptyTableImpl(const char* name, std::shared_ptr<arrow::Schema>& schema);
87
88template <soa::is_table T>
89auto makeEmptyTable(const char* name)
90{
91 auto schema = std::make_shared<arrow::Schema>(soa::createFieldsFromColumns(typename T::table_t::persistent_columns_t{}));
93}
94
95template <soa::TableRef R>
96 requires(soa::not_void<typename aod::MetadataTrait<aod::Hash<R.desc_hash>>::metadata>)
98{
99 auto schema = std::make_shared<arrow::Schema>(soa::createFieldsFromColumns(typename aod::MetadataTrait<aod::Hash<R.desc_hash>>::metadata::persistent_columns_t{}));
100 return makeEmptyTableImpl(o2::aod::label<R>(), schema);
101}
102
103template <typename... Cs>
105{
106 auto schema = std::make_shared<arrow::Schema>(soa::createFieldsFromColumns(p));
108}
109
110template <aod::is_aod_hash D>
112auto makeEmptyTable(const char* name)
113{
114 auto schema = std::make_shared<arrow::Schema>(soa::createFieldsFromColumns(typename aod::MetadataTrait<D>::metadata::persistent_columns_t{}));
116}
117
118std::shared_ptr<arrow::Table> spawnerHelper(std::shared_ptr<arrow::Table> const& fullTable, std::shared_ptr<arrow::Schema> newSchema, size_t nColumns,
119 expressions::Projector* projectors, const char* name, std::shared_ptr<gandiva::Projector>& projector);
120
121std::shared_ptr<arrow::Table> spawnerHelper(std::shared_ptr<arrow::Table> const& fullTable, std::shared_ptr<arrow::Schema> newSchema,
122 const char* name, size_t nColumns,
123 const std::shared_ptr<gandiva::Projector>& projector);
124
126template <aod::is_aod_hash D>
128auto spawner(std::shared_ptr<arrow::Table> const& fullTable, const char* name, o2::framework::expressions::Projector* projectors, std::shared_ptr<gandiva::Projector>& projector, std::shared_ptr<arrow::Schema> const& schema)
129{
130 if (fullTable->num_rows() == 0) {
131 return makeEmptyTable<D>(name);
132 }
133 constexpr auto Ncol = []<typename M>() {
135 return framework::pack_size(typename M::placeholders_pack_t{});
136 } else {
137 return framework::pack_size(typename M::expression_pack_t{});
138 }
139 }.template operator()<typename o2::aod::MetadataTrait<D>::metadata>();
140 return spawnerHelper(fullTable, schema, Ncol, projectors, name, projector);
141}
142
143template <typename... C>
144auto spawner(framework::pack<C...>, std::vector<std::shared_ptr<arrow::Table>>&& tables, const char* name, expressions::Projector* projectors, std::shared_ptr<gandiva::Projector>& projector, std::shared_ptr<arrow::Schema> const& schema)
145{
146 std::array<const char*, 1> labels{"original"};
147 auto fullTable = soa::ArrowHelpers::joinTables(std::move(tables), std::span<const char* const>{labels});
148 if (fullTable->num_rows() == 0) {
150 }
151 return spawnerHelper(fullTable.tablePtr, schema, sizeof...(C), projectors, name, projector);
152}
153
154std::string serializeProjectors(std::vector<framework::expressions::Projector>& projectors);
155std::string serializeSchema(std::shared_ptr<arrow::Schema> schema);
156std::string serializeIndexRecords(std::vector<o2::soa::IndexRecord>& irs);
157std::vector<std::shared_ptr<arrow::Table>> extractSources(ProcessingContext& pc, std::vector<std::string> const& labels);
158
159struct Spawner {
160 std::string binding;
161 std::vector<std::string> labels;
162 std::vector<framework::ConcreteDataMatcher> matchers;
163 std::vector<std::shared_ptr<gandiva::Expression>> expressions;
164 std::shared_ptr<gandiva::Projector> projector = nullptr;
165 std::shared_ptr<arrow::Schema> schema = nullptr;
166 std::shared_ptr<arrow::Schema> inputSchema = nullptr;
167
171
172 std::shared_ptr<arrow::Table> materialize(ProcessingContext& pc) const;
173};
174
175struct Builder {
177 std::vector<std::string> labels;
178 std::vector<framework::ConcreteDataMatcher> matchers;
179 std::vector<o2::soa::IndexRecord> records;
180 std::shared_ptr<arrow::Schema> outputSchema;
184
185 std::shared_ptr<std::vector<framework::IndexColumnBuilder>> builders = nullptr;
186
187 std::shared_ptr<arrow::Table> materialize(ProcessingContext& pc);
188};
189
190ConfigParamSpec replaceOrigin(ConfigParamSpec& source, std::string const& originStr);
192} // namespace o2::framework
193
194namespace o2::soa
195{
196// fmt::format, not std::string + const char*: GCC 14 turns the latter into a
197// spurious -Werror=array-bounds= on the temporary's SSO buffer.
198template <TableRef R>
200{
202 fmt::format("input:{}", o2::aod::label<R>()),
204 aod::sourceSpec<R>(),
205 {"\"\""}};
206}
207
208template <TableRef R>
209constexpr auto tableRef2Schema()
210{
212 fmt::format("input-schema:{}", o2::aod::label<R>()),
215 {"\"\""}};
216}
217
218namespace
219{
220template <soa::with_sources T>
221inline constexpr auto getSources()
222{
223 return []<size_t N, std::array<soa::TableRef, N> refs>() {
224 return []<size_t... Is>(std::index_sequence<Is...>) {
225 return std::vector{soa::tableRef2ConfigParamSpec<refs[Is]>()...};
226 }(std::make_index_sequence<N>());
227 }.template operator()<T::sources.size(), T::sources>();
228}
229
230template <soa::with_sources T>
231inline constexpr auto getSourceSchemas()
232{
233 return []<size_t N, std::array<soa::TableRef, N> refs>() {
234 return []<size_t... Is>(std::index_sequence<Is...>) {
235 return std::vector{soa::tableRef2Schema<refs[Is]>()...};
236 }(std::make_index_sequence<N>());
237 }.template operator()<T::sources.size(), T::sources>();
238}
239
240template <soa::with_sources_generator T, aod::is_origin_hash O = o2::aod::Hash<"AOD"_h>>
241inline constexpr auto getSources()
242{
243 return []<size_t N, std::array<soa::TableRef, N> refs>() {
244 return []<size_t... Is>(std::index_sequence<Is...>) {
245 return std::vector{soa::tableRef2ConfigParamSpec<refs[Is]>()...};
246 }(std::make_index_sequence<N>());
247 }.template operator()<T::N, T::template generateSources<O>()>();
248}
249
250template <soa::with_sources_generator T, aod::is_origin_hash O = o2::aod::Hash<"AOD"_h>>
251inline constexpr auto getSourceSchemas()
252{
253 return []<size_t N, std::array<soa::TableRef, N> refs>() {
254 return []<size_t... Is>(std::index_sequence<Is...>) {
255 return std::vector{soa::tableRef2Schema<refs[Is]>()...};
256 }(std::make_index_sequence<N>());
257 }.template operator()<T::N, T::template generateSources<O>()>();
258}
259
260template <soa::with_ccdb_urls T>
261inline constexpr auto getCCDBUrls()
262{
263 std::vector<framework::ConfigParamSpec> result;
264 for (size_t i = 0; i < T::ccdb_urls.size(); ++i) {
265 result.push_back({std::string{"ccdb:"} + std::string{T::ccdb_bindings[i]},
267 T::ccdb_urls[i],
268 {"\"\""}});
269 }
270 return result;
271}
272
273template <typename T>
274 requires(std::same_as<T, int>)
275consteval IndexKind getIndexKind()
276{
278}
279
280template <typename T>
281 requires(std::is_bounded_array_v<T>)
282consteval IndexKind getIndexKind()
283{
284 return IndexKind::IdxSlice;
285}
286
287template <typename T>
288 requires(framework::is_specialization_v<T, std::vector>)
289consteval IndexKind getIndexKind()
290{
291 return IndexKind::IdxArray;
292}
293
294template <soa::with_index_pack T>
295inline constexpr auto getIndexMapping(header::DataOrigin newOrigin = header::DataOrigin{"AOD"})
296{
297 std::vector<IndexRecord> idx;
298 using indices = T::index_pack_t;
299 using Key = T::Key;
300 [&idx, &newOrigin]<size_t... Is>(std::index_sequence<Is...>) mutable {
301 constexpr auto refs = T::generateSources();
302 ([&idx, &newOrigin]<TableRef ref, typename C>() mutable {
303 constexpr auto pos = o2::aod::MetadataTrait<o2::aod::Hash<ref.desc_hash>>::metadata::template getIndexPosToKey<Key>();
304 auto matcher = o2::aod::matcher<ref>();
305 if ((ref.origin_hash == "AOD"_h) && (newOrigin != header::DataOrigin{"AOD"})) {
306 matcher = replaceOrigin(matcher, newOrigin);
307 }
308 if constexpr (pos == -1) {
309 idx.emplace_back(o2::aod::label<ref>(), matcher, C::columnLabel(), IndexKind::IdxSelf, pos);
310 } else {
311 idx.emplace_back(o2::aod::label<ref>(), matcher, C::columnLabel(), getIndexKind<typename C::type>(), pos);
312 }
313 }.template operator()<refs[Is], typename framework::pack_element_t<Is, indices>>(),
314 ...);
315 }(std::make_index_sequence<framework::pack_size(indices{})>());
316 ;
317 return idx;
318}
319
320template <soa::with_sources_generator T, aod::is_origin_hash O = o2::aod::Hash<"AOD"_h>>
321constexpr auto getInputMetadata() -> std::vector<framework::ConfigParamSpec>
322{
323 std::vector<framework::ConfigParamSpec> inputMetadata;
324
325 auto inputSources = getSources<T, O>();
326 std::sort(inputSources.begin(), inputSources.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name < b.name; });
327 auto last = std::unique(inputSources.begin(), inputSources.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name == b.name; });
328 inputSources.erase(last, inputSources.end());
329 inputMetadata.insert(inputMetadata.end(), inputSources.begin(), inputSources.end());
330
331 auto inputSchemas = getSourceSchemas<T, O>();
332 std::sort(inputSchemas.begin(), inputSchemas.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name < b.name; });
333 last = std::unique(inputSchemas.begin(), inputSchemas.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name == b.name; });
334 inputSchemas.erase(last, inputSchemas.end());
335 inputMetadata.insert(inputMetadata.end(), inputSchemas.begin(), inputSchemas.end());
336
337 return inputMetadata;
338}
339
340template <soa::with_sources T>
341constexpr auto getInputMetadata() -> std::vector<framework::ConfigParamSpec>
342{
343 std::vector<framework::ConfigParamSpec> inputMetadata;
344
345 auto inputSources = getSources<T>();
346 std::sort(inputSources.begin(), inputSources.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name < b.name; });
347 auto last = std::unique(inputSources.begin(), inputSources.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name == b.name; });
348 inputSources.erase(last, inputSources.end());
349 inputMetadata.insert(inputMetadata.end(), inputSources.begin(), inputSources.end());
350
351 auto inputSchemas = getSourceSchemas<T>();
352 std::sort(inputSchemas.begin(), inputSchemas.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name < b.name; });
353 last = std::unique(inputSchemas.begin(), inputSchemas.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name == b.name; });
354 inputSchemas.erase(last, inputSchemas.end());
355 inputMetadata.insert(inputMetadata.end(), inputSchemas.begin(), inputSchemas.end());
356
357 return inputMetadata;
358}
359
360template <typename T>
361 requires(!(soa::with_sources<T> || soa::with_sources_generator<T>))
362constexpr auto getInputMetadata() -> std::vector<framework::ConfigParamSpec>
363{
364 return {};
365}
366
367template <soa::with_ccdb_urls T>
368constexpr auto getCCDBMetadata() -> std::vector<framework::ConfigParamSpec>
369{
370 std::vector<framework::ConfigParamSpec> results = getCCDBUrls<T>();
371 std::sort(results.begin(), results.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name < b.name; });
372 auto last = std::unique(results.begin(), results.end(), [](framework::ConfigParamSpec const& a, framework::ConfigParamSpec const& b) { return a.name == b.name; });
373 results.erase(last, results.end());
374 // Tell the fetcher which column carries the timestamp to query at, and which column
375 // it may group by (rows sharing a uniformity value resolve to the same object, so one
376 // query per distinct value suffices). Both default to the timestamp column.
377 results.push_back({std::string{"timestamp-column"}, framework::VariantType::String, std::string{T::timestamp_column_label}, {"\"\""}});
378 results.push_back({std::string{"uniformity-column"}, framework::VariantType::String, std::string{T::uniformity_column_label}, {"\"\""}});
379 return results;
380}
381
382template <typename T>
383constexpr auto getCCDBMetadata() -> std::vector<framework::ConfigParamSpec>
384{
385 return {};
386}
387
388template <soa::with_expression_pack T>
389constexpr auto getExpressionMetadata() -> std::vector<framework::ConfigParamSpec>
390{
391 using expression_pack_t = T::expression_pack_t;
392
393 auto projectors = []<typename... C>(framework::pack<C...>) -> std::vector<framework::expressions::Projector> {
394 std::vector<framework::expressions::Projector> result;
395 (result.emplace_back(std::move(C::Projector())), ...);
396 return result;
397 }(expression_pack_t{});
398
400 return {framework::ConfigParamSpec{"projectors", framework::VariantType::String, json, {"\"\""}}};
401}
402
403template <typename T>
404 requires(!soa::with_expression_pack<T>)
405constexpr auto getExpressionMetadata() -> std::vector<framework::ConfigParamSpec>
406{
407 return {};
408}
409
410template <soa::with_index_pack T>
411constexpr auto getIndexMetadata(header::DataOrigin newOrigin = header::DataOrigin{"AOD"}) -> std::vector<framework::ConfigParamSpec>
412{
413 auto map = getIndexMapping<T>(newOrigin);
414 return {framework::ConfigParamSpec{"index-records", framework::VariantType::String, framework::serializeIndexRecords(map), {"\"\""}},
415 {framework::ConfigParamSpec{"index-exclusive", framework::VariantType::Bool, T::exclusive, {"\"\""}}}};
416}
417
418template <typename T>
419 requires(!soa::with_index_pack<T>)
420constexpr auto getIndexMetadata(header::DataOrigin) -> std::vector<framework::ConfigParamSpec>
421{
422 return {};
423}
424
425} // namespace
426
427template <TableRef R>
429{
430 std::vector<framework::ConfigParamSpec> metadata;
431 std::vector<framework::ConfigParamSpec> sources;
432 if constexpr (soa::with_sources<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>) {
433 sources = getInputMetadata<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>();
434 } else if constexpr (soa::with_sources_generator<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>) {
435 sources = getInputMetadata<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata, o2::aod::Hash<R.origin_hash>>();
436 }
437 if ((R.origin_hash == "AOD"_h) && (newOrigin != header::DataOrigin{"AOD"})) {
438 std::ranges::transform(sources, sources.begin(), [originStr = newOrigin.as<std::string>()](framework::ConfigParamSpec& source) {
439 return replaceOrigin(source, originStr);
440 });
441 metadata.emplace_back(framework::ConfigParamSpec{"aod-origin-replaced", framework::VariantType::Bool, true, {"\"\""}});
442 }
443 metadata.insert(metadata.end(), sources.begin(), sources.end());
444 auto ccdbURLs = getCCDBMetadata<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>();
445 metadata.insert(metadata.end(), ccdbURLs.begin(), ccdbURLs.end());
446 auto expressions = getExpressionMetadata<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>();
447 metadata.insert(metadata.end(), expressions.begin(), expressions.end());
448 auto indices = getIndexMetadata<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>(newOrigin);
449 metadata.insert(metadata.end(), indices.begin(), indices.end());
450 if constexpr (!soa::with_ccdb_urls<typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata>) {
451 metadata.emplace_back(framework::ConfigParamSpec{"schema", framework::VariantType::String, framework::serializeSchema(o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata::getSchema()), {"\"\""}});
452 }
453
454 return framework::InputSpec{
455 o2::aod::label<R>(),
456 ((R.origin_hash == "AOD"_h) && (newOrigin != header::DataOrigin{"AOD"})) ? newOrigin : o2::aod::origin<R>(),
457 o2::aod::description(o2::aod::signature<R>()),
458 R.version,
459 framework::Lifetime::Timeframe,
460 metadata};
461}
462
463template <TableRef R>
465{
466 std::vector<framework::ConfigParamSpec> metadata;
467 using md = typename o2::aod::MetadataTrait<o2::aod::Hash<R.desc_hash>>::metadata;
468 if constexpr (soa::with_ccdb_urls<md>) {
469 metadata.emplace_back("ccdb:", framework::VariantType::Bool, true, framework::ConfigParamSpec::HelpString{"\"\""});
470 } else if constexpr (soa::with_expression_pack<md>) {
471 metadata.emplace_back("projectors", framework::VariantType::Bool, true, framework::ConfigParamSpec::HelpString{"\"\""});
472 } else if constexpr (soa::with_index_pack<md>) {
473 metadata.emplace_back("index-records", framework::VariantType::Bool, true, framework::ConfigParamSpec::HelpString{"\"\""});
474 }
475 if ((R.origin_hash == "AOD"_h) && (newOrigin != header::DataOrigin{"AOD"})) {
476 metadata.push_back(framework::ConfigParamSpec{"aod-origin-replaced", framework::VariantType::Bool, true, {"\"\""}});
477 }
478 return framework::OutputSpec{
479 framework::OutputLabel{o2::aod::label<R>()},
480 ((R.origin_hash == "AOD"_h) && (newOrigin != header::DataOrigin{"AOD"})) ? newOrigin : o2::aod::origin<R>(),
481 o2::aod::description(o2::aod::signature<R>()),
482 R.version,
483 framework::Lifetime::Timeframe,
484 metadata};
485}
486
487template <TableRef R>
488constexpr auto tableRef2OutputRef()
489{
491 o2::aod::label<R>(),
492 R.version};
493}
494} // namespace o2::soa
495
496namespace o2::framework
497{
498class TableConsumer;
499
503template <is_producable T>
505 public:
506 using persistent_table_t = decltype([]() { if constexpr (soa::is_iterator<T>) { return typename T::parent_t{nullptr}; } else { return T{nullptr}; } }());
507 using cursor_t = decltype(std::declval<TableBuilder>().cursor<persistent_table_t>());
508 OutputSpec outputSpec{soa::tableRef2OutputSpec<persistent_table_t::ref>()};
510 {
511 return soa::tableRef2OutputSpec<persistent_table_t::ref>(newOrigin);
512 }
513
514 template <typename... Ts>
515 void operator()(Ts&&... args)
516 requires(sizeof...(Ts) == framework::pack_size(typename persistent_table_t::persistent_columns_t{}))
517 {
518 ++mCount;
519 if (mReserved >= 0 && mCount >= mReserved) [[unlikely]] {
520 // reserve() switched this cursor to UnsafeAppend, which does not grow its
521 // buffers. Writing row mCount (>= the reserved count) would overrun them and
522 // silently corrupt the heap, so fail here, naming the offending table and
523 // row, rather than crashing later somewhere unrelated.
524 LOG(fatal) << "Table '" << outputSpec.binding.value << "': writing row " << mCount
525 << " exceeds reserve(" << mReserved << ").";
526 }
527 cursor(0, extract(args)...);
528 }
529
531 int64_t lastIndex()
532 {
533 return mCount;
534 }
535
537 {
538 mBuilder = std::move(builder);
539 cursor = std::move(FFL(mBuilder->cursor<persistent_table_t>()));
540 mCount = -1;
541 // Back to the safe, bounds-checked cursor: no reservation to validate until
542 // reserve() is called again for this timeframe.
543 mReserved = -1;
544 return true;
545 }
546
547 void setLabel(const char* label)
548 {
549 mBuilder->setLabel(label);
550 }
551
556 void reserve(int64_t size)
557 {
558 mBuilder->reserve(typename persistent_table_t::column_types{}, size);
559 mReserved = size;
560 cursor = std::move(FFL(mBuilder->template unsafeCursor<persistent_table_t>()));
561 }
562
563 void release()
564 {
565 // Called once per timeframe, when the table is finalized. If reserve() was
566 // used (switching to UnsafeAppend, which skips per-row bounds checks), make
567 // sure we did not write past what we reserved: mCount + 1 is the number of
568 // rows actually filled, mReserved the capacity we requested. Overrunning it
569 // is silent memory corruption of the arrow buffers, so we fail hard here,
570 // before the (corrupt) table is serialized downstream. mReserved < 0 means
571 // reserve() was not called and the safe cursor was used: nothing to check.
572 if (mReserved >= 0 && mCount + 1 > mReserved) {
573 LOG(fatal) << "Table '" << outputSpec.binding.value << "': filled " << (mCount + 1)
574 << " rows after reserve(" << mReserved
575 << "). UnsafeAppend overran the reserved buffer — reserve() must request "
576 "at least as many rows as are filled.";
577 }
578 mBuilder.release();
579 }
580
581 decltype(FFL(std::declval<cursor_t>())) cursor;
582
583 private:
584 static decltype(auto) extract(soa::is_enumerated_iterator auto const& arg)
585 {
586 return arg.globalIndex();
587 }
588
589 template <typename A>
591 static decltype(auto) extract(A&& arg)
592 {
593 return arg;
594 }
595
599 LifetimeHolder<TableBuilder> mBuilder = nullptr;
600 int64_t mCount = -1;
604 int64_t mReserved = -1;
605};
606
608template <soa::is_table T>
609consteval auto typeWithRef() -> T
610{
611}
612
613template <soa::is_iterator T>
614consteval auto typeWithRef() -> typename T::parent_t
615{
616}
617
618template <typename T>
619 requires soa::is_table<T> || soa::is_iterator<T>
621 using table_t = decltype(typeWithRef<T>());
622 using metadata = aod::MetadataTrait<o2::aod::Hash<table_t::ref.desc_hash>>::metadata;
623
624 static constexpr auto spec()
625 {
626 return soa::tableRef2OutputSpec<table_t::ref>();
627 }
628
629 static constexpr auto ref()
630 {
631 return soa::tableRef2OutputRef<table_t::ref>();
632 }
633};
634
638
643template <is_producable T>
645};
646
656 static constexpr void isProducesGroup() {};
657};
658
660template <soa::is_metadata M, soa::TableRef Ref>
662 using metadata = M;
663 constexpr static auto sources = M::template generateSources<o2::aod::Hash<Ref.origin_hash>>();
664
665 OutputSpec outputSpec{soa::tableRef2OutputSpec<Ref>()};
667 {
668 return soa::tableRef2OutputSpec<Ref>(newOrigin);
669 }
670
672 static constexpr auto getRequiredInputs(header::DataOrigin const& newOrigin = header::DataOrigin{"AOD"})
673 {
674 return [&newOrigin]<size_t... Is>(std::index_sequence<Is...>) {
675 return std::array{soa::tableRef2InputSpec<sources[Is]>(newOrigin)...};
676 }(std::make_index_sequence<sources.size()>());
677 }
678};
679
682template <is_spawnable T>
683consteval auto transformBase()
684{
685 using metadata = typename aod::MetadataTrait<o2::aod::Hash<T::originals[T::originals.size() - 1].desc_hash>>::metadata;
686 return TableTransform<metadata, metadata::template extension_table_t_from<o2::aod::Hash<T::originals[T::originals.size() - 1].origin_hash>>::ref>{};
687}
688
693template <is_spawnable T>
694struct Spawns : decltype(transformBase<T>()) {
695 using spawnable_t = T;
696 using metadata = decltype(transformBase<T>())::metadata;
697 using extension_t = typename metadata::template extension_table_t_from<o2::aod::Hash<T::originals[T::originals.size() - 1].origin_hash>>;
698 using expression_pack_t = typename metadata::expression_pack_t;
699 static constexpr size_t N = framework::pack_size(expression_pack_t{});
700
701 typename T::table_t* operator->()
702 {
703 return table.get();
704 }
705 typename T::table_t const& operator*() const
706 {
707 return *table;
708 }
709
711 {
712 return extension->asArrowTable();
713 }
714
715 std::shared_ptr<typename T::table_t> table = nullptr;
716 std::shared_ptr<extension_t> extension = nullptr;
717 std::array<o2::framework::expressions::Projector, N> projectors = []<typename... C>(framework::pack<C...>)->std::array<expressions::Projector, sizeof...(C)>
718 {
719 return {{std::move(C::Projector())...}};
720 }
722 std::shared_ptr<gandiva::Projector> projector = nullptr;
723 std::shared_ptr<arrow::Schema> schema = []() {
724 auto s = std::make_shared<arrow::Schema>(o2::soa::createFieldsFromColumns(expression_pack_t{}));
725 s->WithMetadata(std::make_shared<arrow::KeyValueMetadata>(std::vector{std::string{"label"}}, std::vector{std::string{o2::aod::label<T::ref>()}}));
726 return s;
727 }();
728};
729
734template <is_dynamically_spawnable T, bool DELAYED = false>
735struct Defines : decltype(transformBase<T>()) {
736 static constexpr bool delayed = DELAYED;
737 using spawnable_t = T;
738 using metadata = decltype(transformBase<T>())::metadata;
739 using extension_t = typename metadata::template extension_table_t_from<o2::aod::Hash<T::originals[T::originals.size() - 1].origin_hash>>;
740 using placeholders_pack_t = typename metadata::placeholders_pack_t;
741 static constexpr size_t N = framework::pack_size(placeholders_pack_t{});
742
743 typename T::table_t* operator->()
744 {
745 return table.get();
746 }
747 typename T::table_t const& operator*() const
748 {
749 return *table;
750 }
751
753 {
754 return extension->asArrowTable();
755 }
756 std::shared_ptr<typename T::table_t> table = nullptr;
757 std::shared_ptr<extension_t> extension = nullptr;
758
759 std::array<o2::framework::expressions::Projector, N> projectors;
760 std::shared_ptr<gandiva::Projector> projector = nullptr;
761 std::shared_ptr<arrow::Schema> schema = []() {
762 auto s = std::make_shared<arrow::Schema>(o2::soa::createFieldsFromColumns(placeholders_pack_t{}));
763 s->WithMetadata(std::make_shared<arrow::KeyValueMetadata>(std::vector{std::string{"label"}}, std::vector{std::string{o2::aod::label<T::ref>()}}));
764 return s;
765 }();
766 std::shared_ptr<arrow::Schema> inputSchema = nullptr;
767
768 bool needRecompilation = false;
769
774};
775
776template <is_dynamically_spawnable T>
778
782struct Exclusive {
783};
784struct Sparse {
785};
786
788template <soa::is_index_table T>
789consteval auto transformBase()
790{
791 using metadata = typename aod::MetadataTrait<o2::aod::Hash<T::ref.desc_hash>>::metadata;
793}
794
795template <soa::is_index_table T>
796struct Builds : decltype(transformBase<T>()) {
797 using buildable_t = T;
798 using metadata = decltype(transformBase<T>())::metadata;
799 using Key = metadata::Key;
800 using H = typename T::first_t;
801 using Ts = typename T::rest_t;
802 using index_pack_t = metadata::index_pack_t;
803
804 std::shared_ptr<arrow::Schema> outputSchema = []() { return std::make_shared<arrow::Schema>(soa::createFieldsFromColumns(index_pack_t{}))->WithMetadata(std::make_shared<arrow::KeyValueMetadata>(std::vector{std::string{"label"}}, std::vector{std::string{o2::aod::label<T::ref>()}})); }();
805
806 std::vector<soa::IndexRecord> map = soa::getIndexMapping<metadata>();
807
808 std::vector<framework::IndexColumnBuilder> builders;
809
811 {
812 return table.get();
813 }
814 T const& operator*() const
815 {
816 return *table;
817 }
818
820 {
821 return table->asArrowTable();
822 }
823 std::shared_ptr<T> table = nullptr;
824
825 static consteval auto pack()
826 {
827 return index_pack_t{};
828 }
829
830 auto build(std::vector<std::shared_ptr<arrow::Table>>&& tables)
831 {
832 this->table = std::make_shared<T>(soa::IndexBuilder::materialize(builders, std::forward<std::vector<std::shared_ptr<arrow::Table>>>(tables), map, outputSchema, metadata::exclusive));
833 return (this->table != nullptr);
834 }
835};
836
839
847template <typename T>
848 requires(std::derived_from<T, TObject>)
849struct OutputObj {
850 using obj_t = T;
851
853 : object(std::make_shared<T>(t)),
854 label(t.GetName()),
855 policy{policy_},
856 sourceType{sourceType_},
857 mTaskHash{0}
858 {
859 }
860
862 : object(nullptr),
863 label(label_),
864 policy{policy_},
865 sourceType{sourceType_},
866 mTaskHash{0}
867 {
868 }
869
870 void setObject(T const& t)
871 {
872 object = std::make_shared<T>(t);
873 object->SetName(label.c_str());
874 }
875
876 void setObject(T&& t)
877 {
878 object = std::make_shared<T>(t);
879 object->SetName(label.c_str());
880 }
881
882 void setObject(T* t)
883 {
884 object.reset(t);
885 object->SetName(label.c_str());
886 }
887
888 void setObject(std::shared_ptr<T> t)
889 {
890 object = t;
891 object->SetName(label.c_str());
892 }
893
894 void setHash(uint32_t hash)
895 {
896 mTaskHash = hash;
897 }
898
901 {
903 auto lhash = runtime_hash(label.c_str());
904 std::memset(desc.str, '_', 16);
905 std::stringstream s;
906 s << std::hex << lhash;
907 s << std::hex << mTaskHash;
908 s << std::hex << reinterpret_cast<uint64_t>(this);
909 std::memcpy(desc.str, s.str().c_str(), 12);
910 return OutputSpec{OutputLabel{label}, "ATSK", desc, 0, Lifetime::QA};
911 }
912
914 {
915 return object.get();
916 }
917
919 {
920 return *object.get();
921 }
922
923 OutputRef ref(uint16_t index, uint16_t max)
924 {
925 return OutputRef{std::string{label}, 0,
926 o2::header::Stack{OutputObjHeader{policy, sourceType, mTaskHash, index, max}}};
927 }
928
929 std::shared_ptr<T> object;
930 std::string label;
933 uint32_t mTaskHash;
934};
935
939template <typename T>
940struct Service {
941 using service_t = T;
943
944 decltype(auto) operator->() const
945 {
947 return service->get();
948 } else {
949 return service;
950 }
951 }
952};
953
955{
956 return std::make_unique<o2::soa::Filtered<std::decay_t<decltype(table)>>>(std::vector{table}, std::forward<soa::SelectionVector>(selection));
957}
958
960{
961 return std::make_unique<o2::soa::Filtered<std::decay_t<decltype(table)>>>(std::vector{table.asArrowTableRef()}, std::forward<soa::SelectionVector>(selection));
962}
963
964void initializePartitionCaches(std::span<const uint32_t> hashes, std::shared_ptr<arrow::Schema> const& schema, expressions::Filter const& filter, gandiva::NodePtr& tree, gandiva::FilterPtr& gfilter);
965
973template <soa::is_table T>
974struct Partition {
975 using content_t = T;
976 Partition(expressions::Node&& filter_) : filter{std::forward<expressions::Node>(filter_)}
977 {
978 }
979
980 Partition(expressions::Node&& filter_, T const& table)
981 : filter{std::forward<expressions::Node>(filter_)}
982 {
983 setTable(table);
984 }
985
986 void intializeCaches(std::span<const uint32_t> hashes, std::shared_ptr<arrow::Schema> const& schema)
987 {
989 }
990
991 void bindTable(T const& table)
992 {
993 intializeCaches(T::table_t::column_hashes, table.asArrowTableRef()->schema());
994 if (dataframeChanged) {
996 dataframeChanged = false;
997 }
998 }
999
1000 template <typename... Ts>
1001 void bindExternalIndices(Ts*... tables)
1002 {
1003 if (mFiltered != nullptr) {
1004 mFiltered->bindExternalIndices(tables...);
1005 }
1006 }
1007
1008 template <typename E>
1010 {
1011 if (mFiltered != nullptr) {
1012 mFiltered->bindInternalIndicesTo(ptr);
1013 }
1014 }
1015
1017 {
1019 }
1020
1021 [[nodiscard]] std::shared_ptr<arrow::Table> asArrowTable() const
1022 {
1023 return mFiltered->asArrowTable();
1024 }
1025
1027 {
1028 return mFiltered.get();
1029 }
1030
1031 template <typename T1>
1032 [[nodiscard]] auto rawSliceBy(o2::framework::Preslice<T1> const& container, int value) const
1033 {
1034 return mFiltered->rawSliceBy(container, value);
1035 }
1036
1038 {
1039 return mFiltered->sliceByCached(node, value, cache);
1040 }
1041
1043 {
1044 return mFiltered->sliceByCachedUnsorted(node, value, cache);
1045 }
1046
1047 template <typename T1, typename Policy, bool OPT>
1048 [[nodiscard]] auto sliceBy(o2::framework::PresliceBase<T1, Policy, OPT> const& container, int value) const
1049 {
1050 return mFiltered->sliceBy(container, value);
1051 }
1052
1054 std::unique_ptr<o2::soa::Filtered<T>> mFiltered = nullptr;
1055 gandiva::NodePtr tree = nullptr;
1057 bool dataframeChanged = true;
1058
1064 {
1065 return mFiltered->begin();
1066 }
1068 {
1069 return mFiltered->end();
1070 }
1072 {
1073 return mFiltered->begin();
1074 }
1076 {
1077 return mFiltered->end();
1078 }
1079
1080 int64_t size() const
1081 {
1082 return mFiltered->size();
1083 }
1084};
1085} // namespace o2::framework
1086
1087namespace o2::soa
1088{
1090template <soa::is_table T, soa::is_spawnable_column... Cs>
1091auto Extend(T const& table)
1092{
1093 using output_t = Join<T, soa::Table<o2::aod::Hash<"JOIN"_h>, o2::aod::Hash<"JOIN/0"_h>, o2::aod::Hash<"JOIN"_h>, Cs...>>;
1094 static std::array<framework::expressions::Projector, sizeof...(Cs)> projectors{{std::move(Cs::Projector())...}};
1095 static std::shared_ptr<gandiva::Projector> projector = nullptr;
1096 static auto schema = std::make_shared<arrow::Schema>(o2::soa::createFieldsFromColumns(framework::pack<Cs...>{}));
1097 return output_t{{o2::framework::spawner(framework::pack<Cs...>{}, {table.asArrowTable()}, "dynamicExtension", projectors.data(), projector, schema), table.asArrowTable()}};
1098}
1099
1102template <soa::is_table T, soa::is_dynamic_column... Cs>
1103auto Attach(T const& table)
1104{
1105 using output_t = Join<T, o2::soa::Table<o2::aod::Hash<"JOIN"_h>, o2::aod::Hash<"JOIN/0"_h>, o2::aod::Hash<"JOIN"_h>, Cs...>>;
1106 return output_t{{table.asArrowTableRef()}};
1107}
1108} // namespace o2::soa
1109
1110#endif // o2_framework_AnalysisHelpers_H_DEFINED
bool exclusive
std::vector< o2::soa::IndexRecord > records
std::vector< expressions::Projector > projectors
std::vector< std::shared_ptr< gandiva::Expression > > expressions
std::vector< std::string > labels
o2::monitoring::tags::Key Key
uint32_t hash
std::shared_ptr< arrow::Schema > schema
std::unique_ptr< expressions::Node > node
int32_t i
uint16_t pos
Definition RawData.h:3
uint32_t gfilter
Definition RawData.h:6
constexpr uint32_t runtime_hash(char const *str)
nlohmann::json json
TBranch * ptr
Definition A.h:16
iterator const_iterator
Definition ASoA.h:3844
T::template iterator_template_o< FilteredIndexPolicy, self_t > iterator
Definition ASoA.h:3842
GLuint64EXT * result
Definition glcorearb.h:5662
GLsizeiptr size
Definition glcorearb.h:659
GLuint index
Definition glcorearb.h:781
GLuint const GLchar * name
Definition glcorearb.h:781
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLsizei GLsizei GLchar * source
Definition glcorearb.h:798
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
GLsizei GLenum const void * indices
Definition glcorearb.h:400
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition glcorearb.h:1308
GLuint object
Definition glcorearb.h:4041
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLint ref
Definition glcorearb.h:291
GLsizei GLenum * sources
Definition glcorearb.h:2516
std::shared_ptr< gandiva::Filter > FilterPtr
Definition Expressions.h:46
constexpr framework::ConcreteDataMatcher matcher()
Definition ASoA.h:388
std::variant< OriginValueMatcher, DescriptionValueMatcher, SubSpecificationTypeValueMatcher, std::unique_ptr< DataDescriptorMatcher >, ConstantValueMatcher, StartTimeValueMatcher > Node
std::shared_ptr< gandiva::Projector > createProjectorHelper(size_t nColumns, expressions::Projector *projectors, std::shared_ptr< arrow::Schema > schema, std::vector< std::shared_ptr< arrow::Field > > const &fields)
gandiva::Selection createSelection(std::shared_ptr< arrow::Table > const &table, Filter const &expression)
Function for creating gandiva selection from our internal filter tree.
void updatePlaceholders(Filter &filter, InitContext &context)
Update placeholder nodes from context.
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
auto spawner(std::shared_ptr< arrow::Table > const &fullTable, const char *name, o2::framework::expressions::Projector *projectors, std::shared_ptr< gandiva::Projector > &projector, std::shared_ptr< arrow::Schema > const &schema)
Expression-based column generator to materialize columns.
std::string serializeSchema(std::shared_ptr< arrow::Schema > schema)
consteval auto transformBase()
This helper struct allows you to declare index tables to be created in a task.
void initializePartitionCaches(std::span< const uint32_t > hashes, std::shared_ptr< arrow::Schema > const &schema, expressions::Filter const &filter, gandiva::NodePtr &tree, gandiva::FilterPtr &gfilter)
std::string serializeProjectors(std::vector< framework::expressions::Projector > &projectors)
std::shared_ptr< arrow::Table > spawnerHelper(std::shared_ptr< arrow::Table > const &fullTable, std::shared_ptr< arrow::Schema > newSchema, size_t nColumns, expressions::Projector *projectors, const char *name, std::shared_ptr< gandiva::Projector > &projector)
constexpr std::size_t pack_size(pack< Ts... > const &)
template function to determine number of types in a pack
Definition Pack.h:28
std::string serializeIndexRecords(std::vector< o2::soa::IndexRecord > &irs)
ConfigParamSpec replaceOrigin(ConfigParamSpec &source, std::string const &originStr)
void wrongOriginReplacement(std::string_view replacement)
memfun_type< decltype(&F::operator())>::type FFL(F const &func)
auto getTableFromFilter(soa::is_filtered_table auto const &table, soa::SelectionVector &&selection)
std::vector< std::shared_ptr< arrow::Table > > extractSources(ProcessingContext &pc, std::vector< std::string > const &labels)
consteval auto typeWithRef() -> T
Helper to define output for a Table.
OutputObjHandlingPolicy
Policy enum to determine OutputObj handling when writing.
std::shared_ptr< arrow::Table > makeEmptyTableImpl(const char *name, std::shared_ptr< arrow::Schema > &schema)
Descriptor< gSizeDataOriginString > DataOrigin
Definition DataHeader.h:550
auto createFieldsFromColumns(framework::pack< C... >)
Definition ASoA.h:77
SelectionVector selectionToVector(gandiva::Selection const &sel)
Definition ASoA.cxx:48
std::vector< int64_t > SelectionVector
Definition ASoA.h:444
auto Attach(T const &table)
constexpr auto tableRef2OutputSpec(header::DataOrigin newOrigin=header::DataOrigin{"AOD"})
constexpr auto tableRef2Schema()
constexpr auto tableRef2InputSpec(header::DataOrigin newOrigin=header::DataOrigin{"AOD"})
constexpr auto tableRef2ConfigParamSpec()
auto Extend(T const &table)
On-the-fly adding of expression columns.
constexpr auto tableRef2OutputRef()
@ C
Definition Defs.h:36
header::DataDescription description
std::vector< o2::soa::IndexRecord > records
std::vector< std::string > labels
std::vector< framework::ConcreteDataMatcher > matchers
header::DataOrigin origin
std::shared_ptr< std::vector< framework::IndexColumnBuilder > > builders
header::DataHeader::SubSpecificationType version
std::shared_ptr< arrow::Schema > outputSchema
std::shared_ptr< arrow::Table > materialize(ProcessingContext &pc)
std::shared_ptr< T > table
auto build(std::vector< std::shared_ptr< arrow::Table > > &&tables)
std::vector< soa::IndexRecord > map
std::vector< framework::IndexColumnBuilder > builders
std::shared_ptr< arrow::Schema > outputSchema
typename T::first_t H
T const & operator*() const
static consteval auto pack()
metadata::index_pack_t index_pack_t
typename T::rest_t Ts
decltype(transformBase< T >())::metadata metadata
std::shared_ptr< typename T::table_t > table
T::table_t const & operator*() const
typename metadata::template extension_table_t_from< o2::aod::Hash< T::originals[T::originals.size() - 1].origin_hash > > extension_t
decltype(transformBase< T >())::metadata metadata
std::array< o2::framework::expressions::Projector, N > projectors
std::shared_ptr< extension_t > extension
std::shared_ptr< arrow::Schema > inputSchema
std::shared_ptr< arrow::Schema > schema
static constexpr bool delayed
static constexpr size_t N
typename metadata::placeholders_pack_t placeholders_pack_t
std::shared_ptr< gandiva::Projector > projector
std::vector< std::pair< int, ConcreteDataMatcher > > matchers
static constexpr auto spec()
static constexpr auto ref()
aod::MetadataTrait< o2::aod::Hash< table_t::ref.desc_hash > >::metadata metadata
decltype(typeWithRef< T >()) table_t
O2 header for OutputObj metadata.
OutputObj(T &&t, OutputObjHandlingPolicy policy_=OutputObjHandlingPolicy::AnalysisObject, OutputObjSourceType sourceType_=OutputObjSourceType::OutputObjSource)
void setObject(std::shared_ptr< T > t)
OutputObjSourceType sourceType
OutputRef ref(uint16_t index, uint16_t max)
std::shared_ptr< T > object
OutputObj(std::string const &label_, OutputObjHandlingPolicy policy_=OutputObjHandlingPolicy::AnalysisObject, OutputObjSourceType sourceType_=OutputObjSourceType::OutputObjSource)
OutputSpec const spec()
OutputObjHandlingPolicy policy
void setHash(uint32_t hash)
Partition(expressions::Node &&filter_, T const &table)
typename o2::soa::Filtered< T >::const_iterator filtered_const_iterator
void bindTable(T const &table)
filtered_const_iterator begin() const
auto rawSliceBy(o2::framework::Preslice< T1 > const &container, int value) const
auto sliceByCached(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
Partition(expressions::Node &&filter_)
void intializeCaches(std::span< const uint32_t > hashes, std::shared_ptr< arrow::Schema > const &schema)
typename o2::soa::Filtered< T >::iterator filtered_iterator
o2::soa::Filtered< T > * operator->()
typename o2::soa::Filtered< T >::iterator iterator
auto sliceBy(o2::framework::PresliceBase< T1, Policy, OPT > const &container, int value) const
std::shared_ptr< arrow::Table > asArrowTable() const
o2::soa::RowViewSentinel end() const
void updatePlaceholders(InitContext &context)
std::unique_ptr< o2::soa::Filtered< T > > mFiltered
expressions::Filter filter
o2::soa::RowViewSentinel end()
auto sliceByCachedUnsorted(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
typename o2::soa::Filtered< T >::const_iterator const_iterator
gandiva::FilterPtr gfilter
void bindExternalIndices(Ts *... tables)
filtered_iterator begin()
static constexpr void isProducesGroup()
header::DataDescription description
std::vector< std::string > labels
std::vector< std::shared_ptr< gandiva::Expression > > expressions
std::shared_ptr< gandiva::Projector > projector
header::DataOrigin origin
std::vector< framework::ConcreteDataMatcher > matchers
header::DataHeader::SubSpecificationType version
std::shared_ptr< arrow::Schema > schema
std::shared_ptr< arrow::Table > materialize(ProcessingContext &pc) const
std::shared_ptr< arrow::Schema > inputSchema
T::table_t * operator->()
std::shared_ptr< gandiva::Projector > projector
std::shared_ptr< extension_t > extension
T::table_t const & operator*() const
static constexpr size_t N
std::shared_ptr< arrow::Schema > schema
typename metadata::expression_pack_t expression_pack_t
std::array< o2::framework::expressions::Projector, N > projectors
decltype(transformBase< T >())::metadata metadata
std::shared_ptr< typename T::table_t > table
typename metadata::template extension_table_t_from< o2::aod::Hash< T::originals[T::originals.size() - 1].origin_hash > > extension_t
Helper template for table transformations.
std::array< InputSpec, sources.size()> requiredInputs
static constexpr auto getRequiredInputs(header::DataOrigin const &newOrigin=header::DataOrigin{"AOD"})
static OutputSpec updateOutputSpec(header::DataOrigin const &newOrigin=header::DataOrigin{"AOD"})
int64_t lastIndex()
Last index inserted in the table.
decltype(FFL(std::declval< cursor_t >())) cursor
static OutputSpec updateOutputSpec(header::DataOrigin const &newOrigin=header::DataOrigin{"AOD"})
bool resetCursor(LifetimeHolder< TableBuilder > builder)
void setLabel(const char *label)
void operator()(Ts &&... args)
decltype([]() { if constexpr(soa::is_iterator< T >) { return typename T::parent_t{nullptr} persistent_table_t
decltype(std::declval< TableBuilder >().cursor< persistent_table_t >()) cursor_t
An expression tree node corresponding to a column binding.
A struct, containing the root of the expression tree.
uint32_t SubSpecificationType
Definition DataHeader.h:622
a move-only header stack with serialized headers This is the flat buffer where all the headers in a m...
Definition Stack.h:33
static o2::soa::ArrowTableRef joinTables(std::vector< std::shared_ptr< arrow::Table > > &&tables)
Definition ASoA.cxx:140
static void resetBuilders(std::vector< framework::IndexColumnBuilder > &builders, std::vector< std::shared_ptr< arrow::Table > > &&tables)
static std::vector< framework::IndexColumnBuilder > makeBuilders(std::vector< std::shared_ptr< arrow::Table > > &&tables, std::vector< soa::IndexRecord > const &records)
static std::shared_ptr< arrow::Table > materialize(std::vector< framework::IndexColumnBuilder > &builders, std::vector< std::shared_ptr< arrow::Table > > &&tables, std::vector< soa::IndexRecord > const &records, std::shared_ptr< arrow::Schema > const &schema, bool exclusive)
std::shared_ptr< arrow::Field > field() const
auto operator==(IndexRecord const &other) const
framework::ConcreteDataMatcher matcher
constexpr size_t max
VectorOfTObjectPtrs other
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))