1
0
Fork 0

Merge branch 'sharding' of https://github.com/triAGENS/ArangoDB into sharding

This commit is contained in:
Michael Hackstein 2014-02-28 13:52:28 +01:00
commit 799fc918ef
19 changed files with 357 additions and 168 deletions

View File

@ -29,12 +29,20 @@
#include "BasicsC/logging.h"
#include "BasicsC/tri-strings.h"
#include "BasicsC/vector.h"
#include "VocBase/index.h"
#include "VocBase/document-collection.h"
#include "VocBase/primary-collection.h"
#include "Ahuacatl/ahuacatl-access-optimiser.h"
#include "Ahuacatl/ahuacatl-context.h"
#ifdef TRI_ENABLE_CLUSTER
struct TRI_vector_pointer_s;
struct TRI_vector_pointer_s* TRI_GetCoordinatorIndexes (char const*, char const*);
#endif
// -----------------------------------------------------------------------------
// --SECTION-- private functions
// -----------------------------------------------------------------------------
@ -44,6 +52,30 @@
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief free indexes
////////////////////////////////////////////////////////////////////////////////
static void FreeIndexes (TRI_aql_collection_t* collection) {
size_t i;
if (collection->_availableIndexes == NULL) {
return;
}
for (i = 0; i < collection->_availableIndexes->_length; ++i) {
TRI_index_t* idx = (TRI_index_t*) TRI_AtVectorPointer(collection->_availableIndexes, i);
if (idx != NULL) {
TRI_DestroyVectorString(&idx->_fields);
TRI_Free(TRI_CORE_MEM_ZONE, idx);
}
}
TRI_FreeVectorPointer(TRI_UNKNOWN_MEM_ZONE, collection->_availableIndexes);
collection->_availableIndexes = NULL;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get collection/index id as a string
///
@ -55,7 +87,8 @@ static char* GetIndexIdString (TRI_aql_collection_hint_t* const hint) {
char* result;
TRI_InitStringBuffer(&buffer, TRI_UNKNOWN_MEM_ZONE);
TRI_AppendUInt64StringBuffer(&buffer, hint->_collection->_collection->_cid);
// TRI_AppendUInt64StringBuffer(&buffer, hint->_collection->_name); // cid);
TRI_AppendStringStringBuffer(&buffer, hint->_collection->_name);
TRI_AppendCharStringBuffer(&buffer, '/');
TRI_AppendUInt64StringBuffer(&buffer, hint->_index->_idx->_iid);
@ -80,7 +113,7 @@ static int CollectionNameComparator (const void* l, const void* r) {
/// @brief create a collection container
////////////////////////////////////////////////////////////////////////////////
static TRI_aql_collection_t* CreateCollectionContainer (const char* const name) {
static TRI_aql_collection_t* CreateCollectionContainer (const char* name) {
TRI_aql_collection_t* collection;
assert(name);
@ -91,9 +124,10 @@ static TRI_aql_collection_t* CreateCollectionContainer (const char* const name)
return NULL;
}
collection->_name = (char*) name;
collection->_collection = NULL;
collection->_barrier = NULL;
collection->_name = (char*) name;
collection->_collection = NULL;
collection->_barrier = NULL;
collection->_availableIndexes = NULL;
return collection;
}
@ -207,7 +241,7 @@ TRI_json_t* TRI_GetJsonCollectionHintAql (TRI_aql_collection_hint_t* const hint)
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
indexDescription,
"type",
TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, idx->typeName(idx)));
TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, TRI_TypeNameIndex(idx->_type)));
// index attributes
buffer = TRI_CreateStringBuffer(TRI_UNKNOWN_MEM_ZONE);
@ -295,15 +329,24 @@ void TRI_FreeCollectionHintAql (TRI_aql_collection_hint_t* const hint) {
TRI_Free(TRI_UNKNOWN_MEM_ZONE, hint);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief free a collection
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeCollectionAql (TRI_aql_collection_t* collection) {
FreeIndexes(collection);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, collection);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief lookup a collection in the internal vector
////////////////////////////////////////////////////////////////////////////////
TRI_aql_collection_t* TRI_GetCollectionAql (const TRI_aql_context_t* const context,
const char* const collectionName) {
TRI_aql_collection_t* TRI_GetCollectionAql (const TRI_aql_context_t* context,
const char* collectionName) {
size_t i, n;
assert(context);
assert(context != NULL);
n = context->_collections._length;
for (i = 0; i < n; ++i) {
@ -321,7 +364,7 @@ TRI_aql_collection_t* TRI_GetCollectionAql (const TRI_aql_context_t* const conte
/// @brief init all collections
////////////////////////////////////////////////////////////////////////////////
bool TRI_SetupCollectionsAql (TRI_aql_context_t* const context) {
bool TRI_SetupCollectionsAql (TRI_aql_context_t* context) {
if (! SetupCollections(context)) {
return false;
}
@ -333,7 +376,7 @@ bool TRI_SetupCollectionsAql (TRI_aql_context_t* const context) {
/// @brief adds a gc marker for all collections used in a query
////////////////////////////////////////////////////////////////////////////////
bool TRI_AddBarrierCollectionsAql (TRI_aql_context_t* const context) {
bool TRI_AddBarrierCollectionsAql (TRI_aql_context_t* context) {
size_t i;
size_t n;
bool result = true;
@ -351,18 +394,19 @@ bool TRI_AddBarrierCollectionsAql (TRI_aql_context_t* const context) {
TRI_aql_collection_t* collection = (TRI_aql_collection_t*) context->_collections._buffer[i];
TRI_primary_collection_t* primaryCollection;
assert(collection);
assert(collection->_name);
assert(collection->_collection);
assert(collection->_collection->_collection);
assert(! collection->_barrier);
assert(collection != NULL);
assert(collection->_name != NULL);
assert(collection->_collection != NULL);
assert(collection->_collection->_collection != NULL);
assert(collection->_barrier == NULL);
primaryCollection = (TRI_primary_collection_t*) collection->_collection->_collection;
LOG_TRACE("adding barrier for collection '%s'", collection->_name);
ce = TRI_CreateBarrierElement(&primaryCollection->_barrierList);
if (! ce) {
if (ce == NULL) {
// couldn't create the barrier
result = false;
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
@ -380,7 +424,7 @@ bool TRI_AddBarrierCollectionsAql (TRI_aql_context_t* const context) {
/// @brief removes the gc markers for all collections used in a query
////////////////////////////////////////////////////////////////////////////////
void TRI_RemoveBarrierCollectionsAql (TRI_aql_context_t* const context) {
void TRI_RemoveBarrierCollectionsAql (TRI_aql_context_t* context) {
size_t i;
if (context->_isCoordinator) {
@ -393,16 +437,16 @@ void TRI_RemoveBarrierCollectionsAql (TRI_aql_context_t* const context) {
while (i--) {
TRI_aql_collection_t* collection = (TRI_aql_collection_t*) context->_collections._buffer[i];
assert(collection);
assert(collection->_name);
assert(collection != NULL);
assert(collection->_name != NULL);
if (! collection->_collection || ! collection->_barrier) {
if (collection->_collection == NULL || collection->_barrier == NULL) {
// don't process collections we weren't able to lock at all
continue;
}
assert(collection->_barrier);
assert(collection->_collection->_collection);
assert(collection->_barrier != NULL);
assert(collection->_collection->_collection != NULL);
LOG_TRACE("removing barrier for collection '%s'", collection->_name);
@ -415,9 +459,10 @@ void TRI_RemoveBarrierCollectionsAql (TRI_aql_context_t* const context) {
/// @brief add a collection name to the list of collections used
////////////////////////////////////////////////////////////////////////////////
bool TRI_AddCollectionAql (TRI_aql_context_t* const context, const char* const name) {
assert(context);
assert(name);
bool TRI_AddCollectionAql (TRI_aql_context_t* context,
const char* name) {
assert(context != NULL);
assert(name != NULL);
// duplicates are not a problem here, we simply ignore them
TRI_InsertKeyAssociativePointer(&context->_collectionNames, name, (void*) name, false);
@ -431,6 +476,35 @@ bool TRI_AddCollectionAql (TRI_aql_context_t* const context, const char* const n
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get available indexes of a collection
////////////////////////////////////////////////////////////////////////////////
TRI_vector_pointer_t* TRI_GetIndexesCollectionAql (TRI_aql_context_t* context,
TRI_aql_collection_t* collection) {
#ifdef TRI_ENABLE_CLUSTER
if (context->_isCoordinator) {
if (collection->_availableIndexes == NULL) {
collection->_availableIndexes = TRI_GetCoordinatorIndexes(context->_vocbase->_name, collection->_name);
}
return collection->_availableIndexes;
}
else {
#endif
TRI_primary_collection_t* primary;
if (collection->_collection == NULL) {
return NULL;
}
primary = collection->_collection->_collection;
return &(((TRI_document_collection_t*) primary)->_allIndexes);
#ifdef TRI_ENABLE_CLUSTER
}
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -42,6 +42,7 @@ extern "C" {
#endif
struct TRI_aql_context_s;
struct TRI_vector_pointer_s;
// -----------------------------------------------------------------------------
// --SECTION-- defines
@ -80,9 +81,10 @@ struct TRI_aql_context_s;
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_aql_collection_s {
TRI_vocbase_col_t* _collection;
TRI_barrier_t* _barrier;
char* _name;
TRI_vocbase_col_t* _collection; // this might be NULL !
TRI_barrier_t* _barrier; // this might be NULL !
char* _name;
struct TRI_vector_pointer_s* _availableIndexes;
}
TRI_aql_collection_t;
@ -135,36 +137,50 @@ TRI_aql_collection_hint_t* TRI_CreateCollectionHintAql (void);
void TRI_FreeCollectionHintAql (TRI_aql_collection_hint_t* const);
////////////////////////////////////////////////////////////////////////////////
/// @brief free a collection
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeCollectionAql (TRI_aql_collection_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief lookup a collection in the internal vector
////////////////////////////////////////////////////////////////////////////////
TRI_aql_collection_t* TRI_GetCollectionAql (const struct TRI_aql_context_s* const,
const char* const);
TRI_aql_collection_t* TRI_GetCollectionAql (const struct TRI_aql_context_s*,
const char*);
////////////////////////////////////////////////////////////////////////////////
/// @brief init all collections
////////////////////////////////////////////////////////////////////////////////
bool TRI_SetupCollectionsAql (struct TRI_aql_context_s* const);
bool TRI_SetupCollectionsAql (struct TRI_aql_context_s*);
////////////////////////////////////////////////////////////////////////////////
/// @brief adds a gc marker for all collections used in a query
////////////////////////////////////////////////////////////////////////////////
bool TRI_AddBarrierCollectionsAql (struct TRI_aql_context_s* const);
bool TRI_AddBarrierCollectionsAql (struct TRI_aql_context_s*);
////////////////////////////////////////////////////////////////////////////////
/// @brief removes the gc markers for all collections used in a query
////////////////////////////////////////////////////////////////////////////////
void TRI_RemoveBarrierCollectionsAql (struct TRI_aql_context_s* const);
void TRI_RemoveBarrierCollectionsAql (struct TRI_aql_context_s*);
////////////////////////////////////////////////////////////////////////////////
/// @brief add a collection name to the list of collections used
////////////////////////////////////////////////////////////////////////////////
bool TRI_AddCollectionAql (struct TRI_aql_context_s* const, const char* const);
bool TRI_AddCollectionAql (struct TRI_aql_context_s*,
const char*);
////////////////////////////////////////////////////////////////////////////////
/// @brief get available indexes of a collection
////////////////////////////////////////////////////////////////////////////////
struct TRI_vector_pointer_s* TRI_GetIndexesCollectionAql (struct TRI_aql_context_s*,
TRI_aql_collection_t*);
////////////////////////////////////////////////////////////////////////////////
/// @}

View File

@ -83,8 +83,9 @@ static void FreeCollections (TRI_aql_context_t* const context) {
while (i--) {
TRI_aql_collection_t* collection = (TRI_aql_collection_t*) context->_collections._buffer[i];
if (collection) {
TRI_Free(TRI_UNKNOWN_MEM_ZONE, collection);
if (collection != NULL) {
TRI_FreeCollectionAql(collection);
}
}
TRI_DestroyVectorPointer(&context->_collections);

View File

@ -67,7 +67,7 @@ static void LogIndexString (const char* const what,
LOG_TRACE("%s %s index (%s) for '%s'",
what,
idx->typeName(idx),
TRI_TypeNameIndex(idx->_type),
buffer->_buffer,
collectionName);
@ -318,10 +318,6 @@ TRI_aql_index_t* TRI_DetermineIndexAql (TRI_aql_context_t* const context,
TRI_vector_pointer_t matches;
size_t i, n;
if (context->_isCoordinator) {
return NULL;
}
TRI_InitVectorPointer(&matches, TRI_UNKNOWN_MEM_ZONE);
assert(context);
@ -329,6 +325,7 @@ TRI_aql_index_t* TRI_DetermineIndexAql (TRI_aql_context_t* const context,
assert(candidates);
n = availableIndexes->_length;
for (i = 0; i < n; ++i) {
TRI_index_t* idx = (TRI_index_t*) availableIndexes->_buffer[i];
size_t numIndexFields;
@ -345,7 +342,7 @@ TRI_aql_index_t* TRI_DetermineIndexAql (TRI_aql_context_t* const context,
lastTypeWasExact = true;
numIndexFields = idx->_fields._length;
// now loop over all index fields, from left to right
// index field order is important because skiplists can be used with leftmost prefixes as well,
// but not with rightmost prefixes
@ -475,7 +472,8 @@ TRI_aql_index_t* TRI_DetermineIndexAql (TRI_aql_context_t* const context,
}
// we now do or don't have an index candidate in the matches vector
if (matches._length < numIndexFields && idx->_needsFullCoverage) {
if (matches._length < numIndexFields &&
TRI_NeedsFullCoverageIndex(idx->_type)) {
// the matches vector does not fully cover the indexed fields, but the index requires it
continue;
}

View File

@ -276,7 +276,6 @@ static void AttachCollectionHint (TRI_aql_context_t* const context,
TRI_aql_collection_hint_t* hint;
TRI_aql_index_t* idx;
TRI_aql_collection_t* collection;
TRI_primary_collection_t* primary;
char* collectionName;
collectionName = TRI_AQL_NODE_STRING(nameNode);
@ -302,16 +301,17 @@ static void AttachCollectionHint (TRI_aql_context_t* const context,
return;
}
if (collection->_collection == NULL) {
availableIndexes = TRI_GetIndexesCollectionAql(context, collection);
#ifdef TRI_ENABLE_CLUSTER
if (! context->_isCoordinator &&
availableIndexes == NULL) {
return;
}
#endif
hint->_collection = collection;
primary = collection->_collection->_collection;
availableIndexes = &(((TRI_document_collection_t*) primary)->_allIndexes);
if (availableIndexes == NULL) {
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
@ -322,7 +322,7 @@ static void AttachCollectionHint (TRI_aql_context_t* const context,
availableIndexes,
collectionName,
hint->_ranges);
hint->_index = idx;
}

View File

@ -174,14 +174,6 @@ static int InitialiseCap (TRI_cap_constraint_t* cap,
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the index type name
////////////////////////////////////////////////////////////////////////////////
static const char* TypeNameCapConstraint (TRI_index_t const* idx) {
return "cap";
}
////////////////////////////////////////////////////////////////////////////////
/// @brief describes a cap constraint as a json object
////////////////////////////////////////////////////////////////////////////////
@ -299,8 +291,7 @@ TRI_index_t* TRI_CreateCapConstraint (struct TRI_primary_collection_s* primary,
idx = &cap->base;
idx->typeName = TypeNameCapConstraint;
TRI_InitIndex(idx, iid, TRI_IDX_TYPE_CAP_CONSTRAINT, primary, false, true);
TRI_InitIndex(idx, iid, TRI_IDX_TYPE_CAP_CONSTRAINT, primary, false);
TRI_InitVectorString(&idx->_fields, TRI_CORE_MEM_ZONE);
idx->json = JsonCapConstraint;

View File

@ -27,9 +27,13 @@
#include "Cluster/ClusterMethods.h"
#include "BasicsC/conversions.h"
#include "BasicsC/json.h"
#include "BasicsC/json-utilities.h"
#include "BasicsC/tri-strings.h"
#include "BasicsC/vector.h"
#include "Basics/StringUtils.h"
#include "VocBase/index.h"
#include "VocBase/server.h"
using namespace std;
@ -1235,13 +1239,106 @@ int createEdgeOnCoordinator (
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get indexes from coordinator
////////////////////////////////////////////////////////////////////////////////
TRI_vector_pointer_t* getIndexesCoordinator (string const& databaseName,
string const& collectionName) {
TRI_shared_ptr<CollectionInfo> c = ClusterInfo::instance()->getCollection(databaseName, collectionName);
if ((*c).empty()) {
return 0;
}
TRI_vector_pointer_t* result = (TRI_vector_pointer_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_vector_pointer_t), false);
if (result == 0) {
return 0;
}
TRI_InitVectorPointer(result, TRI_UNKNOWN_MEM_ZONE);
TRI_json_t const* json = (*c).getIndexes();
if (TRI_IsListJson(json)) {
for (size_t i = 0; i < json->_value._objects._length; ++i) {
TRI_json_t const* v = TRI_LookupListJson(json, i);
if (TRI_IsArrayJson(v)) {
TRI_json_t const* value = TRI_LookupArrayJson(v, "type");
if (! TRI_IsStringJson(value)) {
continue;
}
TRI_idx_type_e type = TRI_TypeIndex(value->_value._string.data);
bool unique = false;
value = TRI_LookupArrayJson(v, "unique");
if (TRI_IsBooleanJson(value)) {
unique = value->_value._boolean;
}
TRI_idx_iid_t iid = 0;
value = TRI_LookupArrayJson(v, "id");
if (TRI_IsStringJson(value)) {
iid = TRI_UInt64String2(value->_value._string.data, value->_value._string.length - 1);
}
TRI_index_t* idx = (TRI_index_t*) TRI_Allocate(TRI_CORE_MEM_ZONE, sizeof(TRI_index_t), false);
if (idx == 0) {
continue;
}
idx->_iid = iid;
idx->_type = type;
idx->_unique = unique;
TRI_InitVectorString(&idx->_fields, TRI_CORE_MEM_ZONE);
value = TRI_LookupArrayJson(v, "fields");
if (TRI_IsListJson(value)) {
for (size_t j = 0; j < value->_value._objects._length; ++j) {
TRI_json_t const* f = TRI_LookupListJson(value, j);
if (TRI_IsStringJson(f)) {
char* fieldName = TRI_DuplicateString2Z(TRI_CORE_MEM_ZONE,
f->_value._string.data,
f->_value._string.length - 1);
TRI_PushBackVectorString(&idx->_fields, fieldName);
}
}
}
TRI_PushBackVectorPointer(result, idx);
}
}
}
return result;
}
} // namespace arango
} // namespace triagens
////////////////////////////////////////////////////////////////////////////////
/// @brief
/// @brief c binding for getIndexesCoordinator
////////////////////////////////////////////////////////////////////////////////
extern "C" {
TRI_vector_pointer_t* TRI_GetCoordinatorIndexes (char const* databaseName,
char const* collectionName) {
return getIndexesCoordinator(string(databaseName), string(collectionName));
}
}
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"

View File

@ -47,6 +47,7 @@
extern "C" {
struct TRI_json_s;
struct TRI_vector_pointer_s;
}
namespace triagens {
@ -197,11 +198,14 @@ namespace triagens {
triagens::rest::HttpResponse::HttpResponseCode& responseCode,
map<string, string>& resultHeaders,
string& resultBody);
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief get indexes from coordinator
////////////////////////////////////////////////////////////////////////////////
struct TRI_vector_pointer_s* getIndexesCoordinator (std::string const&,
std::string const&);
} // namespace arango
} // namespace triagens

View File

@ -237,14 +237,6 @@ static bool ExtractDoubleList (TRI_shaper_t* shaper,
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief return the index type name
////////////////////////////////////////////////////////////////////////////////
static const char* TypeNameGeo1Index (TRI_index_t const* idx) {
return "geo1";
}
////////////////////////////////////////////////////////////////////////////////
/// @brief JSON description of a geo index, location is a list
////////////////////////////////////////////////////////////////////////////////
@ -293,14 +285,6 @@ static TRI_json_t* JsonGeo1Index (TRI_index_t* idx) {
return json;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the index type name
////////////////////////////////////////////////////////////////////////////////
static const char* TypeNameGeo2Index (TRI_index_t const* idx) {
return "geo2";
}
////////////////////////////////////////////////////////////////////////////////
/// @brief JSON description of a geo index, two attributes
////////////////////////////////////////////////////////////////////////////////
@ -515,8 +499,7 @@ TRI_index_t* TRI_CreateGeo1Index (struct TRI_primary_collection_s* primary,
TRI_InitVectorString(&idx->_fields, TRI_CORE_MEM_ZONE);
idx->typeName = TypeNameGeo1Index;
TRI_InitIndex(idx, iid, TRI_IDX_TYPE_GEO1_INDEX, primary, unique, true);
TRI_InitIndex(idx, iid, TRI_IDX_TYPE_GEO1_INDEX, primary, unique);
idx->_ignoreNull = ignoreNull;
@ -571,8 +554,7 @@ TRI_index_t* TRI_CreateGeo2Index (struct TRI_primary_collection_s* primary,
TRI_InitVectorString(&idx->_fields, TRI_CORE_MEM_ZONE);
idx->typeName = TypeNameGeo2Index;
TRI_InitIndex(idx, iid, TRI_IDX_TYPE_GEO2_INDEX, primary, unique, true);
TRI_InitIndex(idx, iid, TRI_IDX_TYPE_GEO2_INDEX, primary, unique);
idx->_ignoreNull = ignoreNull;

View File

@ -434,14 +434,6 @@ static TRI_index_result_t MultiHashIndex_find (TRI_hash_index_t* hashIndex,
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief return the index type name
////////////////////////////////////////////////////////////////////////////////
static const char* TypeNameHashIndex (TRI_index_t const* idx) {
return "hash";
}
////////////////////////////////////////////////////////////////////////////////
/// @brief describes a hash index as a json object
////////////////////////////////////////////////////////////////////////////////
@ -592,8 +584,7 @@ TRI_index_t* TRI_CreateHashIndex (struct TRI_primary_collection_s* primary,
hashIndex = TRI_Allocate(TRI_CORE_MEM_ZONE, sizeof(TRI_hash_index_t), false);
idx = &hashIndex->base;
idx->typeName = TypeNameHashIndex;
TRI_InitIndex(idx, iid, TRI_IDX_TYPE_HASH_INDEX, primary, unique, true);
TRI_InitIndex(idx, iid, TRI_IDX_TYPE_HASH_INDEX, primary, unique);
idx->json = JsonHashIndex;
idx->insert = InsertHashIndex;

View File

@ -866,7 +866,7 @@ static TRI_index_operator_t* SetupExampleSkiplist (TRI_index_t* idx,
for (size_t i = 0; i < idx->_fields._length; ++i) {
v8::Handle<v8::String> key = v8::String::New(idx->_fields._buffer[i]);
if (!example->HasOwnProperty(key)) {
if (! example->HasOwnProperty(key)) {
break;
}
@ -1049,6 +1049,7 @@ static v8::Handle<v8::Value> ExecuteSkiplistQuery (v8::Arguments const& argv,
trx.lockRead();
// extract the index
TRI_index_t* idx = TRI_LookupIndexByHandle(col, argv[0], false, &err);
@ -1077,7 +1078,7 @@ static v8::Handle<v8::Value> ExecuteSkiplistQuery (v8::Arguments const& argv,
TRI_skiplist_iterator_t* skiplistIterator = TRI_LookupSkiplistIndex(idx, skiplistOperator);
if (skiplistIterator == 0) {
TRI_V8_EXCEPTION(scope, TRI_ERROR_OUT_OF_MEMORY);
TRI_V8_EXCEPTION(scope, TRI_ERROR_ARANGO_NO_INDEX);
}
TRI_barrier_t* barrier = 0;
@ -1086,8 +1087,7 @@ static v8::Handle<v8::Value> ExecuteSkiplistQuery (v8::Arguments const& argv,
bool error = false;
while (true) {
TRI_skiplist_index_element_t* indexElement =
skiplistIterator->_next(skiplistIterator);
TRI_skiplist_index_element_t* indexElement = skiplistIterator->_next(skiplistIterator);
if (indexElement == NULL) {
break;

View File

@ -1520,6 +1520,11 @@ static v8::Handle<v8::Value> EnsureIndexCoordinator (TRI_vocbase_col_t const* co
}
if (resultJson == 0) {
if (! create) {
// did not find a suitable index
return scope.Close(v8::Null());
}
TRI_V8_EXCEPTION_MEMORY(scope);
}

View File

@ -1403,7 +1403,7 @@ static int AddIndex (TRI_document_collection_t* document,
assert(idx != NULL);
LOG_DEBUG("adding index of type %s for collection '%s'",
idx->typeName(idx),
TRI_TypeNameIndex(idx->_type),
document->base.base._info._name);
res = TRI_PushBackVectorPointer(&document->_allIndexes, idx);

View File

@ -70,8 +70,7 @@ void TRI_InitIndex (TRI_index_t* idx,
TRI_idx_iid_t iid,
TRI_idx_type_e type,
struct TRI_primary_collection_s* primary,
bool unique,
bool needsFullCoverage) {
bool unique) {
// note: primary can be NULL
assert(idx != NULL);
@ -90,7 +89,6 @@ void TRI_InitIndex (TRI_index_t* idx,
idx->_type = type;
idx->_collection = primary;
idx->_unique = unique;
idx->_needsFullCoverage = needsFullCoverage;
// init common functions
idx->removeIndex = NULL;
@ -98,7 +96,7 @@ void TRI_InitIndex (TRI_index_t* idx,
idx->postInsert = NULL;
LOG_TRACE("initialising index of type %s", idx->typeName(idx));
LOG_TRACE("initialising index of type %s", TRI_TypeNameIndex(idx->_type));
}
////////////////////////////////////////////////////////////////////////////////
@ -114,6 +112,32 @@ void TRI_InitIndex (TRI_index_t* idx,
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not an index needs full coverage
////////////////////////////////////////////////////////////////////////////////
bool TRI_NeedsFullCoverageIndex (TRI_idx_type_e type) {
switch (type) {
case TRI_IDX_TYPE_PRIMARY_INDEX:
case TRI_IDX_TYPE_EDGE_INDEX:
case TRI_IDX_TYPE_HASH_INDEX:
case TRI_IDX_TYPE_SKIPLIST_INDEX:
case TRI_IDX_TYPE_FULLTEXT_INDEX:
case TRI_IDX_TYPE_GEO1_INDEX:
case TRI_IDX_TYPE_GEO2_INDEX:
case TRI_IDX_TYPE_CAP_CONSTRAINT:
return true;
case TRI_IDX_TYPE_BITARRAY_INDEX:
return false;
case TRI_IDX_TYPE_PRIORITY_QUEUE_INDEX:
case TRI_IDX_TYPE_UNKNOWN:
return false;
}
// unknown type...
assert(false);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the name of an index type
////////////////////////////////////////////////////////////////////////////////
@ -253,7 +277,7 @@ bool TRI_ValidateIndexIdIndex (char const* key,
/// @brief free an index
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeIndex (TRI_index_t* const idx) {
void TRI_FreeIndex (TRI_index_t* idx) {
assert(idx);
LOG_TRACE("freeing index");
@ -440,7 +464,8 @@ TRI_index_t* TRI_LookupIndex (TRI_primary_collection_t* primary,
/// specialised index
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* TRI_JsonIndex (TRI_memory_zone_t* zone, TRI_index_t* idx) {
TRI_json_t* TRI_JsonIndex (TRI_memory_zone_t* zone,
TRI_index_t const* idx) {
TRI_json_t* json;
json = TRI_CreateArrayJson(zone);
@ -450,7 +475,7 @@ TRI_json_t* TRI_JsonIndex (TRI_memory_zone_t* zone, TRI_index_t* idx) {
number = TRI_StringUInt64(idx->_iid);
TRI_Insert3ArrayJson(zone, json, "id", TRI_CreateStringCopyJson(zone, number));
TRI_Insert3ArrayJson(zone, json, "type", TRI_CreateStringCopyJson(zone, idx->typeName(idx)));
TRI_Insert3ArrayJson(zone, json, "type", TRI_CreateStringCopyJson(zone, TRI_TypeNameIndex(idx->_type)));
TRI_Insert3ArrayJson(zone, json, "unique", TRI_CreateBooleanJson(zone, idx->_unique));
TRI_FreeString(TRI_CORE_MEM_ZONE, number);
@ -540,14 +565,6 @@ char const** TRI_FieldListByPathList (TRI_shaper_t* shaper,
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief return the index type name
////////////////////////////////////////////////////////////////////////////////
static const char* TypeNamePrimary (TRI_index_t const* idx) {
return "primary";
}
////////////////////////////////////////////////////////////////////////////////
/// @brief insert methods does nothing
////////////////////////////////////////////////////////////////////////////////
@ -623,8 +640,7 @@ TRI_index_t* TRI_CreatePrimaryIndex (struct TRI_primary_collection_s* primary) {
TRI_InitVectorString(&idx->_fields, TRI_CORE_MEM_ZONE);
TRI_PushBackVectorString(&idx->_fields, id);
idx->typeName = TypeNamePrimary;
TRI_InitIndex(idx, 0, TRI_IDX_TYPE_PRIMARY_INDEX, primary, true, true);
TRI_InitIndex(idx, 0, TRI_IDX_TYPE_PRIMARY_INDEX, primary, true);
idx->json = JsonPrimary;
idx->insert = InsertPrimary;
@ -766,14 +782,6 @@ static bool IsEqualElementEdge (TRI_multi_pointer_t* array,
(strcmp(lKey, rKey) == 0);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the index type name
////////////////////////////////////////////////////////////////////////////////
static const char* TypeNameEdge (TRI_index_t const* idx) {
return "edge";
}
////////////////////////////////////////////////////////////////////////////////
/// @brief insert method for edges
////////////////////////////////////////////////////////////////////////////////
@ -940,8 +948,7 @@ TRI_index_t* TRI_CreateEdgeIndex (struct TRI_primary_collection_s* primary,
id = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, TRI_VOC_ATTRIBUTE_FROM);
TRI_PushBackVectorString(&idx->_fields, id);
idx->typeName = TypeNameEdge;
TRI_InitIndex(idx, iid, TRI_IDX_TYPE_EDGE_INDEX, primary, false, true);
TRI_InitIndex(idx, iid, TRI_IDX_TYPE_EDGE_INDEX, primary, false);
idx->json = JsonEdge;
idx->insert = InsertEdge;
@ -1351,14 +1358,6 @@ static int InsertSkiplistIndex (TRI_index_t* idx,
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the index type name
////////////////////////////////////////////////////////////////////////////////
static const char* TypeNameSkiplistIndex (TRI_index_t const* idx) {
return "skiplist";
}
////////////////////////////////////////////////////////////////////////////////
/// @brief describes a skiplist index as a json object
////////////////////////////////////////////////////////////////////////////////
@ -1520,8 +1519,7 @@ TRI_index_t* TRI_CreateSkiplistIndex (TRI_primary_collection_t* primary,
idx = &skiplistIndex->base;
idx->typeName = TypeNameSkiplistIndex;
TRI_InitIndex(idx, iid, TRI_IDX_TYPE_SKIPLIST_INDEX, primary, unique, true);
TRI_InitIndex(idx, iid, TRI_IDX_TYPE_SKIPLIST_INDEX, primary, unique);
idx->json = JsonSkiplistIndex;
idx->insert = InsertSkiplistIndex;
@ -1729,14 +1727,6 @@ static int InsertFulltextIndex (TRI_index_t* idx,
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the index type name
////////////////////////////////////////////////////////////////////////////////
static const char* TypeNameFulltextIndex (TRI_index_t const* idx) {
return "fulltext";
}
////////////////////////////////////////////////////////////////////////////////
/// @brief describes a fulltext index as a json object
////////////////////////////////////////////////////////////////////////////////
@ -1864,8 +1854,7 @@ TRI_index_t* TRI_CreateFulltextIndex (struct TRI_primary_collection_s* primary,
idx = &fulltextIndex->base;
idx->typeName = TypeNameFulltextIndex;
TRI_InitIndex(idx, iid, TRI_IDX_TYPE_FULLTEXT_INDEX, primary, false, true);
TRI_InitIndex(idx, iid, TRI_IDX_TYPE_FULLTEXT_INDEX, primary, false);
idx->json = JsonFulltextIndex;
idx->insert = InsertFulltextIndex;
@ -2270,14 +2259,6 @@ static int InsertBitarrayIndex (TRI_index_t* idx,
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the index type name
////////////////////////////////////////////////////////////////////////////////
static const char* TypeNameBitarrayIndex (TRI_index_t const* idx) {
return "bitarray";
}
////////////////////////////////////////////////////////////////////////////////
/// @brief describes a bitarray index as a json object
////////////////////////////////////////////////////////////////////////////////
@ -2580,8 +2561,7 @@ TRI_index_t* TRI_CreateBitarrayIndex (struct TRI_primary_collection_s* primary,
baIndex = TRI_Allocate(TRI_CORE_MEM_ZONE, sizeof(TRI_bitarray_index_t), false);
idx = &baIndex->base;
idx->typeName = TypeNameBitarrayIndex;
TRI_InitIndex(idx, iid, TRI_IDX_TYPE_BITARRAY_INDEX, primary, false, false);
TRI_InitIndex(idx, iid, TRI_IDX_TYPE_BITARRAY_INDEX, primary, false);
idx->json = JsonBitarrayIndex;
idx->insert = InsertBitarrayIndex;

View File

@ -108,9 +108,7 @@ typedef struct TRI_index_s {
TRI_vector_string_t _fields;
bool _unique;
bool _ignoreNull;
bool _needsFullCoverage;
const char* (*typeName) (struct TRI_index_s const*);
TRI_json_t* (*json) (struct TRI_index_s*);
void (*removeIndex) (struct TRI_index_s*, struct TRI_primary_collection_s*);
@ -286,7 +284,6 @@ void TRI_InitIndex (TRI_index_t*,
TRI_idx_iid_t,
TRI_idx_type_e,
struct TRI_primary_collection_s*,
bool,
bool);
////////////////////////////////////////////////////////////////////////////////
@ -302,6 +299,12 @@ void TRI_InitIndex (TRI_index_t*,
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not an index needs full coverage
////////////////////////////////////////////////////////////////////////////////
bool TRI_NeedsFullCoverageIndex (TRI_idx_type_e);
////////////////////////////////////////////////////////////////////////////////
/// @brief return the name of an index type
////////////////////////////////////////////////////////////////////////////////
@ -331,7 +334,7 @@ bool TRI_ValidateIndexIdIndex (char const*,
/// @brief free an index
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeIndex (TRI_index_t* const);
void TRI_FreeIndex (TRI_index_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief removes an index file
@ -362,7 +365,7 @@ TRI_index_t* TRI_LookupIndex (struct TRI_primary_collection_s*,
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* TRI_JsonIndex (TRI_memory_zone_t*,
TRI_index_t*);
TRI_index_t const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys a result set returned by a hash index query

View File

@ -333,8 +333,8 @@ function setupIndexQuery (name, func, isExampleQuery) {
actions.badParameter(req, res, "condition");
return;
}
result = collection[func](index, body.condition, skip, limit);
result = collection[func](index, body.condition);
}
if (skip > 0) {

View File

@ -807,6 +807,8 @@ SimpleQueryByExample.prototype.clone = function () {
query = new SimpleQueryByExample(this._collection, this._example);
query._skip = this._skip;
query._limit = this._limit;
query._type = this._type;
query._index = this._index;
return query;
};
@ -883,6 +885,8 @@ SimpleQueryByCondition.prototype.clone = function () {
query = new SimpleQueryByCondition(this._collection, this._condition);
query._skip = this._skip;
query._limit = this._limit;
query._type = this._type;
query._index = this._index;
return query;
};

View File

@ -806,6 +806,8 @@ SimpleQueryByExample.prototype.clone = function () {
query = new SimpleQueryByExample(this._collection, this._example);
query._skip = this._skip;
query._limit = this._limit;
query._type = this._type;
query._index = this._index;
return query;
};
@ -882,6 +884,8 @@ SimpleQueryByCondition.prototype.clone = function () {
query = new SimpleQueryByCondition(this._collection, this._condition);
query._skip = this._skip;
query._limit = this._limit;
query._type = this._type;
query._index = this._index;
return query;
};

View File

@ -913,6 +913,10 @@ function GET_DOCUMENTS_PRIMARY_LIST (collection, idx, values) {
function GET_DOCUMENTS_HASH (collection, idx, example) {
"use strict";
if (isCoordinator) {
return COLLECTION(collection).byExampleHash(idx, example).toArray();
}
return COLLECTION(collection).BY_EXAMPLE_HASH(idx, example).documents;
}
@ -933,9 +937,18 @@ function GET_DOCUMENTS_HASH_LIST (collection, idx, attribute, values) {
example[attribute] = value;
c.BY_EXAMPLE_HASH(idx, example).documents.forEach(function (doc) {
var list;
if (isCoordinator) {
list = c.byExampleHash(idx, example).toArray();
}
else {
list = c.BY_EXAMPLE_HASH(idx, example).documents;
}
list.forEach(function (doc) {
result.push(doc);
});
});
return result;
@ -1012,6 +1025,10 @@ function GET_DOCUMENTS_EDGE_LIST (collection, att, values) {
function GET_DOCUMENTS_BITARRAY (collection, idx, example) {
"use strict";
if (isCoordinator) {
return COLLECTION(collection).byConditionBitarray(idx, example).toArray();
}
return COLLECTION(collection).BY_CONDITION_BITARRAY(idx, example).documents;
}
@ -1032,7 +1049,13 @@ function GET_DOCUMENTS_BITARRAY_LIST (collection, idx, attribute, values) {
example[attribute] = value;
documents = c.BY_EXAMPLE_BITARRAY(idx, example).documents;
if (isCoordinator) {
documents = c.byExampleBitarray(idx, example).toArray();
}
else {
documents = c.BY_EXAMPLE_BITARRAY(idx, example).documents;
}
documents.forEach(function (doc) {
result.push(doc);
});
@ -1048,6 +1071,10 @@ function GET_DOCUMENTS_BITARRAY_LIST (collection, idx, attribute, values) {
function GET_DOCUMENTS_SKIPLIST (collection, idx, example) {
"use strict";
if (isCoordinator) {
return COLLECTION(collection).byConditionSkiplist(idx, example).toArray();
}
return COLLECTION(collection).BY_CONDITION_SKIPLIST(idx, example).documents;
}
@ -1065,7 +1092,14 @@ function GET_DOCUMENTS_SKIPLIST_LIST (collection, idx, attribute, values) {
var example = { }, documents;
example[attribute] = value;
documents = c.BY_EXAMPLE_SKIPLIST(idx, example).documents;
if (isCoordinator) {
documents = c.byExampleSkiplist(idx, example).toArray();
}
else {
documents = c.BY_EXAMPLE_SKIPLIST(idx, example).documents;
}
documents.forEach(function (doc) {
result.push(doc);
});
@ -3359,6 +3393,7 @@ function SKIPLIST_QUERY (collection, condition, skip, limit) {
}
var c = COLLECTION(collection);
if (c === null) {
THROW(INTERNAL.errors.ERROR_ARANGO_COLLECTION_NOT_FOUND, collection);
}
@ -3378,6 +3413,10 @@ function SKIPLIST_QUERY (collection, condition, skip, limit) {
}
try {
if (isCoordinator) {
return c.byConditionSkiplist(idx.id, condition).skip(skip).limit(limit).toArray();
}
return c.BY_CONDITION_SKIPLIST(idx.id, condition, skip, limit).documents;
}
catch (err) {