1
0
Fork 0

struct Index

This commit is contained in:
Jan Steemann 2014-10-01 15:35:16 +02:00
parent 49237ef55a
commit 0d9cdfc87c
13 changed files with 333 additions and 294 deletions

195
arangod/Aql/Collection.cpp Normal file
View File

@ -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:

View File

@ -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;
};
}

View File

@ -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:

View File

@ -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;

View File

@ -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

View File

@ -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;
};

View File

@ -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:

View File

@ -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();
}

View File

@ -31,7 +31,6 @@
#include <Basics/Common.h>
#include "Aql/Optimizer.h"
#include "Aql/Indexes.h"
namespace triagens {
namespace aql {

View File

@ -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)));
}

View File

@ -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

View File

@ -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 \

View File

@ -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
////////////////////////////////////////////////////////////////////////////////