From c33b909d36ff52194e77ab5d5c7f528b39b46c31 Mon Sep 17 00:00:00 2001 From: Sebastian Wieczorek Date: Fri, 14 Feb 2025 12:37:53 +0100 Subject: [PATCH] c++17 concepts with CPP_template for engine/*.{cpp,h} files --- src/engine/GroupBy.cpp | 36 ++++++------- src/engine/GroupBy.h | 10 ++-- src/engine/GroupByHashMapOptimization.h | 6 +-- src/engine/QueryPlanner.cpp | 67 +++++++++++++------------ 4 files changed, 63 insertions(+), 56 deletions(-) diff --git a/src/engine/GroupBy.cpp b/src/engine/GroupBy.cpp index 2370a91c29..28e756d502 100644 --- a/src/engine/GroupBy.cpp +++ b/src/engine/GroupBy.cpp @@ -432,10 +432,11 @@ ProtoResult GroupBy::computeResult(bool requestLaziness) { } // _____________________________________________________________________________ -template -size_t GroupBy::searchBlockBoundaries( - const std::invocable auto& onBlockChange, - const IdTableView& idTable, GroupBlock& currentGroupBlock) const { +CPP_template_def(int COLS, + typename T)(requires ranges::invocable) + size_t GroupBy::searchBlockBoundaries(const T& onBlockChange, + const IdTableView& idTable, + GroupBlock& currentGroupBlock) const { size_t blockStart = 0; for (size_t pos = 0; pos < idTable.size(); pos++) { @@ -1252,18 +1253,19 @@ GroupBy::HashMapAggregationData::getHashEntries( hashEntries.push_back(iterator->second); } - auto resizeVectors = - []( - T& arg, size_t numberOfGroups, - [[maybe_unused]] const HashMapAggregateTypeWithData& info) { - if constexpr (std::same_as) { - arg.resize(numberOfGroups, - GroupConcatAggregationData{info.separator_.value()}); - } else { - arg.resize(numberOfGroups); - } - }; + // CPP_template_lambda(capture)(typenames...)(arg)(requires ...)` + auto resizeVectors = CPP_template_lambda()(typename T)( + T & arg, size_t numberOfGroups, + [[maybe_unused]] const HashMapAggregateTypeWithData& info)( + requires true) { + if constexpr (std::same_as) { + arg.resize(numberOfGroups, + GroupConcatAggregationData{info.separator_.value()}); + } else { + arg.resize(numberOfGroups); + } + }; // TODO use views::enumerate auto idx = 0; @@ -1273,7 +1275,7 @@ GroupBy::HashMapAggregationData::getHashEntries( std::visit( [&resizeVectors, &aggregationTypeWithData, - numberOfGroups](T& arg) { + numberOfGroups](T& arg) { resizeVectors(arg, numberOfGroups, aggregationTypeWithData); }, aggregation); diff --git a/src/engine/GroupBy.h b/src/engine/GroupBy.h index 8232f381ab..c5502d32b9 100644 --- a/src/engine/GroupBy.h +++ b/src/engine/GroupBy.h @@ -12,6 +12,7 @@ #include #include +#include "backports/concepts.h" #include "engine/GroupByHashMapOptimization.h" #include "engine/Join.h" #include "engine/Operation.h" @@ -112,10 +113,11 @@ class GroupBy : public Operation { // function returns the starting index of the last block of this `idTable`. // The argument `currentGroupBlock` is used to store the values of the group // by columns for the current group. - template - size_t searchBlockBoundaries( - const std::invocable auto& onBlockChange, - const IdTableView& idTable, GroupBlock& currentGroupBlock) const; + CPP_template(int COLS, + typename T)(requires ranges::invocable) size_t + searchBlockBoundaries(const T& onBlockChange, + const IdTableView& idTable, + GroupBlock& currentGroupBlock) const; // Helper function to process a sorted group within a single id table. template diff --git a/src/engine/GroupByHashMapOptimization.h b/src/engine/GroupByHashMapOptimization.h index e8f872e0a4..4d0ad58445 100644 --- a/src/engine/GroupByHashMapOptimization.h +++ b/src/engine/GroupByHashMapOptimization.h @@ -13,9 +13,9 @@ // For `AVG`, add value to sum if it is numeric, otherwise // set error flag. static constexpr auto valueAdder = []() { - auto numericValueAdder = - [](T value, double& sum, [[maybe_unused]] const bool& error) - requires std::is_arithmetic_v { + auto numericValueAdder = [](T value, double& sum, + [[maybe_unused]] const bool& error) + -> CPP_ret(void)(requires std::is_arithmetic_v) { sum += static_cast(value); }; auto nonNumericValueAdder = [](sparqlExpression::detail::NotNumeric, diff --git a/src/engine/QueryPlanner.cpp b/src/engine/QueryPlanner.cpp index d1516428f1..be7cfe27d5 100644 --- a/src/engine/QueryPlanner.cpp +++ b/src/engine/QueryPlanner.cpp @@ -526,7 +526,7 @@ namespace { // `TripleComponent`, typically the subject, predicate, or object of the triple, // hence the name. template -concept TriplePosition = +CPP_concept TriplePosition = ad_utility::InvocableWithExactReturnType; @@ -544,31 +544,32 @@ SparqlFilter createEqualFilter(const Variable& var1, const Variable& var2) { // position of the `scanTriple`, denoted by the `rewritePosition` by a new // variable, and add a filter, that checks the old and the new value for // equality. -constexpr auto rewriteSingle = - [](TriplePosition auto rewritePosition, SparqlTripleSimple& scanTriple, - const auto& addFilter, const auto& generateUniqueVarName) { - Variable filterVar = generateUniqueVarName(); - auto& target = std::invoke(rewritePosition, scanTriple).getVariable(); - addFilter(createEqualFilter(filterVar, target)); - target = filterVar; - }; +constexpr auto rewriteSingle = CPP_template_lambda()(typename T)( + T rewritePosition, SparqlTripleSimple& scanTriple, const auto& addFilter, + const auto& generateUniqueVarName)(requires TriplePosition) { + Variable filterVar = generateUniqueVarName(); + auto& target = std::invoke(rewritePosition, scanTriple).getVariable(); + addFilter(createEqualFilter(filterVar, target)); + target = filterVar; +}; // Replace the positions of the `triple` that are specified by the // `rewritePositions` with a new variable, and add a filter, which checks the // old and the new value for equality for each of these rewrites. Then also // add an index scan for the rewritten triple. constexpr auto handleRepeatedVariablesImpl = - [](const auto& triple, auto& addIndexScan, - const auto& generateUniqueVarName, const auto& addFilter, - std::span permutations, - TriplePosition auto... rewritePositions) { - auto scanTriple = triple; - (..., rewriteSingle(rewritePositions, scanTriple, addFilter, - generateUniqueVarName)); - for (const auto& permutation : permutations) { - addIndexScan(permutation, scanTriple); - } - }; + [](const auto& triple, auto& addIndexScan, + const auto& generateUniqueVarName, const auto& addFilter, + std::span permutations, + T... rewritePositions) + -> CPP_ret(void)(requires(TriplePosition&&...)) { + auto scanTriple = triple; + (..., rewriteSingle(rewritePositions, scanTriple, addFilter, + generateUniqueVarName)); + for (const auto& permutation : permutations) { + addIndexScan(permutation, scanTriple); + } +}; } // namespace @@ -601,13 +602,14 @@ void QueryPlanner::indexScanTwoVarsCase( // add an index scan for the rewritten triple. auto generate = [this]() { return generateUniqueVarName(); }; auto handleRepeatedVariables = - [&triple, &addIndexScan, &addFilter, &generate]( + [&triple, &addIndexScan, &addFilter, &generate]( std::span permutations, - TriplePosition auto... rewritePositions) { - return handleRepeatedVariablesImpl(triple, addIndexScan, generate, - addFilter, permutations, - rewritePositions...); - }; + T... rewritePositions) + -> CPP_ret(void)(requires(TriplePosition&&...)) { + return handleRepeatedVariablesImpl(triple, addIndexScan, generate, + addFilter, permutations, + rewritePositions...); + }; const auto& [s, p, o, _] = triple; @@ -653,13 +655,14 @@ void QueryPlanner::indexScanThreeVarsCase( // old and the new value for equality for this rewrite. Then also // add an index scan for the rewritten triple. auto handleRepeatedVariables = - [&triple, &addIndexScan, &addFilter, &generate]( + [&triple, &addIndexScan, &addFilter, &generate]( std::span permutations, - TriplePosition auto... rewritePositions) { - return handleRepeatedVariablesImpl(triple, addIndexScan, generate, - addFilter, permutations, - rewritePositions...); - }; + T... rewritePositions) + -> CPP_ret(void)(requires(TriplePosition&&...)) { + return handleRepeatedVariablesImpl(triple, addIndexScan, generate, + addFilter, permutations, + rewritePositions...); + }; using Tr = SparqlTripleSimple; const auto& [s, p, o, _] = triple;