//////////////////////////////////////////////////////////////////////////////// /// DISCLAIMER /// /// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany /// Copyright 2004-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 ArangoDB GmbH, Cologne, Germany /// /// @author Jan Steemann /// @author Michael Hackstein //////////////////////////////////////////////////////////////////////////////// #ifndef ARANGOD_AQL_INDEX_BLOCK_H #define ARANGOD_AQL_INDEX_BLOCK_H 1 #include "Aql/ExecutionBlock.h" #include "Aql/ExecutionNode.h" #include "Aql/IndexNode.h" #include "Utils/AqlTransaction.h" struct TRI_doc_mptr_t; namespace arangodb { struct OperationCursor; namespace velocypack { class Slice; } namespace aql { class AqlItemBlock; struct AstNode; struct Collection; class ExecutionEngine; class IndexBlock : public ExecutionBlock { public: IndexBlock(ExecutionEngine* engine, IndexNode const* ep); ~IndexBlock(); /// @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; private: /// @brief adds a SORT to a dynamic IN condition arangodb::aql::AstNode* makeUnique(arangodb::aql::AstNode*) const; /// @brief create an iterator object std::shared_ptr createCursor(); /// @brief Forwards _cursor to the next available index void startNextCursor(); /// @brief Initializes the indexes bool initIndexes(); /// @brief whether or not one of the bounds expressions requires V8 bool hasV8Expression() const; /// @brief execute the bounds expressions void executeExpressions(); /// @brief continue fetching of documents bool readIndex(size_t atMost); /// @brief frees the memory for all non-constant expressions void cleanupNonConstExpressions(); private: /// @brief collection Collection const* _collection; /// @brief document result std::shared_ptr _result; /// @brief document buffer std::vector _documents; /// @brief current position in _allDocs size_t _posInDocs; /// @brief current position in _indexes size_t _currentIndex; /// @brief _indexes holds all Indexes used in this block std::vector _indexes; /// @brief _nonConstExpressions, list of all non const expressions, mapped /// by their _condition node path indexes std::vector _nonConstExpressions; /// @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 _cursor: holds the index cursor found using /// getIndexCursor (if any) so that it can be read in chunks and not /// necessarily all at once. std::shared_ptr _cursor; /// @brief _condition: holds the complete condition this Block can serve for AstNode const* _condition; /// @brief set of already returned documents. Used to make the result distinct std::unordered_set _alreadyReturned; /// @brief whether or not at least one expression uses v8 bool _hasV8Expression; }; } // namespace arangodb::aql } // namespace arangodb #endif