mirror of https://gitee.com/bigwinds/arangodb
struct Index
This commit is contained in:
parent
49237ef55a
commit
0d9cdfc87c
|
@ -0,0 +1,195 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Aql, collection
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 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 Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Collection.h"
|
||||
#include "Aql/ExecutionEngine.h"
|
||||
#include "Basics/StringUtils.h"
|
||||
#include "Cluster/ClusterInfo.h"
|
||||
#include "Utils/Exception.h"
|
||||
#include "VocBase/document-collection.h"
|
||||
#include "VocBase/transaction.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
||||
using namespace triagens::aql;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- constructors / destructors
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a collection wrapper
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Collection::Collection (std::string const& name,
|
||||
struct TRI_vocbase_s* vocbase,
|
||||
TRI_transaction_type_e accessType)
|
||||
: name(name),
|
||||
currentShard(),
|
||||
vocbase(vocbase),
|
||||
collection(nullptr),
|
||||
accessType(accessType) {
|
||||
|
||||
TRI_ASSERT(! name.empty());
|
||||
TRI_ASSERT(vocbase != nullptr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destroy a collection wrapper
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Collection::~Collection () {
|
||||
for (auto idx : indexes) {
|
||||
delete idx;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief count the LOCAL number of documents in the collection
|
||||
/// TODO: must be adjusted for clusters
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
size_t Collection::count () const {
|
||||
if (numDocuments == UNINITIALIZED) {
|
||||
auto document = documentCollection();
|
||||
// cache the result
|
||||
numDocuments = static_cast<int64_t>(document->size(document));
|
||||
}
|
||||
|
||||
return static_cast<size_t>(numDocuments);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the shard ids of a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<std::string> Collection::shardIds () const {
|
||||
auto clusterInfo = triagens::arango::ClusterInfo::instance();
|
||||
auto collectionInfo = clusterInfo->getCollection(std::string(vocbase->_name), name);
|
||||
if (collectionInfo.get() == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "collection not found");
|
||||
}
|
||||
|
||||
std::vector<std::string> ids;
|
||||
for (auto const& it : collectionInfo.get()->shardIds()) {
|
||||
ids.emplace_back(it.first);
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the indexes of the collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<Index*> Collection::getIndexes () {
|
||||
fillIndexes();
|
||||
|
||||
return indexes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return an index by its id
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Index* Collection::getIndex (TRI_idx_iid_t id) const {
|
||||
fillIndexes();
|
||||
|
||||
for (auto idx : indexes) {
|
||||
if (idx->id == id) {
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return an index by its id
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Index* Collection::getIndex (std::string const& id) const {
|
||||
return getIndex(triagens::basics::StringUtils::uint64(id));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief fills the index list for the collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Collection::fillIndexes () const {
|
||||
if (! indexes.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExecutionEngine::isCoordinator()) {
|
||||
// coordinator case, remote collection
|
||||
auto clusterInfo = triagens::arango::ClusterInfo::instance();
|
||||
auto collectionInfo = clusterInfo->getCollection(std::string(vocbase->_name), triagens::basics::StringUtils::itoa(collection->_cid));
|
||||
if (collectionInfo.get() == nullptr || (*collectionInfo).empty()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "collection not found");
|
||||
}
|
||||
|
||||
TRI_json_t const* json = (*collectionInfo).getIndexes();
|
||||
|
||||
if (TRI_IsListJson(json)) {
|
||||
size_t const n = TRI_LengthListJson(json);
|
||||
indexes.reserve(n);
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
TRI_json_t const* v = TRI_LookupListJson(json, i);
|
||||
// indexes.push_back(static_cast<TRI_index_t*>(document->_allIndexes._buffer[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// local collection
|
||||
auto document = documentCollection();
|
||||
size_t const n = document->_allIndexes._length;
|
||||
indexes.reserve(n);
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
indexes.emplace_back(new Index(static_cast<TRI_index_t*>(document->_allIndexes._buffer[i])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
|
@ -31,8 +31,7 @@
|
|||
#define ARANGODB_AQL_COLLECTION_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "Cluster/ClusterInfo.h"
|
||||
#include "Utils/Exception.h"
|
||||
#include "Aql/Index.h"
|
||||
#include "VocBase/document-collection.h"
|
||||
#include "VocBase/transaction.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
@ -54,21 +53,11 @@ namespace triagens {
|
|||
Collection (Collection const&) = delete;
|
||||
Collection () = delete;
|
||||
|
||||
Collection (std::string const& name,
|
||||
struct TRI_vocbase_s* vocbase,
|
||||
TRI_transaction_type_e accessType)
|
||||
: name(name),
|
||||
currentShard(),
|
||||
vocbase(vocbase),
|
||||
collection(nullptr),
|
||||
accessType(accessType) {
|
||||
|
||||
TRI_ASSERT(! name.empty());
|
||||
TRI_ASSERT(vocbase != nullptr);
|
||||
}
|
||||
Collection (std::string const&,
|
||||
struct TRI_vocbase_s*,
|
||||
TRI_transaction_type_e);
|
||||
|
||||
~Collection () {
|
||||
}
|
||||
~Collection ();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
|
@ -78,7 +67,7 @@ namespace triagens {
|
|||
/// @brief set the current shard
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setCurrentShard (std::string const& shard) {
|
||||
inline void setCurrentShard (std::string const& shard) {
|
||||
currentShard = shard;
|
||||
}
|
||||
|
||||
|
@ -86,7 +75,7 @@ namespace triagens {
|
|||
/// @brief remove the current shard
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void resetCurrentShard () {
|
||||
inline void resetCurrentShard () {
|
||||
currentShard = "";
|
||||
}
|
||||
|
||||
|
@ -99,6 +88,21 @@ namespace triagens {
|
|||
return collection->_cid;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the name of the collection, translated for the sharding
|
||||
/// case. this will return currentShard if it is set, and name otherwise
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string getName () const {
|
||||
if (! currentShard.empty()) {
|
||||
// sharding case: return the current shard name instead of the collection name
|
||||
return currentShard;
|
||||
}
|
||||
|
||||
// non-sharding case: simply return the name
|
||||
return name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the pointer to the document collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -133,62 +137,43 @@ namespace triagens {
|
|||
/// TODO: must be adjusted for clusters
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
size_t count () const {
|
||||
if (numDocuments == UNINITIALIZED) {
|
||||
auto document = documentCollection();
|
||||
// cache the result
|
||||
numDocuments = static_cast<int64_t>(document->size(document));
|
||||
}
|
||||
|
||||
return static_cast<size_t>(numDocuments);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the shard information for a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::map<std::string, std::string> shardInfo () const {
|
||||
auto clusterInfo = triagens::arango::ClusterInfo::instance();
|
||||
auto collectionInfo = clusterInfo->getCollection(std::string(vocbase->_name), name);
|
||||
if (collectionInfo.get() == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "collection not found");
|
||||
}
|
||||
|
||||
return collectionInfo.get()->shardIds();
|
||||
}
|
||||
size_t count () const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the shard ids of a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<std::string> shardIds () const {
|
||||
auto clusterInfo = triagens::arango::ClusterInfo::instance();
|
||||
auto collectionInfo = clusterInfo->getCollection(std::string(vocbase->_name), name);
|
||||
if (collectionInfo.get() == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "collection not found");
|
||||
}
|
||||
|
||||
std::vector<std::string> ids;
|
||||
for (auto const& it : collectionInfo.get()->shardIds()) {
|
||||
ids.emplace_back(it.first);
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
std::vector<std::string> shardIds () const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the name of the collection, translated for the sharding
|
||||
/// case
|
||||
/// @brief returns the indexes of the collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string getName () const {
|
||||
if (! currentShard.empty()) {
|
||||
// sharding case: return the current shard name instead of the collection name
|
||||
return currentShard;
|
||||
}
|
||||
std::vector<Index*> getIndexes ();
|
||||
|
||||
// non-sharding case: simply return the name
|
||||
return name;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return an index by its id
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Index* getIndex (TRI_idx_iid_t) const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return an index by its id
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Index* getIndex (std::string const&) const;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief fills the index list for the collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private:
|
||||
|
||||
void fillIndexes () const;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
|
@ -205,12 +190,13 @@ namespace triagens {
|
|||
|
||||
public:
|
||||
|
||||
TRI_vocbase_t* vocbase;
|
||||
TRI_vocbase_col_t* collection;
|
||||
TRI_transaction_type_e accessType;
|
||||
mutable int64_t numDocuments = UNINITIALIZED;
|
||||
TRI_vocbase_t* vocbase;
|
||||
TRI_vocbase_col_t* collection;
|
||||
TRI_transaction_type_e accessType;
|
||||
mutable std::vector<Index*> indexes;
|
||||
mutable int64_t numDocuments = UNINITIALIZED;
|
||||
|
||||
static int64_t const UNINITIALIZED = -1;
|
||||
static int64_t const UNINITIALIZED = -1;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -961,16 +961,16 @@ bool IndexRangeBlock::readIndex () {
|
|||
condition = newCondition.get();
|
||||
}
|
||||
|
||||
if (en->_index->_type == TRI_IDX_TYPE_PRIMARY_INDEX) {
|
||||
if (en->_index->type == TRI_IDX_TYPE_PRIMARY_INDEX) {
|
||||
readPrimaryIndex(*condition);
|
||||
}
|
||||
else if (en->_index->_type == TRI_IDX_TYPE_HASH_INDEX) {
|
||||
else if (en->_index->type == TRI_IDX_TYPE_HASH_INDEX) {
|
||||
readHashIndex(*condition);
|
||||
}
|
||||
else if (en->_index->_type == TRI_IDX_TYPE_SKIPLIST_INDEX) {
|
||||
else if (en->_index->type == TRI_IDX_TYPE_SKIPLIST_INDEX) {
|
||||
readSkiplistIndex(*condition);
|
||||
}
|
||||
else if (en->_index->_type == TRI_IDX_TYPE_EDGE_INDEX) {
|
||||
else if (en->_index->type == TRI_IDX_TYPE_EDGE_INDEX) {
|
||||
readEdgeIndex(*condition);
|
||||
}
|
||||
else {
|
||||
|
@ -1221,7 +1221,7 @@ void IndexRangeBlock::readPrimaryIndex (IndexOrCondition const& ranges) {
|
|||
|
||||
void IndexRangeBlock::readHashIndex (IndexOrCondition const& ranges) {
|
||||
auto en = static_cast<IndexRangeNode const*>(getPlanNode());
|
||||
TRI_index_t* idx = const_cast<TRI_index_t*>(en->_index);
|
||||
TRI_index_t* idx = en->_index->data;
|
||||
TRI_ASSERT(idx != nullptr);
|
||||
TRI_hash_index_t* hashIndex = (TRI_hash_index_t*) idx;
|
||||
|
||||
|
@ -1381,7 +1381,7 @@ void IndexRangeBlock::readEdgeIndex (IndexOrCondition const& ranges) {
|
|||
|
||||
void IndexRangeBlock::readSkiplistIndex (IndexOrCondition const& ranges) {
|
||||
auto en = static_cast<IndexRangeNode const*>(getPlanNode());
|
||||
TRI_index_t* idx = const_cast<TRI_index_t*>(en->_index);
|
||||
TRI_index_t* idx = en->_index->data;
|
||||
TRI_ASSERT(idx != nullptr);
|
||||
|
||||
TRI_shaper_t* shaper = _collection->documentCollection()->getShaper();
|
||||
|
@ -3783,8 +3783,6 @@ double const RemoteBlock::defaultTimeOut = 3600.0;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void throwExceptionAfterBadSyncRequest (ClusterCommResult* res) {
|
||||
std::cout << "IN THROW EXCEPTION AFTER BAD SYNC REQUEST\n";
|
||||
|
||||
if (res->status == CL_COMM_TIMEOUT) {
|
||||
std::cout << "GOT TIMEOUT\n";
|
||||
// No reply, we give up:
|
||||
|
|
|
@ -316,25 +316,26 @@ void ExecutionNode::appendAsString (std::string& st, int indent) {
|
|||
/// match->index==nullptr means no match at all.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExecutionNode::IndexMatch ExecutionNode::CompareIndex (TRI_index_t const* idx,
|
||||
ExecutionNode::IndexMatch ExecutionNode::CompareIndex (Index const* idx,
|
||||
ExecutionNode::IndexMatchVec const& attrs) {
|
||||
IndexMatch match;
|
||||
|
||||
if (idx->_type != TRI_IDX_TYPE_SKIPLIST_INDEX ||
|
||||
if (idx->type != TRI_IDX_TYPE_SKIPLIST_INDEX ||
|
||||
attrs.empty()) {
|
||||
return match;
|
||||
}
|
||||
|
||||
size_t const idxFields = idx->fields.size();
|
||||
size_t const n = attrs.size();
|
||||
match.doesMatch = (idx->_fields._length >= n);
|
||||
match.doesMatch = (idxFields >= n);
|
||||
|
||||
size_t interestingCount = 0;
|
||||
size_t forwardCount = 0;
|
||||
size_t backwardCount = 0;
|
||||
size_t j = 0;
|
||||
|
||||
for (; (j < idx->_fields._length && j < n); j++) {
|
||||
if (std::string(idx->_fields._buffer[j]) == attrs[j].first) {
|
||||
for (; (j < idxFields && j < n); j++) {
|
||||
if (idx->fields[j] == attrs[j].first) {
|
||||
if (attrs[j].second) {
|
||||
// ascending
|
||||
match.matches.push_back(FORWARD_MATCH);
|
||||
|
@ -363,8 +364,8 @@ ExecutionNode::IndexMatch ExecutionNode::CompareIndex (TRI_index_t const* idx,
|
|||
if (interestingCount > 0) {
|
||||
match.index = idx;
|
||||
|
||||
if (j < idx->_fields._length) { // more index fields
|
||||
for (; j < idx->_fields._length; j++) {
|
||||
if (j < idxFields) { // more index fields
|
||||
for (; j < idxFields; j++) {
|
||||
match.matches.push_back(NOT_COVERED_IDX);
|
||||
}
|
||||
}
|
||||
|
@ -877,11 +878,11 @@ ExecutionNode* EnumerateCollectionNode::clone (ExecutionPlan* plan,
|
|||
/// attributes passed)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
size_t EnumerateCollectionNode::getUsableFieldsOfIndex (TRI_index_t const* idx,
|
||||
size_t EnumerateCollectionNode::getUsableFieldsOfIndex (Index const* idx,
|
||||
std::unordered_set<std::string> const& attrs) const {
|
||||
size_t count = 0;
|
||||
for (size_t i = 0; i < idx->_fields._length; i++) {
|
||||
if (attrs.find(std::string(idx->_fields._buffer[i])) == attrs.end()) {
|
||||
for (size_t i = 0; i < idx->fields.size(); i++) {
|
||||
if (attrs.find(idx->fields[i]) == attrs.end()) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -899,18 +900,15 @@ size_t EnumerateCollectionNode::getUsableFieldsOfIndex (TRI_index_t const* idx,
|
|||
// of the collection of this node, modifies its arguments <idxs>, and <prefixes>
|
||||
// so that . . .
|
||||
|
||||
void EnumerateCollectionNode::getIndexesForIndexRangeNode
|
||||
(std::unordered_set<std::string> const& attrs, std::vector<TRI_index_t*>& idxs,
|
||||
std::vector<size_t>& prefixes) const {
|
||||
void EnumerateCollectionNode::getIndexesForIndexRangeNode (std::unordered_set<std::string> const& attrs,
|
||||
std::vector<Index*>& idxs,
|
||||
std::vector<size_t>& prefixes) const {
|
||||
|
||||
TRI_document_collection_t* document = _collection->documentCollection();
|
||||
TRI_ASSERT(document != nullptr);
|
||||
|
||||
for (size_t i = 0; i < document->_allIndexes._length; ++i) {
|
||||
TRI_index_t* idx = static_cast<TRI_index_t*>(document->_allIndexes._buffer[i]);
|
||||
auto&& indexes = _collection->getIndexes();
|
||||
for (auto idx : indexes) {
|
||||
TRI_ASSERT(idx != nullptr);
|
||||
|
||||
auto const idxType = idx->_type;
|
||||
auto const idxType = idx->type;
|
||||
|
||||
if (idxType != TRI_IDX_TYPE_PRIMARY_INDEX &&
|
||||
idxType != TRI_IDX_TYPE_HASH_INDEX &&
|
||||
|
@ -936,7 +934,7 @@ void EnumerateCollectionNode::getIndexesForIndexRangeNode
|
|||
else if (idxType == TRI_IDX_TYPE_HASH_INDEX) {
|
||||
prefix = getUsableFieldsOfIndex(idx, attrs);
|
||||
|
||||
if (prefix == idx->_fields._length) {
|
||||
if (prefix == idx->fields.size()) {
|
||||
// can use index
|
||||
idxs.push_back(idx);
|
||||
// <prefixes> not used for this type of index
|
||||
|
@ -944,7 +942,7 @@ void EnumerateCollectionNode::getIndexesForIndexRangeNode
|
|||
}
|
||||
}
|
||||
|
||||
else if (idx->_type == TRI_IDX_TYPE_SKIPLIST_INDEX) {
|
||||
else if (idxType == TRI_IDX_TYPE_SKIPLIST_INDEX) {
|
||||
prefix = getUsableFieldsOfIndex(idx, attrs);
|
||||
|
||||
if (prefix > 0) {
|
||||
|
@ -975,21 +973,17 @@ std::vector<EnumerateCollectionNode::IndexMatch>
|
|||
EnumerateCollectionNode::getIndicesOrdered (IndexMatchVec const& attrs) const {
|
||||
|
||||
std::vector<IndexMatch> out;
|
||||
TRI_document_collection_t* document = _collection->documentCollection();
|
||||
size_t const n = document->_allIndexes._length;
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
TRI_index_t* idx = static_cast<TRI_index_t*>(document->_allIndexes._buffer[i]);
|
||||
|
||||
auto&& indexes = _collection->getIndexes();
|
||||
for (auto idx : indexes) {
|
||||
IndexMatch match = CompareIndex(idx, attrs);
|
||||
if (match.index != nullptr) {
|
||||
out.push_back(match);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- methods of EnumerateListNode
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -1073,7 +1067,7 @@ void IndexRangeNode::toJsonHelper (triagens::basics::Json& nodes,
|
|||
("outVariable", _outVariable->toJson())
|
||||
("ranges", ranges);
|
||||
|
||||
TRI_json_t* idxJson = _index->json(_index);
|
||||
TRI_json_t* idxJson = _index->data->json(_index->data);
|
||||
|
||||
if (idxJson != nullptr) {
|
||||
try {
|
||||
|
@ -1152,9 +1146,9 @@ IndexRangeNode::IndexRangeNode (ExecutionPlan* plan,
|
|||
// TODO the following could be a constructor method for
|
||||
// an Index object when these are actually used
|
||||
auto index = JsonHelper::checkAndGetArrayValue(json.json(), "index");
|
||||
auto iid = JsonHelper::checkAndGetStringValue(index, "id");
|
||||
auto iid = JsonHelper::checkAndGetStringValue(index, "id");
|
||||
|
||||
_index = TRI_LookupIndex(_collection->documentCollection(), basics::StringUtils::uint64(iid));
|
||||
_index = _collection->getIndex(iid);
|
||||
_reverse = JsonHelper::checkAndGetBooleanValue(json.json(), "reverse");
|
||||
}
|
||||
|
||||
|
@ -1174,22 +1168,22 @@ double IndexRangeNode::estimateCost () {
|
|||
|
||||
TRI_ASSERT(! _ranges.empty());
|
||||
|
||||
if (_index->_type == TRI_IDX_TYPE_PRIMARY_INDEX) {
|
||||
if (_index->type == TRI_IDX_TYPE_PRIMARY_INDEX) {
|
||||
return dependencyCost;
|
||||
}
|
||||
|
||||
if (_index->_type == TRI_IDX_TYPE_EDGE_INDEX) {
|
||||
if (_index->type == TRI_IDX_TYPE_EDGE_INDEX) {
|
||||
return oldCost / 1000;
|
||||
}
|
||||
|
||||
if (_index->_type == TRI_IDX_TYPE_HASH_INDEX) {
|
||||
if (_index->_unique) {
|
||||
if (_index->type == TRI_IDX_TYPE_HASH_INDEX) {
|
||||
if (_index->unique) {
|
||||
return dependencyCost;
|
||||
}
|
||||
return oldCost / 1000;
|
||||
}
|
||||
|
||||
if (_index->_type == TRI_IDX_TYPE_SKIPLIST_INDEX) {
|
||||
if (_index->type == TRI_IDX_TYPE_SKIPLIST_INDEX) {
|
||||
auto const count = _ranges.at(0).size();
|
||||
|
||||
if (count == 0) {
|
||||
|
@ -1197,8 +1191,8 @@ double IndexRangeNode::estimateCost () {
|
|||
return oldCost;
|
||||
}
|
||||
|
||||
if (_index->_unique &&
|
||||
count == _index->_fields._length) {
|
||||
if (_index->unique &&
|
||||
count == _index->fields.size()) {
|
||||
if (_ranges.at(0).back().is1ValueRangeInfo()) {
|
||||
// unique index, all attributes compared using eq (==) operator
|
||||
return dependencyCost;
|
||||
|
|
|
@ -218,7 +218,7 @@ namespace triagens {
|
|||
reverse(false) {
|
||||
}
|
||||
|
||||
TRI_index_t const* index; // The index concerned; if null, this is a nonmatch.
|
||||
Index const* index; // The index concerned; if null, this is a nonmatch.
|
||||
std::vector<MatchType> matches; // qualification of the attrs match quality
|
||||
bool doesMatch; // do all criteria match?
|
||||
bool reverse; // reverse index scan required
|
||||
|
@ -226,7 +226,7 @@ namespace triagens {
|
|||
|
||||
typedef std::vector<std::pair<std::string, bool>> IndexMatchVec;
|
||||
|
||||
static IndexMatch CompareIndex (TRI_index_t const* idx,
|
||||
static IndexMatch CompareIndex (Index const* idx,
|
||||
IndexMatchVec const& attrs);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -865,7 +865,7 @@ namespace triagens {
|
|||
/// attributes passed)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
size_t getUsableFieldsOfIndex (TRI_index_t const* idx,
|
||||
size_t getUsableFieldsOfIndex (Index const* idx,
|
||||
std::unordered_set<std::string> const&) const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -873,7 +873,8 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void getIndexesForIndexRangeNode (std::unordered_set<std::string> const& attrs,
|
||||
std::vector<TRI_index_t*>& idxs, std::vector<size_t>& prefixes) const;
|
||||
std::vector<Index*>& idxs,
|
||||
std::vector<size_t>& prefixes) const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get vector of skiplist indices which match attrs in sequence.
|
||||
|
@ -1064,7 +1065,7 @@ namespace triagens {
|
|||
TRI_vocbase_t* vocbase,
|
||||
Collection const* collection,
|
||||
Variable const* outVariable,
|
||||
TRI_index_t const* index,
|
||||
Index const* index,
|
||||
std::vector<std::vector<RangeInfo>> const& ranges,
|
||||
bool reverse)
|
||||
: ExecutionNode(plan, id),
|
||||
|
@ -1189,7 +1190,7 @@ namespace triagens {
|
|||
/// @brief the index
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_index_t const* _index;
|
||||
Index const* _index;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief the range info
|
||||
|
|
|
@ -27,19 +27,17 @@
|
|||
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGODB_AQL_Index_H
|
||||
#define ARANGODB_AQL_Index_H 1
|
||||
#ifndef ARANGODB_AQL_INDEX_H
|
||||
#define ARANGODB_AQL_INDEX_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "VocBase/document-collection.h"
|
||||
#include "VocBase/transaction.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
#include "VocBase/index.h"
|
||||
|
||||
namespace triagens {
|
||||
namespace aql {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- struct Index
|
||||
// --SECTION-- struct Index
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
struct Index {
|
||||
|
@ -49,42 +47,37 @@ namespace triagens {
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
Index& operator= (Index const&) = delete;
|
||||
Index (Index const&) = delete;
|
||||
Index () = delete;
|
||||
|
||||
Index (TRI_idx_iid_t id, Collection const* collection)
|
||||
: _id(id), _collection(collection){
|
||||
Index (TRI_index_t* idx)
|
||||
: id(idx->_iid),
|
||||
type(idx->_type),
|
||||
unique(idx->_unique),
|
||||
fields(),
|
||||
data(idx) {
|
||||
|
||||
size_t const n = idx->_fields._length;
|
||||
fields.reserve(n);
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
char const* field = idx->_fields._buffer[i];
|
||||
fields.push_back(std::string(field));
|
||||
}
|
||||
|
||||
TRI_ASSERT(data != nullptr);
|
||||
}
|
||||
|
||||
~Index() {
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get a pointer to the underlying TRI_index_s of the Index
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline TRI_index_s* index () const {
|
||||
return TRI_LookupIndex(_collection->documentCollection(), _id);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the index type
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline TRI_idx_type_e type () const {
|
||||
return this->index()->_type;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TRI_idx_iid_t _id;
|
||||
Collection const* _collection;
|
||||
TRI_idx_iid_t const id;
|
||||
TRI_idx_type_e const type;
|
||||
bool const unique;
|
||||
std::vector<std::string> fields;
|
||||
TRI_index_t* data;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -1,128 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Aql, indexes
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 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 not James
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGODB_AQL_Indexes_H
|
||||
#define ARANGODB_AQL_Indexes_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "Aql/Index.h"
|
||||
|
||||
struct TRI_vocbase_s;
|
||||
|
||||
namespace triagens {
|
||||
namespace aql {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- class Indexes
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class Indexes {
|
||||
public:
|
||||
|
||||
Indexes& operator= (Indexes const& other) = delete;
|
||||
|
||||
Indexes ()
|
||||
: _indexes(){
|
||||
}
|
||||
|
||||
~Indexes () {
|
||||
for (auto x: _indexes) {
|
||||
for (auto y: x.second){
|
||||
delete y.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Index* get (TRI_idx_iid_t id, Collection const* collection) {
|
||||
// there may be multiple indexes in the same collection . . .
|
||||
auto it1 = _indexes.find(collection->cid());
|
||||
|
||||
if(it1 == _indexes.end()){
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto it2 = it1->second.find(id);
|
||||
|
||||
if(it2 == it1->second.end()){
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return (*it2).second;
|
||||
}
|
||||
|
||||
void add (TRI_idx_iid_t id, Collection const* collection) {
|
||||
auto it = _indexes.find(collection->cid());
|
||||
|
||||
if (it == _indexes.end()){
|
||||
_indexes.insert(std::make_pair(collection->cid(),
|
||||
std::unordered_map<TRI_idx_iid_t, Index*>()));
|
||||
}
|
||||
|
||||
auto index = new Index(id, collection);
|
||||
try {
|
||||
it->second.insert(std::make_pair(id, index));
|
||||
}
|
||||
catch (...) {
|
||||
delete index;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<TRI_idx_iid_t> indexIds () const {
|
||||
std::vector<TRI_idx_iid_t> result;
|
||||
|
||||
for (auto x : _indexes) {
|
||||
for (auto y : x.second) {
|
||||
result.push_back(y.first);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::unordered_map<TRI_voc_cid_t, std::unordered_map<TRI_idx_iid_t, Index*>> _indexes;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
||||
|
|
@ -28,7 +28,6 @@
|
|||
#include "Aql/OptimizerRules.h"
|
||||
#include "Aql/ExecutionEngine.h"
|
||||
#include "Aql/ExecutionNode.h"
|
||||
#include "Aql/Indexes.h"
|
||||
#include "Aql/Variable.h"
|
||||
|
||||
using namespace triagens::aql;
|
||||
|
@ -843,7 +842,7 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
|
|||
}
|
||||
}
|
||||
else {
|
||||
std::vector<TRI_index_t*> idxs;
|
||||
std::vector<Index*> idxs;
|
||||
std::vector<size_t> prefixes;
|
||||
// {idxs.at(i)->_fields[0]..idxs.at(i)->_fields[prefixes.at(i)]}
|
||||
// is a subset of <attrs>
|
||||
|
@ -866,7 +865,7 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
|
|||
auto idx = idxs.at(i);
|
||||
TRI_ASSERT(idx != nullptr);
|
||||
|
||||
if (idx->_type == TRI_IDX_TYPE_PRIMARY_INDEX) {
|
||||
if (idx->type == TRI_IDX_TYPE_PRIMARY_INDEX) {
|
||||
bool handled = false;
|
||||
auto range = map->find(std::string(TRI_VOC_ATTRIBUTE_ID));
|
||||
|
||||
|
@ -893,9 +892,9 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (idx->_type == TRI_IDX_TYPE_HASH_INDEX) {
|
||||
for (size_t j = 0; j < idx->_fields._length; j++) {
|
||||
auto range = map->find(std::string(idx->_fields._buffer[j]));
|
||||
else if (idx->type == TRI_IDX_TYPE_HASH_INDEX) {
|
||||
for (size_t j = 0; j < idx->fields.size(); j++) {
|
||||
auto range = map->find(idx->fields[j]);
|
||||
|
||||
if (! range->second.is1ValueRangeInfo()) {
|
||||
rangeInfo.at(0).clear(); // not usable
|
||||
|
@ -904,7 +903,7 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
|
|||
rangeInfo.at(0).push_back(range->second);
|
||||
}
|
||||
}
|
||||
else if (idx->_type == TRI_IDX_TYPE_EDGE_INDEX) {
|
||||
else if (idx->type == TRI_IDX_TYPE_EDGE_INDEX) {
|
||||
bool handled = false;
|
||||
auto range = map->find(std::string(TRI_VOC_ATTRIBUTE_FROM));
|
||||
|
||||
|
@ -931,14 +930,14 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (idx->_type == TRI_IDX_TYPE_SKIPLIST_INDEX) {
|
||||
else if (idx->type == TRI_IDX_TYPE_SKIPLIST_INDEX) {
|
||||
size_t j = 0;
|
||||
auto range = map->find(std::string(idx->_fields._buffer[0]));
|
||||
auto range = map->find(idx->fields[0]);
|
||||
TRI_ASSERT(range != map->end());
|
||||
rangeInfo.at(0).push_back(range->second);
|
||||
bool equality = range->second.is1ValueRangeInfo();
|
||||
while (++j < prefixes.at(i) && equality) {
|
||||
range = map->find(std::string(idx->_fields._buffer[j]));
|
||||
range = map->find(idx->fields[j]);
|
||||
rangeInfo.at(0).push_back(range->second);
|
||||
equality = equality && range->second.is1ValueRangeInfo();
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include <Basics/Common.h>
|
||||
|
||||
#include "Aql/Optimizer.h"
|
||||
#include "Aql/Indexes.h"
|
||||
|
||||
namespace triagens {
|
||||
namespace aql {
|
||||
|
|
|
@ -502,7 +502,6 @@ void RestAqlHandler::useQuery (std::string const& operation,
|
|||
int res;
|
||||
try {
|
||||
if (JsonHelper::getBooleanValue(queryJson.json(), "exhausted", true)) {
|
||||
std::cout << "GOT EXHAUSTED FLAG\n";
|
||||
res = query->engine()->initializeCursor(nullptr, 0);
|
||||
}
|
||||
else {
|
||||
|
@ -516,7 +515,7 @@ std::cout << "GOT EXHAUSTED FLAG\n";
|
|||
"initializeCursor lead to an exception");
|
||||
return;
|
||||
}
|
||||
std::cout << "ABOUT TO ANSWER: " << res << "\n";
|
||||
std::cout << "ABOUT TO ANSWER WITH CODE: " << res << "\n";
|
||||
answerBody("error", Json(res == TRI_ERROR_NO_ERROR))
|
||||
("code", Json(static_cast<double>(res)));
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ add_executable(
|
|||
Aql/Ast.cpp
|
||||
Aql/AstNode.cpp
|
||||
Aql/BindParameters.cpp
|
||||
Aql/Collection.cpp
|
||||
Aql/ExecutionBlock.cpp
|
||||
Aql/ExecutionEngine.cpp
|
||||
Aql/ExecutionNode.cpp
|
||||
|
|
|
@ -43,6 +43,7 @@ arangod_libarangod_a_SOURCES = \
|
|||
arangod/Aql/Ast.cpp \
|
||||
arangod/Aql/AstNode.cpp \
|
||||
arangod/Aql/BindParameters.cpp \
|
||||
arangod/Aql/Collection.cpp \
|
||||
arangod/Aql/ExecutionBlock.cpp \
|
||||
arangod/Aql/ExecutionEngine.cpp \
|
||||
arangod/Aql/ExecutionNode.cpp \
|
||||
|
|
|
@ -1290,6 +1290,7 @@ static v8::Handle<v8::Value> JS_DropIndexVocbaseCol (v8::Arguments const& argv)
|
|||
|
||||
return scope.Close(v8::Boolean::New(ok));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns information about the indexes, coordinator case
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue