//////////////////////////////////////////////////////////////////////////////// /// @brief AQL IndexRangeBlock /// /// @file /// /// DISCLAIMER /// /// Copyright 2010-2014 triagens GmbH, Cologne, Germany /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. /// You may obtain a copy of the License at /// /// http://www.apache.org/licenses/LICENSE-2.0 /// /// Unless required by applicable law or agreed to in writing, software /// distributed under the License is distributed on an "AS IS" BASIS, /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. /// See the License for the specific language governing permissions and /// limitations under the License. /// /// Copyright holder is triAGENS GmbH, Cologne, Germany /// /// @author Max Neunhoeffer /// @author Copyright 2014, triagens GmbH, Cologne, Germany //////////////////////////////////////////////////////////////////////////////// #ifndef ARANGODB_AQL_INDEX_RANGE_BLOCK_H #define ARANGODB_AQL_INDEX_RANGE_BLOCK_H 1 #include "Aql/Collection.h" #include "Aql/ExecutionBlock.h" #include "Aql/ExecutionNode.h" #include "Indexes/SkiplistIndex.h" #include "Utils/AqlTransaction.h" #include "VocBase/shaped-json.h" struct TRI_doc_mptr_copy_t; struct TRI_edge_index_iterator_t; struct TRI_hash_index_element_multi_s; namespace triagens { namespace aql { class AqlItemBlock; class ExecutionEngine; // ----------------------------------------------------------------------------- // --SECTION-- IndexRangeBlock // ----------------------------------------------------------------------------- class IndexRangeBlock : public ExecutionBlock { public: IndexRangeBlock (ExecutionEngine* engine, IndexRangeNode const* ep); ~IndexRangeBlock (); //////////////////////////////////////////////////////////////////////////////// /// @brief initialize, here we fetch all docs from the database //////////////////////////////////////////////////////////////////////////////// int initialize () override; //////////////////////////////////////////////////////////////////////////////// /// @brief initializeCursor, here we release our docs from this collection //////////////////////////////////////////////////////////////////////////////// int initializeCursor (AqlItemBlock* items, size_t pos) override; AqlItemBlock* getSome (size_t atLeast, size_t atMost) override final; //////////////////////////////////////////////////////////////////////////////// // skip between atLeast and atMost, returns the number actually skipped . . . // will only return less than atLeast if there aren't atLeast many // things to skip overall. //////////////////////////////////////////////////////////////////////////////// size_t skipSome (size_t atLeast, size_t atMost) override final; // ----------------------------------------------------------------------------- // --SECTION-- private methods // ----------------------------------------------------------------------------- private: //////////////////////////////////////////////////////////////////////////////// /// @brief whether or not the high bound values should be taken into account /// they can be ignored for indexes that only support equality conditions, /// i.e. primary index, edge index and hash index //////////////////////////////////////////////////////////////////////////////// bool useHighBounds () const; //////////////////////////////////////////////////////////////////////////////// /// @brief whether or not one of the bounds expressions requires V8 //////////////////////////////////////////////////////////////////////////////// bool hasV8Expression () const; //////////////////////////////////////////////////////////////////////////////// /// @brief build the bounds expressions //////////////////////////////////////////////////////////////////////////////// void buildExpressions (); //////////////////////////////////////////////////////////////////////////////// /// @brief free _condition if it belongs to us //////////////////////////////////////////////////////////////////////////////// void freeCondition (); //////////////////////////////////////////////////////////////////////////////// /// @brief continue fetching of documents //////////////////////////////////////////////////////////////////////////////// bool readIndex (size_t atMost); //////////////////////////////////////////////////////////////////////////////// /// @brief set up the index for reading. This should be called once per incoming /// block. //////////////////////////////////////////////////////////////////////////////// bool initRanges (); //////////////////////////////////////////////////////////////////////////////// /// @brief read using the primary index //////////////////////////////////////////////////////////////////////////////// void readPrimaryIndex (IndexOrCondition const&); //////////////////////////////////////////////////////////////////////////////// /// @brief destroy the hash index search value //////////////////////////////////////////////////////////////////////////////// void destroyHashIndexSearchValues (); //////////////////////////////////////////////////////////////////////////////// /// @brief set up a hash index search value //////////////////////////////////////////////////////////////////////////////// bool setupHashIndexSearchValue (IndexAndCondition const&); //////////////////////////////////////////////////////////////////////////////// /// @brief produce a reentrant hash index iterator //////////////////////////////////////////////////////////////////////////////// void getHashIndexIterator (IndexAndCondition const&); //////////////////////////////////////////////////////////////////////////////// /// @brief read using a hash index //////////////////////////////////////////////////////////////////////////////// void readHashIndex (size_t); //////////////////////////////////////////////////////////////////////////////// /// @brief this tries to create an edge iterator to read from the index. //////////////////////////////////////////////////////////////////////////////// void getEdgeIndexIterator (IndexAndCondition const&); //////////////////////////////////////////////////////////////////////////////// /// @brief read using an edge index //////////////////////////////////////////////////////////////////////////////// void readEdgeIndex (size_t atMost); //////////////////////////////////////////////////////////////////////////////// /// @brief this tries to create a skiplistIterator to read from the index. //////////////////////////////////////////////////////////////////////////////// void getSkiplistIterator (IndexAndCondition const&); //////////////////////////////////////////////////////////////////////////////// /// @brief read using a skiplist index //////////////////////////////////////////////////////////////////////////////// void readSkiplistIndex (size_t atMost); //////////////////////////////////////////////////////////////////////////////// // @brief: sorts the index range conditions and resets _posInRanges to 0 //////////////////////////////////////////////////////////////////////////////// void sortConditions (); //////////////////////////////////////////////////////////////////////////////// /// @brief andCombineRangeInfoVecs: combine the arguments into a single vector, /// by intersecting every pair of range infos and inserting them in the returned /// value if the intersection is valid. //////////////////////////////////////////////////////////////////////////////// std::vector andCombineRangeInfoVecs (std::vector const&, std::vector const&) const; //////////////////////////////////////////////////////////////////////////////// /// @brief cartesian: form the cartesian product of the inner vectors. This is /// required in case a dynamic bound evaluates to a list, then we have an /// "and" condition containing an "or" condition, which we must then distribute. //////////////////////////////////////////////////////////////////////////////// IndexOrCondition* cartesian (std::vector> const&) const; //////////////////////////////////////////////////////////////////////////////// /// @brief: subclass for comparing IndexAndConditions in _condition. Similar to /// OurLessThan in the SortBlock //////////////////////////////////////////////////////////////////////////////// class SortFunc { public: SortFunc (std::vector> const& prefix, IndexOrCondition* condition, bool reverse) : _prefix(prefix), _condition(condition), _reverse(reverse) { } bool operator() (size_t const&, size_t const&) const; private: std::vector> const& _prefix; IndexOrCondition* _condition; bool const _reverse; }; // ----------------------------------------------------------------------------- // --SECTION-- private variables // ----------------------------------------------------------------------------- private: //////////////////////////////////////////////////////////////////////////////// /// @brief collection //////////////////////////////////////////////////////////////////////////////// Collection const* _collection; //////////////////////////////////////////////////////////////////////////////// /// @brief document buffer //////////////////////////////////////////////////////////////////////////////// std::vector _documents; //////////////////////////////////////////////////////////////////////////////// /// @brief current position in _allDocs //////////////////////////////////////////////////////////////////////////////// size_t _posInDocs; //////////////////////////////////////////////////////////////////////////////// /// @brief _allBoundsConstant, this indicates whether all given bounds /// are constant //////////////////////////////////////////////////////////////////////////////// std::vector _allBoundsConstant; bool _anyBoundVariable; //////////////////////////////////////////////////////////////////////////////// /// @brief _allBoundsConstant, this indicates whether all given bounds /// are constant //////////////////////////////////////////////////////////////////////////////// std::vector _allVariableBoundExpressions; //////////////////////////////////////////////////////////////////////////////// /// @brief _inVars, a vector containing for each expression above /// a vector of Variable*, used to execute the expression ///////////////////////////////////////////////////////////////////////////////// std::vector> _inVars; //////////////////////////////////////////////////////////////////////////////// /// @brief _inRegs, a vector containing for each expression above /// a vector of RegisterId, used to execute the expression //////////////////////////////////////////////////////////////////////////////// std::vector> _inRegs; //////////////////////////////////////////////////////////////////////////////// /// @brief _skiplistIterator: holds the skiplist iterator found using /// getSkiplistIterator (if any) so that it can be read in chunks and not /// necessarily all at once. //////////////////////////////////////////////////////////////////////////////// triagens::arango::SkiplistIterator* _skiplistIterator; //////////////////////////////////////////////////////////////////////////////// /// @brief _edgeIterator: holds the edge iterator found using /// getEdgeIndexIterator (if any) so that it can be read in chunks and not /// necessarily all at once. //////////////////////////////////////////////////////////////////////////////// struct TRI_edge_index_iterator_t* _edgeIndexIterator; //////////////////////////////////////////////////////////////////////////////// /// @brief current search value for hash index lookup //////////////////////////////////////////////////////////////////////////////// TRI_index_search_value_t _hashIndexSearchValue; //////////////////////////////////////////////////////////////////////////////// /// @brief reentrant hash index iterator state //////////////////////////////////////////////////////////////////////////////// TRI_index_element_t* _hashNextElement; //////////////////////////////////////////////////////////////////////////////// /// @brief reentrant edge index iterator state //////////////////////////////////////////////////////////////////////////////// void* _edgeNextElement; //////////////////////////////////////////////////////////////////////////////// /// @brief _condition: holds the IndexAndCondition for the current incoming block, /// this is just the _ranges[_rangesPos] member of the plan node if _allBoundsConstant /// otherwise it is reevaluated every time initIndex is called, i.e. once per /// incoming block. //////////////////////////////////////////////////////////////////////////////// IndexOrCondition* _condition; //////////////////////////////////////////////////////////////////////////////// /// @brief _flag: since readIndex for primary, hash, edges indexes reads the /// whole index, this is if initIndex has been called but readIndex has /// not been called, otherwise it is to avoid rereading the entire index /// with successive calls to readIndex. ////////////////////////////////////////////////////////////////////////////////// bool _flag; size_t _posInRanges; std::vector _sortCoords; //////////////////////////////////////////////////////////////////////////////// /// @brief _freeCondition: whether or not the _condition is owned by the /// IndexRangeBlock and must be freed //////////////////////////////////////////////////////////////////////////////// bool _freeCondition; bool _hasV8Expression; }; } // namespace triagens::aql } // namespace triagens #endif // Local Variables: // mode: outline-minor // outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)" // End: