summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2020-09-18 09:51:11 +0000
committerHåvard Pettersen <havardpe@oath.com>2020-09-18 09:51:11 +0000
commitc3f88e7df81531fa634df53f807a5e478367126b (patch)
tree743b00354558203633f2f29d3f9c2d5c9fd8be70
parent12c25d92a0a498087e514b0c53f1d182c5854790 (diff)
combine helper classes into one class
in order to handle index swapping more locally
-rw-r--r--eval/src/vespa/eval/eval/simple_value.cpp80
1 files changed, 40 insertions, 40 deletions
diff --git a/eval/src/vespa/eval/eval/simple_value.cpp b/eval/src/vespa/eval/eval/simple_value.cpp
index 9c6c10ac4e1..2f3c175ed1a 100644
--- a/eval/src/vespa/eval/eval/simple_value.cpp
+++ b/eval/src/vespa/eval/eval/simple_value.cpp
@@ -168,48 +168,49 @@ public:
}
};
-// Index references, possibly swapped to make sure the first index is
-// smaller than the second one. This will affect how the JoinSparseAddress
-// is set up as well.
-struct IndexRefs {
- bool swapped;
- const NewValue::Index &first;
- const NewValue::Index &second;
- IndexRefs(const NewValue::Index &lhs, const NewValue::Index &rhs)
- : swapped(rhs.size() < lhs.size()), first(swapped ? rhs : lhs), second(swapped ? lhs : rhs) {}
-};
-
-// contains the full address used when joining sparse indexes as well
-// as helper structures needed to use the value api.
-struct JoinSparseAddress {
- std::vector<vespalib::stringref> address;
- std::vector<vespalib::stringref*> first;
- std::vector<const vespalib::stringref*> overlap;
- std::vector<vespalib::stringref*> second_only;
+// Contains various state needed to perform the sparse part (all
+// mapped dimensions) of the join operation. Performs swapping of
+// sparse indexes to ensure that we look up entries from the smallest
+// index in the largest index.
+struct SparseJoinState {
+ bool swapped;
+ const NewValue::Index &first_index;
+ const NewValue::Index &second_index;
+ const std::vector<size_t> &second_view_dims;
+ std::vector<vespalib::stringref> full_address;
+ std::vector<vespalib::stringref*> first_address;
+ std::vector<const vespalib::stringref*> address_overlap;
+ std::vector<vespalib::stringref*> second_only_address;
size_t lhs_subspace;
size_t rhs_subspace;
size_t &first_subspace;
size_t &second_subspace;
- JoinSparseAddress(const SparseJoinPlan &plan, bool swap)
- : address(plan.sources.size()), first(), overlap(), second_only(),
+
+ SparseJoinState(const SparseJoinPlan &plan, const NewValue::Index &lhs, const NewValue::Index &rhs)
+ : swapped(rhs.size() < lhs.size()),
+ first_index(swapped ? rhs : lhs), second_index(swapped ? lhs : rhs),
+ second_view_dims(swapped ? plan.lhs_overlap : plan.rhs_overlap),
+ full_address(plan.sources.size()),
+ first_address(), address_overlap(), second_only_address(),
lhs_subspace(), rhs_subspace(),
- first_subspace(swap ? rhs_subspace : lhs_subspace),
- second_subspace(swap ? lhs_subspace : rhs_subspace)
+ first_subspace(swapped ? rhs_subspace : lhs_subspace),
+ second_subspace(swapped ? lhs_subspace : rhs_subspace)
{
- for (size_t i = 0; i < address.size(); ++i) {
+ auto first_source = swapped ? SparseJoinPlan::Source::RHS : SparseJoinPlan::Source::LHS;
+ for (size_t i = 0; i < full_address.size(); ++i) {
if (plan.sources[i] == SparseJoinPlan::Source::BOTH) {
- first.push_back(&address[i]);
- overlap.push_back(&address[i]);
- } else if ((plan.sources[i] == SparseJoinPlan::Source::RHS) == swap) {
- first.push_back(&address[i]);
+ first_address.push_back(&full_address[i]);
+ address_overlap.push_back(&full_address[i]);
+ } else if (plan.sources[i] == first_source) {
+ first_address.push_back(&full_address[i]);
} else {
- second_only.push_back(&address[i]);
+ second_only_address.push_back(&full_address[i]);
}
}
}
- ~JoinSparseAddress();
+ ~SparseJoinState();
};
-JoinSparseAddress::~JoinSparseAddress() = default;
+SparseJoinState::~SparseJoinState() = default;
// Treats all values as mixed tensors. Needs output cell type as well
// as input cell types since output cell type cannot always be
@@ -223,18 +224,17 @@ struct GenericJoin {
Fun fun(function);
auto lhs_cells = lhs.cells().typify<LCT>();
auto rhs_cells = rhs.cells().typify<RCT>();
- IndexRefs index_refs(lhs.index(), rhs.index());
- JoinSparseAddress addr(sparse_plan, index_refs.swapped);
- auto builder = factory.create_value_builder<OCT>(res_type, sparse_plan.sources.size(), dense_plan.out_size, index_refs.first.size());
- auto outer = index_refs.first.create_view({});
- auto inner = index_refs.second.create_view(index_refs.swapped ? sparse_plan.lhs_overlap : sparse_plan.rhs_overlap);
+ SparseJoinState state(sparse_plan, lhs.index(), rhs.index());
+ auto builder = factory.create_value_builder<OCT>(res_type, sparse_plan.sources.size(), dense_plan.out_size, state.first_index.size());
+ auto outer = state.first_index.create_view({});
+ auto inner = state.second_index.create_view(state.second_view_dims);
outer->lookup({});
- while (outer->next_result(addr.first, addr.first_subspace)) {
- inner->lookup(addr.overlap);
- while (inner->next_result(addr.second_only, addr.second_subspace)) {
- OCT *dst = builder->add_subspace(addr.address).begin();
+ while (outer->next_result(state.first_address, state.first_subspace)) {
+ inner->lookup(state.address_overlap);
+ while (inner->next_result(state.second_only_address, state.second_subspace)) {
+ OCT *dst = builder->add_subspace(state.full_address).begin();
auto join_cells = [&](size_t lhs_idx, size_t rhs_idx) { *dst++ = fun(lhs_cells[lhs_idx], rhs_cells[rhs_idx]); };
- dense_plan.execute(dense_plan.lhs_size * addr.lhs_subspace, dense_plan.rhs_size * addr.rhs_subspace, join_cells);
+ dense_plan.execute(dense_plan.lhs_size * state.lhs_subspace, dense_plan.rhs_size * state.rhs_subspace, join_cells);
}
}
return builder->build(std::move(builder));