You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@quickstep.apache.org by ji...@apache.org on 2016/11/07 21:34:13 UTC
[02/15] incubator-quickstep git commit: Optimizer
PushDownLowCostDisjunctivePredicate as physical optimization.
Optimizer PushDownLowCostDisjunctivePredicate as physical optimization.
Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/564897fc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/564897fc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/564897fc
Branch: refs/heads/collision-free-agg
Commit: 564897fc5f8b6a7d00e23f56a8dad7e0dfa1342c
Parents: 1e16f7d
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Sat Nov 5 01:22:09 2016 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Mon Nov 7 15:32:34 2016 -0600
----------------------------------------------------------------------
query_optimizer/CMakeLists.txt | 1 +
query_optimizer/PhysicalGenerator.cpp | 4 +-
query_optimizer/rules/CMakeLists.txt | 11 +-
.../PushDownLowCostDisjunctivePredicate.cpp | 161 +++++++++++++++++-
.../PushDownLowCostDisjunctivePredicate.hpp | 25 ++-
.../CollisionFreeAggregationStateHashTable.cpp | 65 +++++--
.../CollisionFreeAggregationStateHashTable.hpp | 168 +++++++++++--------
7 files changed, 338 insertions(+), 97 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/564897fc/query_optimizer/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/CMakeLists.txt b/query_optimizer/CMakeLists.txt
index 225955d..23929e8 100644
--- a/query_optimizer/CMakeLists.txt
+++ b/query_optimizer/CMakeLists.txt
@@ -215,6 +215,7 @@ target_link_libraries(quickstep_queryoptimizer_PhysicalGenerator
quickstep_queryoptimizer_rules_AttachLIPFilters
quickstep_queryoptimizer_rules_InjectJoinFilters
quickstep_queryoptimizer_rules_PruneColumns
+ quickstep_queryoptimizer_rules_PushDownLowCostDisjunctivePredicate
quickstep_queryoptimizer_rules_StarSchemaHashJoinOrderOptimization
quickstep_queryoptimizer_rules_SwapProbeBuild
quickstep_queryoptimizer_strategy_Aggregate
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/564897fc/query_optimizer/PhysicalGenerator.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/PhysicalGenerator.cpp b/query_optimizer/PhysicalGenerator.cpp
index 0e1b61e..dc9eab7 100644
--- a/query_optimizer/PhysicalGenerator.cpp
+++ b/query_optimizer/PhysicalGenerator.cpp
@@ -27,10 +27,11 @@
#include "query_optimizer/logical/Logical.hpp"
#include "query_optimizer/physical/Physical.hpp"
#include "query_optimizer/rules/AttachLIPFilters.hpp"
+#include "query_optimizer/rules/InjectJoinFilters.hpp"
#include "query_optimizer/rules/PruneColumns.hpp"
+#include "query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp"
#include "query_optimizer/rules/StarSchemaHashJoinOrderOptimization.hpp"
#include "query_optimizer/rules/SwapProbeBuild.hpp"
-#include "query_optimizer/rules/InjectJoinFilters.hpp"
#include "query_optimizer/strategy/Aggregate.hpp"
#include "query_optimizer/strategy/Join.hpp"
#include "query_optimizer/strategy/OneToOne.hpp"
@@ -106,6 +107,7 @@ P::PhysicalPtr PhysicalGenerator::generateInitialPlan(
P::PhysicalPtr PhysicalGenerator::optimizePlan() {
std::vector<std::unique_ptr<Rule<P::Physical>>> rules;
rules.emplace_back(new PruneColumns());
+ rules.emplace_back(new PushDownLowCostDisjunctivePredicate());
if (FLAGS_reorder_hash_joins) {
rules.emplace_back(new StarSchemaHashJoinOrderOptimization());
rules.emplace_back(new PruneColumns());
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/564897fc/query_optimizer/rules/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/CMakeLists.txt b/query_optimizer/rules/CMakeLists.txt
index c44e576..cace3f2 100644
--- a/query_optimizer/rules/CMakeLists.txt
+++ b/query_optimizer/rules/CMakeLists.txt
@@ -118,13 +118,18 @@ target_link_libraries(quickstep_queryoptimizer_rules_PushDownLowCostDisjunctiveP
quickstep_queryoptimizer_costmodel_StarSchemaSimpleCostModel
quickstep_queryoptimizer_expressions_AttributeReference
quickstep_queryoptimizer_expressions_ExprId
- quickstep_queryoptimizer_physical_Aggregate
+ quickstep_queryoptimizer_expressions_ExpressionUtil
+ quickstep_queryoptimizer_expressions_LogicalAnd
+ quickstep_queryoptimizer_expressions_LogicalOr
+ quickstep_queryoptimizer_expressions_PatternMatcher
+ quickstep_queryoptimizer_expressions_Predicate
quickstep_queryoptimizer_physical_HashJoin
+ quickstep_queryoptimizer_physical_NestedLoopsJoin
quickstep_queryoptimizer_physical_PatternMatcher
quickstep_queryoptimizer_physical_Physical
quickstep_queryoptimizer_physical_PhysicalType
quickstep_queryoptimizer_physical_Selection
- quickstep_queryoptimizer_physical_TopLevelPlan
+ quickstep_queryoptimizer_physical_TableReference
quickstep_queryoptimizer_rules_Rule
quickstep_utility_Macros)
target_link_libraries(quickstep_queryoptimizer_rules_PushDownSemiAntiJoin
@@ -199,6 +204,7 @@ target_link_libraries(quickstep_queryoptimizer_rules_InjectJoinFilters
quickstep_utility_lipfilter_LIPFilter)
target_link_libraries(quickstep_queryoptimizer_rules_UnnestSubqueries
quickstep_queryoptimizer_OptimizerContext
+ quickstep_queryoptimizer_expressions_Alias
quickstep_queryoptimizer_expressions_AttributeReference
quickstep_queryoptimizer_expressions_ComparisonExpression
quickstep_queryoptimizer_expressions_Exists
@@ -250,6 +256,7 @@ target_link_libraries(quickstep_queryoptimizer_rules
quickstep_queryoptimizer_rules_InjectJoinFilters
quickstep_queryoptimizer_rules_PruneColumns
quickstep_queryoptimizer_rules_PushDownFilter
+ quickstep_queryoptimizer_rules_PushDownLowCostDisjunctivePredicate
quickstep_queryoptimizer_rules_PushDownSemiAntiJoin
quickstep_queryoptimizer_rules_Rule
quickstep_queryoptimizer_rules_RuleHelper
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/564897fc/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.cpp
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.cpp b/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.cpp
index dfe5d53..6799f16 100644
--- a/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.cpp
+++ b/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.cpp
@@ -17,7 +17,7 @@
* under the License.
**/
-#include "query_optimizer/rules/AttachLIPFilters.hpp"
+#include "query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp"
#include <map>
#include <set>
@@ -28,15 +28,18 @@
#include "query_optimizer/cost_model/StarSchemaSimpleCostModel.hpp"
#include "query_optimizer/expressions/AttributeReference.hpp"
-#include "query_optimizer/physical/LIPFilterConfiguration.hpp"
-#include "query_optimizer/physical/Aggregate.hpp"
+#include "query_optimizer/expressions/ExpressionUtil.hpp"
+#include "query_optimizer/expressions/LogicalAnd.hpp"
+#include "query_optimizer/expressions/LogicalOr.hpp"
+#include "query_optimizer/expressions/PatternMatcher.hpp"
+#include "query_optimizer/expressions/Predicate.hpp"
#include "query_optimizer/physical/HashJoin.hpp"
+#include "query_optimizer/physical/NestedLoopsJoin.hpp"
#include "query_optimizer/physical/PatternMatcher.hpp"
#include "query_optimizer/physical/Physical.hpp"
#include "query_optimizer/physical/PhysicalType.hpp"
#include "query_optimizer/physical/Selection.hpp"
-#include "query_optimizer/physical/TopLevelPlan.hpp"
-#include "utility/lip_filter/LIPFilter.hpp"
+#include "query_optimizer/physical/TableReference.hpp"
#include "glog/logging.h"
@@ -46,6 +49,154 @@ namespace optimizer {
namespace E = ::quickstep::optimizer::expressions;
namespace P = ::quickstep::optimizer::physical;
+P::PhysicalPtr PushDownLowCostDisjunctivePredicate::apply(const P::PhysicalPtr &input) {
+ DCHECK(input->getPhysicalType() == P::PhysicalType::kTopLevelPlan);
+
+ const P::TopLevelPlanPtr top_level_plan =
+ std::static_pointer_cast<const P::TopLevelPlan>(input);
+ cost_model_.reset(
+ new cost::StarSchemaSimpleCostModel(
+ top_level_plan->shared_subplans()));
+
+ collectApplicablePredicates(input);
+// std::cout << "Num nodes = " << applicable_predicates_.size() << "\n";
+// for (const auto &pair : applicable_predicates_) {
+// std::cout << "Num predicates = " << pair.second.predicates.size() << "\n";
+// for (const auto &predicate : pair.second.predicates) {
+// std::cout << predicate->toString() << "\n";
+// }
+// }
+
+ if (!applicable_predicates_.empty()) {
+ return attachPredicates(input);
+ } else {
+ return input;
+ }
+}
+
+void PushDownLowCostDisjunctivePredicate::collectApplicablePredicates(
+ const physical::PhysicalPtr &input) {
+ // Currently consider only stored relations with small cardinality as targets.
+ P::TableReferencePtr table_reference;
+ if (P::SomeTableReference::MatchesWithConditionalCast(input, &table_reference)) {
+ if (cost_model_->estimateCardinality(input) <= 100u) {
+ applicable_nodes_.emplace(input, table_reference->attribute_list());
+ }
+ return;
+ }
+
+ for (const auto &child : input->children()) {
+ collectApplicablePredicates(child);
+ }
+
+ E::PredicatePtr filter_predicate = nullptr;
+ switch (input->getPhysicalType()) {
+ case P::PhysicalType::kHashJoin:
+ filter_predicate =
+ std::static_pointer_cast<const P::HashJoin>(input)->residual_predicate();
+ break;
+ case P::PhysicalType::kNestedLoopsJoin:
+ filter_predicate =
+ std::static_pointer_cast<const P::NestedLoopsJoin>(input)->join_predicate();
+ break;
+ default:
+ break;
+ }
+
+ E::LogicalOrPtr disjunctive_predicate;
+ if (filter_predicate == nullptr ||
+ !E::SomeLogicalOr::MatchesWithConditionalCast(filter_predicate, &disjunctive_predicate)) {
+ return;
+ }
+
+ // Currently consider only disjunctive normal form. E.g. disjunction of conjunctions.
+ std::vector<std::vector<E::PredicatePtr>> candidate_predicates;
+ std::vector<std::vector<std::vector<E::AttributeReferencePtr>>> candidate_attributes;
+ for (const auto &conjunctive_predicate : disjunctive_predicate->operands()) {
+ candidate_predicates.emplace_back();
+ candidate_attributes.emplace_back();
+ E::LogicalAndPtr logical_and;
+ if (E::SomeLogicalAnd::MatchesWithConditionalCast(conjunctive_predicate, &logical_and)) {
+ for (const auto &predicate : logical_and->operands()) {
+ candidate_predicates.back().emplace_back(predicate);
+ candidate_attributes.back().emplace_back(
+ predicate->getReferencedAttributes());
+ }
+ } else {
+ candidate_predicates.back().emplace_back(conjunctive_predicate);
+ candidate_attributes.back().emplace_back(
+ conjunctive_predicate->getReferencedAttributes());
+ }
+ }
+
+ for (const auto &node_pair : applicable_nodes_) {
+ const std::vector<E::AttributeReferencePtr> &target_attributes = node_pair.second;
+ std::vector<E::PredicatePtr> selected_disj_preds;
+ for (std::size_t i = 0; i < candidate_predicates.size(); ++i) {
+ const auto &cand_preds = candidate_predicates[i];
+ const auto &cand_attrs = candidate_attributes[i];
+
+ std::vector<E::PredicatePtr> selected_conj_preds;
+ for (std::size_t j = 0; j < cand_preds.size(); ++j) {
+ if (E::SubsetOfExpressions(cand_attrs[j], target_attributes)) {
+ selected_conj_preds.emplace_back(cand_preds[j]);
+ }
+ }
+ if (!selected_conj_preds.empty()) {
+ selected_disj_preds.emplace_back(
+ CreateConjunctive(selected_conj_preds));
+ }
+ }
+ if (!selected_disj_preds.empty()) {
+ applicable_predicates_[node_pair.first].add(
+ CreateDisjunctive(selected_disj_preds));
+ }
+ }
+}
+
+P::PhysicalPtr PushDownLowCostDisjunctivePredicate::attachPredicates(
+ const P::PhysicalPtr &input) const {
+ std::vector<P::PhysicalPtr> new_children;
+ for (const P::PhysicalPtr &child : input->children()) {
+ const P::PhysicalPtr new_child = attachPredicates(child);
+ new_children.push_back(new_child);
+ }
+
+ const P::PhysicalPtr output =
+ new_children == input->children() ? input
+ : input->copyWithNewChildren(new_children);
+
+ const auto &node_it = applicable_predicates_.find(input);
+ if (node_it != applicable_predicates_.end()) {
+ const E::PredicatePtr filter_predicate =
+ CreateConjunctive(node_it->second.predicates);
+ return P::Selection::Create(output,
+ E::ToNamedExpressions(output->getOutputAttributes()),
+ filter_predicate);
+ }
+
+ return output;
+}
+
+E::PredicatePtr PushDownLowCostDisjunctivePredicate::CreateConjunctive(
+ const std::vector<E::PredicatePtr> predicates) {
+ DCHECK_GE(predicates.size(), 1u);
+ if (predicates.size() == 1) {
+ return predicates.front();
+ } else {
+ return E::LogicalAnd::Create(predicates);
+ }
+}
+
+E::PredicatePtr PushDownLowCostDisjunctivePredicate::CreateDisjunctive(
+ const std::vector<E::PredicatePtr> predicates) {
+ DCHECK_GE(predicates.size(), 1u);
+ if (predicates.size() == 1) {
+ return predicates.front();
+ } else {
+ return E::LogicalOr::Create(predicates);
+ }
+}
} // namespace optimizer
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/564897fc/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp
----------------------------------------------------------------------
diff --git a/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp b/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp
index 9017437..0af704f 100644
--- a/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp
+++ b/query_optimizer/rules/PushDownLowCostDisjunctivePredicate.hpp
@@ -23,13 +23,13 @@
#include <cstddef>
#include <map>
#include <memory>
-#include <set>
#include <string>
#include <vector>
#include "query_optimizer/cost_model/StarSchemaSimpleCostModel.hpp"
#include "query_optimizer/expressions/AttributeReference.hpp"
#include "query_optimizer/expressions/ExprId.hpp"
+#include "query_optimizer/expressions/Predicate.hpp"
#include "query_optimizer/physical/Physical.hpp"
#include "query_optimizer/rules/Rule.hpp"
#include "utility/Macros.hpp"
@@ -57,6 +57,29 @@ class PushDownLowCostDisjunctivePredicate : public Rule<physical::Physical> {
physical::PhysicalPtr apply(const physical::PhysicalPtr &input) override;
private:
+ struct PredicateInfo {
+ PredicateInfo() {}
+ inline void add(expressions::PredicatePtr predicate) {
+ predicates.emplace_back(predicate);
+ }
+ std::vector<expressions::PredicatePtr> predicates;
+ };
+
+ void collectApplicablePredicates(const physical::PhysicalPtr &input);
+ physical::PhysicalPtr attachPredicates(const physical::PhysicalPtr &input) const;
+
+ static expressions::PredicatePtr CreateConjunctive(
+ const std::vector<expressions::PredicatePtr> predicates);
+
+ static expressions::PredicatePtr CreateDisjunctive(
+ const std::vector<expressions::PredicatePtr> predicates);
+
+ std::unique_ptr<cost::StarSchemaSimpleCostModel> cost_model_;
+
+ std::map<physical::PhysicalPtr,
+ std::vector<expressions::AttributeReferencePtr>> applicable_nodes_;
+ std::map<physical::PhysicalPtr, PredicateInfo> applicable_predicates_;
+
DISALLOW_COPY_AND_ASSIGN(PushDownLowCostDisjunctivePredicate);
};
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/564897fc/storage/CollisionFreeAggregationStateHashTable.cpp
----------------------------------------------------------------------
diff --git a/storage/CollisionFreeAggregationStateHashTable.cpp b/storage/CollisionFreeAggregationStateHashTable.cpp
index 8c9be7b..a24a9d3 100644
--- a/storage/CollisionFreeAggregationStateHashTable.cpp
+++ b/storage/CollisionFreeAggregationStateHashTable.cpp
@@ -132,18 +132,12 @@ bool CollisionFreeAggregationStateHashTable::upsertValueAccessor(
const attribute_id key_attr_id = key_attr_ids.front();
const bool is_key_nullable = key_type_->isNullable();
- // TODO: aux_accessor
- CHECK_GE(key_attr_id, 0);
-
for (std::size_t i = 0; i < num_handles_; ++i) {
DCHECK_LE(argument_ids[i].size(), 1u);
const attribute_id argument_id =
argument_ids[i].empty() ? kInvalidAttributeID : argument_ids[i].front();
- // TODO: aux_accessor
- CHECK_GE(argument_id, 0u);
-
const AggregationHandle *handle = handles_[i];
const auto &argument_types = handle->getArgumentTypes();
@@ -157,19 +151,58 @@ bool CollisionFreeAggregationStateHashTable::upsertValueAccessor(
is_argument_nullable = argument_type->isNullable();
}
- // TODO: aux_accessor
InvokeOnValueAccessorMaybeTupleIdSequenceAdapter(
base_accessor,
[&](auto *accessor) -> void { // NOLINT(build/c++11)
- upsertValueAccessorDispatchHelper(is_key_nullable,
- is_argument_nullable,
- key_type_,
- argument_type,
- handle->getAggregationID(),
- key_attr_id,
- argument_id,
- vec_tables_[i],
- accessor);
+ if (key_attr_id >= 0) {
+ if (argument_id >= 0) {
+ upsertValueAccessorDispatchHelper<false>(is_key_nullable,
+ is_argument_nullable,
+ key_type_,
+ argument_type,
+ handle->getAggregationID(),
+ key_attr_id,
+ argument_id,
+ vec_tables_[i],
+ accessor,
+ accessor);
+ } else {
+ upsertValueAccessorDispatchHelper<true>(is_key_nullable,
+ is_argument_nullable,
+ key_type_,
+ argument_type,
+ handle->getAggregationID(),
+ key_attr_id,
+ -(argument_id+2),
+ vec_tables_[i],
+ accessor,
+ aux_accessor);
+ }
+ } else {
+ if (argument_id >= 0) {
+ upsertValueAccessorDispatchHelper<true>(is_key_nullable,
+ is_argument_nullable,
+ key_type_,
+ argument_type,
+ handle->getAggregationID(),
+ -(key_attr_id+2),
+ argument_id,
+ vec_tables_[i],
+ aux_accessor,
+ accessor);
+ } else {
+ upsertValueAccessorDispatchHelper<false>(is_key_nullable,
+ is_argument_nullable,
+ key_type_,
+ argument_type,
+ handle->getAggregationID(),
+ -(key_attr_id+2),
+ -(argument_id+2),
+ vec_tables_[i],
+ aux_accessor,
+ aux_accessor);
+ }
+ }
});
}
return true;
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/564897fc/storage/CollisionFreeAggregationStateHashTable.hpp
----------------------------------------------------------------------
diff --git a/storage/CollisionFreeAggregationStateHashTable.hpp b/storage/CollisionFreeAggregationStateHashTable.hpp
index 0fa539b..be76f1c 100644
--- a/storage/CollisionFreeAggregationStateHashTable.hpp
+++ b/storage/CollisionFreeAggregationStateHashTable.hpp
@@ -128,71 +128,77 @@ class CollisionFreeAggregationStateHashTable
num_entries_);
}
- template <typename ...ArgTypes>
+ template <bool use_two_accessors, typename ...ArgTypes>
inline void upsertValueAccessorDispatchHelper(
const bool is_key_nullable,
const bool is_argument_nullable,
ArgTypes &&...args);
- template <bool is_key_nullable, bool is_value_nullable, typename ...ArgTypes>
+ template <bool ...bool_values, typename ...ArgTypes>
inline void upsertValueAccessorDispatchHelper(
const Type *key_type,
ArgTypes &&...args);
- template <bool is_key_nullable, bool is_value_nullable,
+ template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
typename KeyT, typename ...ArgTypes>
inline void upsertValueAccessorDispatchHelper(
const Type *argument_type,
const AggregationID agg_id,
ArgTypes &&...args);
- template <bool is_key_nullable, bool is_value_nullable,
- typename KeyT, typename ValueAccessorT>
+ template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
+ typename KeyT, typename KeyValueAccessorT, typename ArgumentValueAccessorT>
inline void upsertValueAccessorCountHelper(
const attribute_id key_attr_id,
const attribute_id argument_id,
void *vec_table,
- ValueAccessorT *accessor);
+ KeyValueAccessorT *key_accessor,
+ ArgumentValueAccessorT *argument_accessor);
- template <bool is_key_nullable, bool is_value_nullable,
- typename KeyT, typename ValueAccessorT>
+ template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
+ typename KeyT, typename KeyValueAccessorT, typename ArgumentValueAccessorT>
inline void upsertValueAccessorSumHelper(
const Type *argument_type,
const attribute_id key_attr_id,
const attribute_id argument_id,
void *vec_table,
- ValueAccessorT *accessor);
+ KeyValueAccessorT *key_accessor,
+ ArgumentValueAccessorT *argument_accessor);
- template <bool is_key_nullable, typename KeyT, typename ValueAccessorT>
+ template <bool is_key_nullable, typename KeyT, typename KeyValueAccessorT>
inline void upsertValueAccessorCountNullary(
const attribute_id key_attr_id,
std::atomic<std::size_t> *vec_table,
- ValueAccessorT *accessor);
+ KeyValueAccessorT *key_accessor);
- template <bool is_key_nullable, typename KeyT, typename ValueAccessorT>
+ template <bool use_two_accessors, bool is_key_nullable, typename KeyT,
+ typename KeyValueAccessorT, typename ArgumentValueAccessorT>
inline void upsertValueAccessorCountUnary(
const attribute_id key_attr_id,
const attribute_id argument_id,
std::atomic<std::size_t> *vec_table,
- ValueAccessorT *accessor);
+ KeyValueAccessorT *key_accessor,
+ ArgumentValueAccessorT *argument_accessor);
- template <bool is_key_nullable, bool is_argument_nullable,
+ template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
typename KeyT, typename ArgumentT, typename StateT,
- typename ValueAccessorT>
+ typename KeyValueAccessorT, typename ArgumentValueAccessorT>
inline void upsertValueAccessorIntegerSum(
const attribute_id key_attr_id,
const attribute_id argument_id,
std::atomic<StateT> *vec_table,
- ValueAccessorT *accessor);
+ KeyValueAccessorT *key_accessor,
+ ArgumentValueAccessorT *argument_accessor);
- template <bool is_key_nullable, bool is_argument_nullable,
+ template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
typename KeyT, typename ArgumentT, typename StateT,
- typename ValueAccessorT>
+ typename KeyValueAccessorT, typename ArgumentValueAccessorT>
inline void upsertValueAccessorGenericSum(
const attribute_id key_attr_id,
const attribute_id argument_id,
std::atomic<StateT> *vec_table,
- ValueAccessorT *accessor);
+ KeyValueAccessorT *key_accessor,
+ ArgumentValueAccessorT *argument_accessor);
template <typename KeyT>
inline void finalizeKeyInternal(const std::size_t start_position,
@@ -296,7 +302,7 @@ class CollisionFreeAggregationStateHashTable
// ----------------------------------------------------------------------------
// Implementations of template methods follow.
-template <typename ...ArgTypes>
+template <bool use_two_accessors, typename ...ArgTypes>
inline void CollisionFreeAggregationStateHashTable
::upsertValueAccessorDispatchHelper(
const bool is_key_nullable,
@@ -304,45 +310,43 @@ inline void CollisionFreeAggregationStateHashTable
ArgTypes &&...args) {
if (is_key_nullable) {
if (is_argument_nullable) {
- upsertValueAccessorDispatchHelper<true, true>(
+ upsertValueAccessorDispatchHelper<use_two_accessors, true, true>(
std::forward<ArgTypes>(args)...);
} else {
- upsertValueAccessorDispatchHelper<true, false>(
+ upsertValueAccessorDispatchHelper<use_two_accessors, true, false>(
std::forward<ArgTypes>(args)...);
}
} else {
if (is_argument_nullable) {
- upsertValueAccessorDispatchHelper<false, true>(
+ upsertValueAccessorDispatchHelper<use_two_accessors, false, true>(
std::forward<ArgTypes>(args)...);
} else {
- upsertValueAccessorDispatchHelper<false, false>(
+ upsertValueAccessorDispatchHelper<use_two_accessors, false, false>(
std::forward<ArgTypes>(args)...);
}
}
}
-template <bool is_key_nullable, bool is_value_nullable, typename ...ArgTypes>
+template <bool ...bool_values, typename ...ArgTypes>
inline void CollisionFreeAggregationStateHashTable
::upsertValueAccessorDispatchHelper(
const Type *key_type,
ArgTypes &&...args) {
switch (key_type->getTypeID()) {
case TypeID::kInt:
- upsertValueAccessorDispatchHelper<
- is_key_nullable, is_value_nullable, int>(
- std::forward<ArgTypes>(args)...);
+ upsertValueAccessorDispatchHelper<bool_values..., int>(
+ std::forward<ArgTypes>(args)...);
return;
case TypeID::kLong:
- upsertValueAccessorDispatchHelper<
- is_key_nullable, is_value_nullable, std::int64_t>(
- std::forward<ArgTypes>(args)...);
+ upsertValueAccessorDispatchHelper<bool_values..., std::int64_t>(
+ std::forward<ArgTypes>(args)...);
return;
default:
LOG(FATAL) << "Not supported";
}
}
-template <bool is_key_nullable, bool is_value_nullable,
+template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
typename KeyT, typename ...ArgTypes>
inline void CollisionFreeAggregationStateHashTable
::upsertValueAccessorDispatchHelper(
@@ -352,12 +356,12 @@ inline void CollisionFreeAggregationStateHashTable
switch (agg_id) {
case AggregationID::kCount:
upsertValueAccessorCountHelper<
- is_key_nullable, is_value_nullable, KeyT>(
+ use_two_accessors, is_key_nullable, is_argument_nullable, KeyT>(
std::forward<ArgTypes>(args)...);
return;
case AggregationID::kSum:
upsertValueAccessorSumHelper<
- is_key_nullable, is_value_nullable, KeyT>(
+ use_two_accessors, is_key_nullable, is_argument_nullable, KeyT>(
argument_type, std::forward<ArgTypes>(args)...);
return;
default:
@@ -365,41 +369,44 @@ inline void CollisionFreeAggregationStateHashTable
}
}
-template <bool is_key_nullable, bool is_value_nullable,
- typename KeyT, typename ValueAccessorT>
+template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
+ typename KeyT, typename KeyValueAccessorT, typename ArgumentValueAccessorT>
inline void CollisionFreeAggregationStateHashTable
::upsertValueAccessorCountHelper(
const attribute_id key_attr_id,
const attribute_id argument_id,
void *vec_table,
- ValueAccessorT *accessor) {
+ KeyValueAccessorT *key_accessor,
+ ArgumentValueAccessorT *argument_accessor) {
DCHECK_GE(key_attr_id, 0u);
- if (is_value_nullable && argument_id != kInvalidAttributeID) {
- upsertValueAccessorCountUnary<is_key_nullable, KeyT>(
+ if (is_argument_nullable && argument_id != kInvalidAttributeID) {
+ upsertValueAccessorCountUnary<use_two_accessors, is_key_nullable, KeyT>(
key_attr_id,
argument_id,
static_cast<std::atomic<std::size_t> *>(vec_table),
- accessor);
+ key_accessor,
+ argument_accessor);
return;
} else {
upsertValueAccessorCountNullary<is_key_nullable, KeyT>(
key_attr_id,
static_cast<std::atomic<std::size_t> *>(vec_table),
- accessor);
+ key_accessor);
return;
}
}
-template <bool is_key_nullable, bool is_value_nullable,
- typename KeyT, typename ValueAccessorT>
+template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
+ typename KeyT, typename KeyValueAccessorT, typename ArgumentValueAccessorT>
inline void CollisionFreeAggregationStateHashTable
::upsertValueAccessorSumHelper(
const Type *argument_type,
const attribute_id key_attr_id,
const attribute_id argument_id,
void *vec_table,
- ValueAccessorT *accessor) {
+ KeyValueAccessorT *key_accessor,
+ ArgumentValueAccessorT *argument_accessor) {
DCHECK_GE(key_attr_id, 0u);
DCHECK_GE(argument_id, 0u);
DCHECK(argument_type != nullptr);
@@ -407,35 +414,39 @@ inline void CollisionFreeAggregationStateHashTable
switch (argument_type->getTypeID()) {
case TypeID::kInt:
upsertValueAccessorIntegerSum<
- is_key_nullable, is_value_nullable, KeyT, int>(
+ use_two_accessors, is_key_nullable, is_argument_nullable, KeyT, int>(
key_attr_id,
argument_id,
static_cast<std::atomic<std::int64_t> *>(vec_table),
- accessor);
+ key_accessor,
+ argument_accessor);
return;
case TypeID::kLong:
upsertValueAccessorIntegerSum<
- is_key_nullable, is_value_nullable, KeyT, std::int64_t>(
+ use_two_accessors, is_key_nullable, is_argument_nullable, KeyT, std::int64_t>(
key_attr_id,
argument_id,
static_cast<std::atomic<std::int64_t> *>(vec_table),
- accessor);
+ key_accessor,
+ argument_accessor);
return;
case TypeID::kFloat:
upsertValueAccessorGenericSum<
- is_key_nullable, is_value_nullable, KeyT, float>(
+ use_two_accessors, is_key_nullable, is_argument_nullable, KeyT, float>(
key_attr_id,
argument_id,
static_cast<std::atomic<double> *>(vec_table),
- accessor);
+ key_accessor,
+ argument_accessor);
return;
case TypeID::kDouble:
upsertValueAccessorGenericSum<
- is_key_nullable, is_value_nullable, KeyT, double>(
+ use_two_accessors, is_key_nullable, is_argument_nullable, KeyT, double>(
key_attr_id,
argument_id,
static_cast<std::atomic<double> *>(vec_table),
- accessor);
+ key_accessor,
+ argument_accessor);
return;
default:
LOG(FATAL) << "Not supported";
@@ -461,49 +472,58 @@ inline void CollisionFreeAggregationStateHashTable
}
}
-template <bool is_key_nullable, typename KeyT, typename ValueAccessorT>
+template <bool use_two_accessors, bool is_key_nullable, typename KeyT,
+ typename KeyValueAccessorT, typename ArgumentValueAccessorT>
inline void CollisionFreeAggregationStateHashTable
::upsertValueAccessorCountUnary(
const attribute_id key_attr_id,
const attribute_id argument_id,
std::atomic<std::size_t> *vec_table,
- ValueAccessorT *accessor) {
- accessor->beginIteration();
- while (accessor->next()) {
+ KeyValueAccessorT *key_accessor,
+ ArgumentValueAccessorT *argument_accessor) {
+ key_accessor->beginIteration();
+ while (key_accessor->next()) {
+ if (use_two_accessors) {
+ argument_accessor->next();
+ }
const KeyT *key = static_cast<const KeyT *>(
- accessor->template getUntypedValue<is_key_nullable>(key_attr_id));
+ key_accessor->template getUntypedValue<is_key_nullable>(key_attr_id));
if (is_key_nullable && key == nullptr) {
continue;
}
const std::size_t loc = *key;
existence_map_->setBit(loc);
- if (accessor->getUntypedValue(argument_id) == nullptr) {
+ if (argument_accessor->getUntypedValue(argument_id) == nullptr) {
continue;
}
vec_table[loc].fetch_add(1u, std::memory_order_relaxed);
}
}
-template <bool is_key_nullable, bool is_argument_nullable,
+template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
typename KeyT, typename ArgumentT, typename StateT,
- typename ValueAccessorT>
+ typename KeyValueAccessorT, typename ArgumentValueAccessorT>
inline void CollisionFreeAggregationStateHashTable
::upsertValueAccessorIntegerSum(
const attribute_id key_attr_id,
const attribute_id argument_id,
std::atomic<StateT> *vec_table,
- ValueAccessorT *accessor) {
- accessor->beginIteration();
- while (accessor->next()) {
+ KeyValueAccessorT *key_accessor,
+ ArgumentValueAccessorT *argument_accessor) {
+ key_accessor->beginIteration();
+ while (key_accessor->next()) {
+ if (use_two_accessors) {
+ argument_accessor->next();
+ }
const KeyT *key = static_cast<const KeyT *>(
- accessor->template getUntypedValue<is_key_nullable>(key_attr_id));
+ key_accessor->template getUntypedValue<is_key_nullable>(key_attr_id));
if (is_key_nullable && key == nullptr) {
continue;
}
const std::size_t loc = *key;
existence_map_->setBit(loc);
const ArgumentT *argument = static_cast<const ArgumentT *>(
- accessor->template getUntypedValue<is_argument_nullable>(argument_id));
+ argument_accessor->template getUntypedValue<is_argument_nullable>(argument_id));
if (is_argument_nullable && argument == nullptr) {
continue;
}
@@ -511,26 +531,30 @@ inline void CollisionFreeAggregationStateHashTable
}
}
-template <bool is_key_nullable, bool is_argument_nullable,
+template <bool use_two_accessors, bool is_key_nullable, bool is_argument_nullable,
typename KeyT, typename ArgumentT, typename StateT,
- typename ValueAccessorT>
+ typename KeyValueAccessorT, typename ArgumentValueAccessorT>
inline void CollisionFreeAggregationStateHashTable
::upsertValueAccessorGenericSum(
const attribute_id key_attr_id,
const attribute_id argument_id,
std::atomic<StateT> *vec_table,
- ValueAccessorT *accessor) {
- accessor->beginIteration();
- while (accessor->next()) {
+ KeyValueAccessorT *key_accessor,
+ ArgumentValueAccessorT *argument_accessor) {
+ key_accessor->beginIteration();
+ while (key_accessor->next()) {
+ if (use_two_accessors) {
+ argument_accessor->next();
+ }
const KeyT *key = static_cast<const KeyT *>(
- accessor->template getUntypedValue<is_key_nullable>(key_attr_id));
+ key_accessor->template getUntypedValue<is_key_nullable>(key_attr_id));
if (is_key_nullable && key == nullptr) {
continue;
}
const std::size_t loc = *key;
existence_map_->setBit(loc);
const ArgumentT *argument = static_cast<const ArgumentT *>(
- accessor->template getUntypedValue<is_argument_nullable>(argument_id));
+ argument_accessor->template getUntypedValue<is_argument_nullable>(argument_id));
if (is_argument_nullable && argument == nullptr) {
continue;
}