From 7d4f1f300550dc7d03746a75dcb91329df140a4d Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Wed, 7 Oct 2015 17:48:46 +0200 Subject: [PATCH] Unified the Permutation State for Skiplist and HashIndex --- arangod/Indexes/HashIndex.cpp | 30 ------------------------------ arangod/Indexes/PathBasedIndex.cpp | 20 ++++++++++++++++++++ arangod/Indexes/PathBasedIndex.h | 29 +++++++++++++++++++++++++++++ arangod/Indexes/SkiplistIndex.cpp | 13 +++++++------ 4 files changed, 56 insertions(+), 36 deletions(-) diff --git a/arangod/Indexes/HashIndex.cpp b/arangod/Indexes/HashIndex.cpp index 552247d7d3..867aba186c 100644 --- a/arangod/Indexes/HashIndex.cpp +++ b/arangod/Indexes/HashIndex.cpp @@ -801,36 +801,6 @@ IndexIterator* HashIndex::iteratorForCondition (IndexIteratorContext* context, triagens::aql::AstNode* allVals = matcher.getAll(ast, this, node, reference); TRI_ASSERT(allVals->numMembers() == n); - struct PermutationState { - PermutationState (triagens::aql::AstNodeType type, triagens::aql::AstNode const* value, size_t attributePosition, size_t current, size_t n) - : type(type), - value(value), - attributePosition(attributePosition), - current(current), - n(n) { - } - - triagens::aql::AstNode const* getValue () const { - if (type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_EQ) { - TRI_ASSERT(current == 0); - return value; - } - else if (type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_IN) { - TRI_ASSERT(current < n); - return value->getMember(current); - } - - TRI_ASSERT(false); - return nullptr; - } - - triagens::aql::AstNodeType type; - triagens::aql::AstNode const* value; - size_t const attributePosition; - size_t current; - size_t const n; - }; - // initialize permutations std::vector permutationStates; permutationStates.reserve(n); diff --git a/arangod/Indexes/PathBasedIndex.cpp b/arangod/Indexes/PathBasedIndex.cpp index 2f5905f840..7134db5a25 100644 --- a/arangod/Indexes/PathBasedIndex.cpp +++ b/arangod/Indexes/PathBasedIndex.cpp @@ -28,6 +28,7 @@ //////////////////////////////////////////////////////////////////////////////// #include "PathBasedIndex.h" +#include "Aql/AstNode.h" #include "Basics/logging.h" using namespace triagens::arango; @@ -36,6 +37,25 @@ using namespace triagens::arango; // --SECTION-- class PathBasedIndex // ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// --SECTION-- struct PermutationState +// ----------------------------------------------------------------------------- + +triagens::aql::AstNode const* PathBasedIndex::PermutationState::getValue () const { + if (type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_EQ) { + TRI_ASSERT(current == 0); + return value; + } + else if (type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_IN) { + TRI_ASSERT(current < n); + return value->getMember(current); + } + + TRI_ASSERT(false); + return nullptr; +} + + // ----------------------------------------------------------------------------- // --SECTION-- constructors and destructors // ----------------------------------------------------------------------------- diff --git a/arangod/Indexes/PathBasedIndex.h b/arangod/Indexes/PathBasedIndex.h index af2f6fac65..8e0cb426a8 100644 --- a/arangod/Indexes/PathBasedIndex.h +++ b/arangod/Indexes/PathBasedIndex.h @@ -39,15 +39,44 @@ class VocShaper; + // ----------------------------------------------------------------------------- // --SECTION-- class PathBasedIndex // ----------------------------------------------------------------------------- namespace triagens { + namespace aql { + enum AstNodeType : uint32_t; + } + namespace arango { class PathBasedIndex : public Index { + protected: + + struct PermutationState { + PermutationState (triagens::aql::AstNodeType type, triagens::aql::AstNode const* value, size_t attributePosition, size_t current, size_t n) + : type(type), + value(value), + attributePosition(attributePosition), + current(current), + n(n) { + } + + triagens::aql::AstNode const* getValue () const; + + triagens::aql::AstNodeType type; + triagens::aql::AstNode const* value; + size_t const attributePosition; + size_t current; + size_t const n; + }; + +// ----------------------------------------------------------------------------- +// --SECTION-- shared Permuation struct +// ----------------------------------------------------------------------------- + // ----------------------------------------------------------------------------- // --SECTION-- constructors / destructors // ----------------------------------------------------------------------------- diff --git a/arangod/Indexes/SkiplistIndex.cpp b/arangod/Indexes/SkiplistIndex.cpp index fc0742db6c..ce784bbcbe 100644 --- a/arangod/Indexes/SkiplistIndex.cpp +++ b/arangod/Indexes/SkiplistIndex.cpp @@ -1140,10 +1140,10 @@ IndexIterator* SkiplistIndex::iteratorForCondition (IndexIteratorContext* contex // We found an access for this field if (comp->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_EQ) { // This is an equalityCheck, we can continue with the next field - permutationStates.emplace_back(PermutationState(comp, value, 0, 1)); + permutationStates.emplace_back(PermutationState(comp->type, value, usedFields, 0, 1)); } else if (comp->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_IN) { - permutationStates.emplace_back(PermutationState(comp, value, 0, value->numMembers())); + permutationStates.emplace_back(PermutationState(comp->type, value, usedFields, 0, value->numMembers())); } else { // This is a one-sided range @@ -1261,7 +1261,7 @@ IndexIterator* SkiplistIndex::iteratorForCondition (IndexIteratorContext* contex rangeOperator.reset(TRI_CreateIndexOperator(TRI_AND_INDEX_OPERATOR, rangeOperator.release(), tmpOp.release(), - parameter, + nullptr, _shaper, 2)); } @@ -1293,7 +1293,7 @@ IndexIterator* SkiplistIndex::iteratorForCondition (IndexIteratorContext* contex std::unique_ptr tmpOp(TRI_CreateIndexOperator(TRI_EQ_INDEX_OPERATOR, nullptr, nullptr, - parameter, + parameter.get(), _shaper, usedFields)); if (rangeOperator != nullptr) { @@ -1301,7 +1301,7 @@ IndexIterator* SkiplistIndex::iteratorForCondition (IndexIteratorContext* contex std::unique_ptr combinedOp(TRI_CreateIndexOperator(TRI_AND_INDEX_OPERATOR, rangeOperator.get(), tmpOp.get(), - parameter, + nullptr, _shaper, 2)); tmpOp.release(); @@ -1314,6 +1314,7 @@ IndexIterator* SkiplistIndex::iteratorForCondition (IndexIteratorContext* contex } } + size_t current = 0; // now permute while (true) { if (++permutationStates[current].current < permutationStates[current].n) { @@ -1324,7 +1325,7 @@ IndexIterator* SkiplistIndex::iteratorForCondition (IndexIteratorContext* contex permutationStates[current].current = 0; - if (++current >= n) { + if (++current >= usedFields) { done = true; break; }