mirror of https://gitee.com/bigwinds/arangodb
fixed hash
This commit is contained in:
parent
45f348db2c
commit
e1cd69d515
|
@ -224,12 +224,17 @@ static int SetupExampleObjectIndex (TRI_hash_index_t* hashIndex,
|
|||
*err = TRI_CreateErrorObject(TRI_ERROR_INTERNAL, "shaper failed");
|
||||
return TRI_ERROR_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
|
||||
v8::Handle<v8::String> key = v8::String::New(name);
|
||||
v8::Handle<v8::Value> val = example->Get(key);
|
||||
|
||||
if (example->HasOwnProperty(key)) {
|
||||
v8::Handle<v8::Value> val = example->Get(key);
|
||||
|
||||
values[i] = TRI_ShapedJsonV8Object(val, shaper);
|
||||
values[i] = TRI_ShapedJsonV8Object(val, shaper);
|
||||
}
|
||||
else {
|
||||
values[i] = TRI_ShapedJsonV8Object(v8::Null(), shaper);
|
||||
}
|
||||
|
||||
if (values[i] == 0) {
|
||||
CleanupExampleObject(shaper, i, 0, values);
|
||||
|
@ -459,6 +464,8 @@ static v8::Handle<v8::Value> EdgesQuery (TRI_edge_direction_e direction, v8::Arg
|
|||
TRI_ReleaseCollection(vertexCollection);
|
||||
}
|
||||
|
||||
collection->_collection->endRead(collection->_collection);
|
||||
|
||||
TRI_ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(errMsg));
|
||||
}
|
||||
|
@ -804,12 +811,14 @@ static v8::Handle<v8::Value> JS_ByExampleHashIndex (v8::Arguments const& argv) {
|
|||
int res = SetupExampleObjectIndex(hashIndex, example, shaper, n, values, &err);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
collection->_collection->endRead(collection->_collection);
|
||||
|
||||
TRI_ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(err));
|
||||
}
|
||||
|
||||
// find the matches
|
||||
TRI_hash_index_elements_t* list = TRI_LookupShapedJsonHashIndex(idx, *values);
|
||||
TRI_hash_index_elements_t* list = TRI_LookupShapedJsonHashIndex(idx, values);
|
||||
|
||||
// convert result
|
||||
size_t total = list->_numElements;
|
||||
|
@ -924,12 +933,14 @@ static v8::Handle<v8::Value> JS_NearQuery (v8::Arguments const& argv) {
|
|||
|
||||
if (idx == 0) {
|
||||
collection->_collection->endRead(collection->_collection);
|
||||
|
||||
TRI_ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(err));
|
||||
}
|
||||
|
||||
if (idx->_type != TRI_IDX_TYPE_GEO1_INDEX && idx->_type != TRI_IDX_TYPE_GEO2_INDEX) {
|
||||
collection->_collection->endRead(collection->_collection);
|
||||
|
||||
TRI_ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(TRI_ERROR_BAD_PARAMETER, "index must be a geo-index")));
|
||||
}
|
||||
|
@ -1024,12 +1035,14 @@ static v8::Handle<v8::Value> JS_WithinQuery (v8::Arguments const& argv) {
|
|||
|
||||
if (idx == 0) {
|
||||
collection->_collection->endRead(collection->_collection);
|
||||
|
||||
TRI_ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(err));
|
||||
}
|
||||
|
||||
if (idx->_type != TRI_IDX_TYPE_GEO1_INDEX && idx->_type != TRI_IDX_TYPE_GEO2_INDEX) {
|
||||
collection->_collection->endRead(collection->_collection);
|
||||
|
||||
TRI_ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(TRI_ERROR_BAD_PARAMETER, "index must be a geo-index")));
|
||||
}
|
||||
|
|
|
@ -331,7 +331,8 @@ int FillVectorPointerFromArguments (v8::Arguments const& argv,
|
|||
static v8::Handle<v8::Value> EnsureHashSkipListIndex (string const& cmd,
|
||||
v8::Arguments const& argv,
|
||||
bool unique,
|
||||
int type) {
|
||||
bool create,
|
||||
TRI_idx_type_e type) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
// .............................................................................
|
||||
|
@ -367,17 +368,13 @@ static v8::Handle<v8::Value> EnsureHashSkipListIndex (string const& cmd,
|
|||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(TRI_ERROR_ILLEGAL_OPTION, "usage: " + cmd + "(<path>, ...)")));
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// Return string when there is an error of some sort.
|
||||
// .............................................................................
|
||||
|
||||
string errorString;
|
||||
|
||||
// .............................................................................
|
||||
// Create a list of paths, these will be used to create a list of shapes
|
||||
// which will be used by the hash index.
|
||||
// .............................................................................
|
||||
|
||||
string errorString;
|
||||
|
||||
TRI_vector_pointer_t attributes;
|
||||
TRI_InitVectorPointer(&attributes, TRI_CORE_MEM_ZONE);
|
||||
|
||||
|
@ -402,14 +399,19 @@ static v8::Handle<v8::Value> EnsureHashSkipListIndex (string const& cmd,
|
|||
bool created;
|
||||
TRI_index_t* idx;
|
||||
|
||||
if (type == 0) {
|
||||
idx = TRI_EnsureHashIndexSimCollection(sim, &attributes, unique, &created);
|
||||
if (type == TRI_IDX_TYPE_HASH_INDEX) {
|
||||
if (create) {
|
||||
idx = TRI_EnsureHashIndexSimCollection(sim, &attributes, unique, &created);
|
||||
|
||||
if (idx == 0) {
|
||||
res = TRI_errno();
|
||||
if (idx == 0) {
|
||||
res = TRI_errno();
|
||||
}
|
||||
}
|
||||
else {
|
||||
idx = TRI_LookupHashIndexSimCollection(sim, &attributes, unique);
|
||||
}
|
||||
}
|
||||
else if (type == 1) {
|
||||
else if (type == TRI_IDX_TYPE_SKIPLIST_INDEX) {
|
||||
idx = TRI_EnsureSkiplistIndexSimCollection(sim, &attributes, unique, &created);
|
||||
|
||||
if (idx == 0) {
|
||||
|
@ -417,7 +419,7 @@ static v8::Handle<v8::Value> EnsureHashSkipListIndex (string const& cmd,
|
|||
}
|
||||
}
|
||||
else {
|
||||
LOG_ERROR("unknown index type %d", type);
|
||||
LOG_ERROR("unknown index type %d", (int) type);
|
||||
res = TRI_ERROR_INTERNAL;
|
||||
idx = 0;
|
||||
}
|
||||
|
@ -430,8 +432,14 @@ static v8::Handle<v8::Value> EnsureHashSkipListIndex (string const& cmd,
|
|||
TRI_DestroyVectorPointer(&attributes);
|
||||
|
||||
if (idx == 0) {
|
||||
TRI_ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(res, "index could not be created")));
|
||||
if (create) {
|
||||
TRI_ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(TRI_CreateErrorObject(res, "index could not be created")));
|
||||
}
|
||||
else {
|
||||
TRI_ReleaseCollection(collection);
|
||||
return scope.Close(v8::Null());
|
||||
}
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
|
@ -448,8 +456,10 @@ static v8::Handle<v8::Value> EnsureHashSkipListIndex (string const& cmd,
|
|||
v8::Handle<v8::Value> index = IndexRep(&collection->_collection->base, json);
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
|
||||
if (index->IsObject()) {
|
||||
index->ToObject()->Set(v8::String::New("isNewlyCreated"), created ? v8::True() : v8::False());
|
||||
if (create) {
|
||||
if (index->IsObject()) {
|
||||
index->ToObject()->Set(v8::String::New("isNewlyCreated"), created ? v8::True() : v8::False());
|
||||
}
|
||||
}
|
||||
|
||||
TRI_ReleaseCollection(collection);
|
||||
|
@ -2206,7 +2216,15 @@ static v8::Handle<v8::Value> JS_EnsureGeoConstraintVocbaseCol (v8::Arguments con
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_EnsureUniqueConstraintVocbaseCol (v8::Arguments const& argv) {
|
||||
return EnsureHashSkipListIndex("ensureUniqueConstraint", argv, true, 0);
|
||||
return EnsureHashSkipListIndex("ensureUniqueConstraint", argv, true, true, TRI_IDX_TYPE_HASH_INDEX);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief looks up a unique constraint
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_LookupUniqueConstraintVocbaseCol (v8::Arguments const& argv) {
|
||||
return EnsureHashSkipListIndex("lookupUniqueConstraint", argv, true, false, TRI_IDX_TYPE_HASH_INDEX);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2229,7 +2247,15 @@ static v8::Handle<v8::Value> JS_EnsureUniqueConstraintVocbaseCol (v8::Arguments
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_EnsureHashIndexVocbaseCol (v8::Arguments const& argv) {
|
||||
return EnsureHashSkipListIndex("ensureHashIndex", argv, false, 0);
|
||||
return EnsureHashSkipListIndex("ensureHashIndex", argv, false, true, TRI_IDX_TYPE_HASH_INDEX);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief looks up a hash index
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_LookupHashIndexVocbaseCol (v8::Arguments const& argv) {
|
||||
return EnsureHashSkipListIndex("lookupHashIndex", argv, false, false, TRI_IDX_TYPE_HASH_INDEX);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2369,7 +2395,7 @@ static v8::Handle<v8::Value> JS_EnsurePriorityQueueIndexVocbaseCol (v8::Argument
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_EnsureUniqueSkiplistVocbaseCol (v8::Arguments const& argv) {
|
||||
return EnsureHashSkipListIndex("ensureUniqueSkipList", argv, true, 1);
|
||||
return EnsureHashSkipListIndex("ensureUniqueSkipList", argv, true, true, TRI_IDX_TYPE_SKIPLIST_INDEX);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2389,7 +2415,7 @@ static v8::Handle<v8::Value> JS_EnsureUniqueSkiplistVocbaseCol (v8::Arguments co
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_EnsureSkiplistVocbaseCol (v8::Arguments const& argv) {
|
||||
return EnsureHashSkipListIndex("ensureSkipList", argv, false, 1);
|
||||
return EnsureHashSkipListIndex("ensureSkipList", argv, false, true, TRI_IDX_TYPE_SKIPLIST_INDEX);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -4219,6 +4245,8 @@ void TRI_InitV8VocBridge (v8::Handle<v8::Context> context, TRI_vocbase_t* vocbas
|
|||
v8::Handle<v8::String> HasNextFuncName = v8::Persistent<v8::String>::New(v8::String::New("hasNext"));
|
||||
v8::Handle<v8::String> IdFuncName = v8::Persistent<v8::String>::New(v8::String::New("id"));
|
||||
v8::Handle<v8::String> LoadFuncName = v8::Persistent<v8::String>::New(v8::String::New("load"));
|
||||
v8::Handle<v8::String> LookupHashIndexFuncName = v8::Persistent<v8::String>::New(v8::String::New("lookupHashIndex"));
|
||||
v8::Handle<v8::String> LookupUniqueConstraintFuncName = v8::Persistent<v8::String>::New(v8::String::New("lookupUniqueConstraint"));
|
||||
v8::Handle<v8::String> NameFuncName = v8::Persistent<v8::String>::New(v8::String::New("name"));
|
||||
v8::Handle<v8::String> NextFuncName = v8::Persistent<v8::String>::New(v8::String::New("next"));
|
||||
v8::Handle<v8::String> PersistFuncName = v8::Persistent<v8::String>::New(v8::String::New("persist"));
|
||||
|
@ -4381,6 +4409,8 @@ void TRI_InitV8VocBridge (v8::Handle<v8::Context> context, TRI_vocbase_t* vocbas
|
|||
rt->Set(FiguresFuncName, v8::FunctionTemplate::New(JS_FiguresVocbaseCol));
|
||||
rt->Set(GetIndexesFuncName, v8::FunctionTemplate::New(JS_GetIndexesVocbaseCol));
|
||||
rt->Set(LoadFuncName, v8::FunctionTemplate::New(JS_LoadVocbaseCol));
|
||||
rt->Set(LookupHashIndexFuncName, v8::FunctionTemplate::New(JS_LookupHashIndexVocbaseCol));
|
||||
rt->Set(LookupUniqueConstraintFuncName, v8::FunctionTemplate::New(JS_LookupUniqueConstraintVocbaseCol));
|
||||
rt->Set(NameFuncName, v8::FunctionTemplate::New(JS_NameVocbaseCol));
|
||||
rt->Set(PropertiesFuncName, v8::FunctionTemplate::New(JS_PropertiesVocbaseCol));
|
||||
rt->Set(RemoveFuncName, v8::FunctionTemplate::New(JS_RemoveVocbaseCol));
|
||||
|
@ -4422,6 +4452,8 @@ void TRI_InitV8VocBridge (v8::Handle<v8::Context> context, TRI_vocbase_t* vocbas
|
|||
rt->Set(FiguresFuncName, v8::FunctionTemplate::New(JS_FiguresVocbaseCol));
|
||||
rt->Set(GetIndexesFuncName, v8::FunctionTemplate::New(JS_GetIndexesVocbaseCol));
|
||||
rt->Set(LoadFuncName, v8::FunctionTemplate::New(JS_LoadVocbaseCol));
|
||||
rt->Set(LookupHashIndexFuncName, v8::FunctionTemplate::New(JS_LookupHashIndexVocbaseCol));
|
||||
rt->Set(LookupUniqueConstraintFuncName, v8::FunctionTemplate::New(JS_LookupUniqueConstraintVocbaseCol));
|
||||
rt->Set(NameFuncName, v8::FunctionTemplate::New(JS_NameVocbaseCol));
|
||||
rt->Set(PropertiesFuncName, v8::FunctionTemplate::New(JS_PropertiesVocbaseCol));
|
||||
rt->Set(RemoveFuncName, v8::FunctionTemplate::New(JS_RemoveVocbaseCol));
|
||||
|
|
|
@ -1812,7 +1812,7 @@ TRI_hash_index_elements_t* TRI_LookupJsonHashIndex (TRI_index_t* idx, TRI_json_t
|
|||
|
||||
if (element.fields == NULL) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
LOG_WARNING("out-of-memory in LookupHashIndex");
|
||||
LOG_WARNING("out-of-memory in LookupJsonHashIndex");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1847,16 +1847,27 @@ TRI_hash_index_elements_t* TRI_LookupJsonHashIndex (TRI_index_t* idx, TRI_json_t
|
|||
/// @brief locates entries in the hash index given shaped json objects
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_hash_index_elements_t* TRI_LookupShapedJsonHashIndex (TRI_index_t* idx, TRI_shaped_json_t* values) {
|
||||
TRI_hash_index_elements_t* TRI_LookupShapedJsonHashIndex (TRI_index_t* idx, TRI_shaped_json_t** values) {
|
||||
TRI_hash_index_t* hashIndex;
|
||||
TRI_hash_index_elements_t* result;
|
||||
HashIndexElement element;
|
||||
size_t j;
|
||||
|
||||
hashIndex = (TRI_hash_index_t*) idx;
|
||||
|
||||
element.numFields = hashIndex->_paths._length;
|
||||
element.fields = values;
|
||||
element.fields = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_shaped_json_t) * element.numFields, false);
|
||||
|
||||
if (element.fields == NULL) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
LOG_WARNING("out-of-memory in LookupJsonHashIndex");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (j = 0; j < element.numFields; ++j) {
|
||||
element.fields[j] = *values[j];
|
||||
}
|
||||
|
||||
if (hashIndex->base._unique) {
|
||||
result = HashIndex_find(hashIndex->_hashIndex, &element);
|
||||
}
|
||||
|
@ -1864,6 +1875,8 @@ TRI_hash_index_elements_t* TRI_LookupShapedJsonHashIndex (TRI_index_t* idx, TRI_
|
|||
result = MultiHashIndex_find(hashIndex->_hashIndex, &element);
|
||||
}
|
||||
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, element.fields);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -451,7 +451,7 @@ TRI_hash_index_elements_t* TRI_LookupJsonHashIndex (TRI_index_t*, TRI_json_t*);
|
|||
/// TRI_hash_index_elements_t* results
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_hash_index_elements_t* TRI_LookupShapedJsonHashIndex (TRI_index_t* idx, TRI_shaped_json_t* values);
|
||||
TRI_hash_index_elements_t* TRI_LookupShapedJsonHashIndex (TRI_index_t* idx, TRI_shaped_json_t** values);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
|
|
@ -3192,7 +3192,7 @@ TRI_index_t* TRI_EnsureGeoIndex2SimCollection (TRI_sim_collection_t* sim,
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// --SECTION-- private types
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -3210,6 +3210,73 @@ typedef struct pid_name_s {
|
|||
}
|
||||
pid_name_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup VocBase
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds a hash index (unique or non-unique)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_index_t* LookupHashIndexSimCollection (TRI_sim_collection_t* collection,
|
||||
TRI_vector_t const* paths,
|
||||
bool unique) {
|
||||
TRI_index_t* matchedIndex = NULL;
|
||||
size_t j;
|
||||
size_t k;
|
||||
|
||||
// go through every index and see if we have a match
|
||||
for (j = 0; j < collection->_indexes._length; ++j) {
|
||||
TRI_index_t* idx = collection->_indexes._buffer[j];
|
||||
TRI_hash_index_t* hashIndex = (TRI_hash_index_t*) idx;
|
||||
bool found = true;
|
||||
|
||||
// check that the type of the index is in fact a hash index
|
||||
if (idx->_type != TRI_IDX_TYPE_HASH_INDEX) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check that the uniqueness is the same
|
||||
if (idx->_unique != unique) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check that the number of paths (fields) in the hash index matches that
|
||||
// of the number of attributes
|
||||
if (paths->_length != hashIndex->_paths._length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// go through all the attributes and see if they match
|
||||
for (k = 0; k < paths->_length; ++k) {
|
||||
TRI_shape_pid_t field = *((TRI_shape_pid_t*)(TRI_AtVector(&hashIndex->_paths, k)));
|
||||
TRI_shape_pid_t shape = *((TRI_shape_pid_t*)(TRI_AtVector(paths, k)));
|
||||
|
||||
if (field != shape) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// stop if we found a match
|
||||
if (found) {
|
||||
matchedIndex = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return matchedIndex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief adds a hash index to the collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -3246,7 +3313,7 @@ static TRI_index_t* CreateHashIndexSimCollection (TRI_sim_collection_t* collecti
|
|||
// a new one.
|
||||
// ...........................................................................
|
||||
|
||||
idx = TRI_LookupHashIndexSimCollection(collection, &paths, unique);
|
||||
idx = LookupHashIndexSimCollection(collection, &paths, unique);
|
||||
|
||||
if (idx != NULL) {
|
||||
TRI_DestroyVector(&paths);
|
||||
|
@ -3373,20 +3440,7 @@ static int HashIndexFromJson (TRI_sim_collection_t* sim,
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup VocBase
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief compares pid
|
||||
/// @brief compares pid and name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int ComparePidName (void const* left, void const* right) {
|
||||
|
@ -3396,60 +3450,6 @@ static int ComparePidName (void const* left, void const* right) {
|
|||
return l->_pid - r->_pid;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds a hash index (unique or non-unique)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_index_t* TRI_LookupHashIndexSimCollection (TRI_sim_collection_t* collection,
|
||||
TRI_vector_t const* paths,
|
||||
bool unique) {
|
||||
TRI_index_t* matchedIndex = NULL;
|
||||
size_t j;
|
||||
size_t k;
|
||||
|
||||
// go through every index and see if we have a match
|
||||
for (j = 0; j < collection->_indexes._length; ++j) {
|
||||
TRI_index_t* idx = collection->_indexes._buffer[j];
|
||||
TRI_hash_index_t* hashIndex = (TRI_hash_index_t*) idx;
|
||||
bool found = true;
|
||||
|
||||
// check that the type of the index is in fact a hash index
|
||||
if (idx->_type != TRI_IDX_TYPE_HASH_INDEX) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check that the uniqueness is the same
|
||||
if (idx->_unique != unique) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check that the number of paths (fields) in the hash index matches that
|
||||
// of the number of attributes
|
||||
if (paths->_length != hashIndex->_paths._length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// go through all the attributes and see if they match
|
||||
for (k = 0; k < paths->_length; ++k) {
|
||||
TRI_shape_pid_t field = *((TRI_shape_pid_t*)(TRI_AtVector(&hashIndex->_paths, k)));
|
||||
TRI_shape_pid_t shape = *((TRI_shape_pid_t*)(TRI_AtVector(paths, k)));
|
||||
|
||||
if (field != shape) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// stop if we found a match
|
||||
if (found) {
|
||||
matchedIndex = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return matchedIndex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -3504,6 +3504,49 @@ int TRI_PidNamesByAttributeNames (TRI_vector_pointer_t const* attributes,
|
|||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds a hash index (unique or non-unique)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_index_t* TRI_LookupHashIndexSimCollection (TRI_sim_collection_t* sim,
|
||||
TRI_vector_pointer_t const* attributes,
|
||||
bool unique) {
|
||||
TRI_index_t* idx;
|
||||
TRI_vector_pointer_t fields;
|
||||
TRI_vector_t paths;
|
||||
int res;
|
||||
|
||||
// determine the sorted shape ids for the attributes
|
||||
res = TRI_PidNamesByAttributeNames(attributes,
|
||||
sim->base._shaper,
|
||||
&paths,
|
||||
&fields);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// inside write-lock
|
||||
// .............................................................................
|
||||
|
||||
TRI_READ_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
idx = LookupHashIndexSimCollection(sim, &paths, unique);
|
||||
|
||||
TRI_READ_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
// .............................................................................
|
||||
// outside write-lock
|
||||
// .............................................................................
|
||||
|
||||
// release memory allocated to vector
|
||||
TRI_DestroyVector(&paths);
|
||||
TRI_DestroyVectorPointer(&fields);
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief ensures that a hash index exists
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -3521,10 +3564,7 @@ TRI_index_t* TRI_EnsureHashIndexSimCollection (TRI_sim_collection_t* sim,
|
|||
|
||||
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
// .............................................................................
|
||||
// Given the list of attributes (as strings)
|
||||
// .............................................................................
|
||||
|
||||
// given the list of attributes (as strings)
|
||||
idx = CreateHashIndexSimCollection(sim, attributes, 0, unique, created);
|
||||
|
||||
if (idx == NULL) {
|
||||
|
|
|
@ -512,7 +512,7 @@ int TRI_PidNamesByAttributeNames (TRI_vector_pointer_t const* attributes,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct TRI_index_s* TRI_LookupHashIndexSimCollection (TRI_sim_collection_t*,
|
||||
TRI_vector_t const* paths,
|
||||
TRI_vector_pointer_t const* attributes,
|
||||
bool unique);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -78,6 +78,45 @@ SQ.SimpleQueryAll.prototype.execute = function () {
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief query-by scan or hash index
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function ByExample (collection, example, skip, limit) {
|
||||
var unique = true;
|
||||
var attributes = [];
|
||||
|
||||
for (var k in example) {
|
||||
if (example.hasOwnProperty(k)) {
|
||||
attributes.push(k);
|
||||
|
||||
if (example[k] == null) {
|
||||
unique = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var idx = collection.lookupHashIndex.apply(collection, attributes);
|
||||
|
||||
if (idx == null && unique) {
|
||||
idx = collection.lookupUniqueConstraint(collection, attributes);
|
||||
|
||||
if (idx != null) {
|
||||
console.info("found unique constraint %s", idx.id);
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.info("found hash index %s", idx.id);
|
||||
}
|
||||
|
||||
if (idx != null) {
|
||||
return collection.BY_EXAMPLE_HASH(idx.id, example, skip, limit);
|
||||
}
|
||||
else {
|
||||
return collection.BY_EXAMPLE(example, skip, limit);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes a query-by-example
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -90,7 +129,7 @@ SQ.SimpleQueryByExample.prototype.execute = function () {
|
|||
this._skip = 0;
|
||||
}
|
||||
|
||||
var documents = this._collection.BY_EXAMPLE(this._example, this._skip, this._limit);
|
||||
var documents = ByExample(this._collection, this._example, this._skip, this._limit);
|
||||
|
||||
this._execution = new SQ.GeneralArrayCursor(documents.documents);
|
||||
this._countQuery = documents.count;
|
||||
|
@ -149,7 +188,7 @@ AvocadoCollection.prototype.firstExample = function () {
|
|||
}
|
||||
}
|
||||
|
||||
var documents = this.BY_EXAMPLE(example, 0, 1);
|
||||
var documents = ByExample(this._collection, this._example, 0, 1);
|
||||
|
||||
if (0 < documents.documents.length) {
|
||||
return documents.documents[0];
|
||||
|
|
Loading…
Reference in New Issue