mirror of https://gitee.com/bigwinds/arangodb
less copying hash index results
This commit is contained in:
parent
37ae686d4b
commit
cacaddd5e0
|
@ -740,6 +740,7 @@ int EnumerateCollectionBlock::initializeCursor (AqlItemBlock* items, size_t pos)
|
|||
|
||||
AqlItemBlock* EnumerateCollectionBlock::getSome (size_t, // atLeast,
|
||||
size_t atMost) {
|
||||
|
||||
// Invariants:
|
||||
// As soon as we notice that _totalCount == 0, we set _done = true.
|
||||
// Otherwise, outside of this method (or skipSome), _documents is
|
||||
|
@ -1359,7 +1360,7 @@ std::vector<RangeInfo> IndexRangeBlock::andCombineRangeInfoVecs (
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IndexOrCondition* IndexRangeBlock::cartesian (
|
||||
std::vector<std::vector<RangeInfo>> collector) {
|
||||
std::vector<std::vector<RangeInfo>> const& collector) {
|
||||
|
||||
std::vector<size_t> indexes;
|
||||
indexes.reserve(collector.size());
|
||||
|
@ -1779,26 +1780,18 @@ void IndexRangeBlock::readHashIndex (IndexOrCondition const& ranges) {
|
|||
|
||||
for (size_t i = 0; i < ranges.size(); i++) {
|
||||
if (setupSearchValue(i)) {
|
||||
TRI_vector_pointer_t list = TRI_LookupHashIndex(idx, &searchValue);
|
||||
destroySearchValue();
|
||||
|
||||
size_t const n = TRI_LengthVectorPointer(&list);
|
||||
try {
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
_documents.emplace_back(* (static_cast<TRI_doc_mptr_t*>(TRI_AtVectorPointer(&list, i))));
|
||||
}
|
||||
|
||||
_engine->_stats.scannedIndex += static_cast<int64_t>(n);
|
||||
TRI_DestroyVectorPointer(&list);
|
||||
size_t const n = _documents.size();
|
||||
TRI_LookupHashIndex(idx, &searchValue, _documents);
|
||||
_engine->_stats.scannedIndex += static_cast<int64_t>(_documents.size() - n);
|
||||
}
|
||||
catch (...) {
|
||||
TRI_DestroyVectorPointer(&list);
|
||||
destroySearchValue();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
else {
|
||||
destroySearchValue();
|
||||
}
|
||||
|
||||
destroySearchValue();
|
||||
}
|
||||
LEAVE_BLOCK;
|
||||
}
|
||||
|
|
|
@ -637,7 +637,7 @@ namespace triagens {
|
|||
/// "and" condition containing an "or" condition, which we must then distribute.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IndexOrCondition* cartesian (std::vector<std::vector<RangeInfo>>);
|
||||
IndexOrCondition* cartesian (std::vector<std::vector<RangeInfo>> const&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief: subclass for comparing IndexAndConditions in _condition. Similar to
|
||||
|
|
|
@ -539,7 +539,7 @@ namespace triagens {
|
|||
/// @brief clone
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
RangeInfo clone () {
|
||||
RangeInfo clone () const {
|
||||
RangeInfo copy(_var, _attr);
|
||||
|
||||
copy._lowConst.assign(_lowConst);
|
||||
|
@ -556,8 +556,6 @@ namespace triagens {
|
|||
copy._equality = _equality;
|
||||
|
||||
return copy;
|
||||
//FIXME the following should work but doesn't!!
|
||||
//return RangeInfo(this->toJson());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -481,55 +481,39 @@ TRI_vector_pointer_t TRI_LookupByKeyHashArrayMulti (TRI_hash_array_multi_t const
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief lookups an element given a key and a state
|
||||
/// @brief lookups an element given a key
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vector_pointer_t TRI_LookupByKeyHashArrayMulti (TRI_hash_array_multi_t const* array,
|
||||
TRI_index_search_value_t const* key,
|
||||
TRI_hash_index_element_multi_t*& next,
|
||||
size_t batchSize) {
|
||||
int TRI_LookupByKeyHashArrayMulti (TRI_hash_array_multi_t const* array,
|
||||
TRI_index_search_value_t const* key,
|
||||
std::vector<TRI_doc_mptr_copy_t>& result) {
|
||||
TRI_ASSERT_EXPENSIVE(array->_nrUsed < array->_nrAlloc);
|
||||
TRI_ASSERT(batchSize > 0);
|
||||
|
||||
// ...........................................................................
|
||||
// initialise the vector which will hold the result if any
|
||||
// ...........................................................................
|
||||
uint64_t const n = array->_nrAlloc;
|
||||
uint64_t i, k;
|
||||
|
||||
TRI_vector_pointer_t result;
|
||||
TRI_InitVectorPointer(&result, TRI_UNKNOWN_MEM_ZONE);
|
||||
|
||||
if (next == nullptr) {
|
||||
// no previous state. start at the beginning
|
||||
uint64_t const n = array->_nrAlloc;
|
||||
uint64_t i, k;
|
||||
|
||||
i = k = HashKey(array, key) % n;
|
||||
i = k = HashKey(array, key) % n;
|
||||
|
||||
for (; i < n && array->_table[i]._document != nullptr && ! IsEqualKeyElement(array, key, &array->_table[i]); ++i);
|
||||
if (i == n) {
|
||||
for (i = 0; i < k && array->_table[i]._document != nullptr && ! IsEqualKeyElement(array, key, &array->_table[i]); ++i);
|
||||
}
|
||||
|
||||
TRI_ASSERT_EXPENSIVE(i < n);
|
||||
|
||||
if (array->_table[i]._document != nullptr) {
|
||||
TRI_PushBackVectorPointer(&result, array->_table[i]._document);
|
||||
}
|
||||
next = array->_table[i]._next;
|
||||
for (; i < n && array->_table[i]._document != nullptr && ! IsEqualKeyElement(array, key, &array->_table[i]); ++i);
|
||||
if (i == n) {
|
||||
for (i = 0; i < k && array->_table[i]._document != nullptr && ! IsEqualKeyElement(array, key, &array->_table[i]); ++i);
|
||||
}
|
||||
|
||||
if (next != nullptr) {
|
||||
// we already had a state
|
||||
size_t total = TRI_LengthVectorPointer(&result);;
|
||||
|
||||
while (next != nullptr && total < batchSize) {
|
||||
TRI_PushBackVectorPointer(&result, next->_document);
|
||||
next = next->_next;
|
||||
++total;
|
||||
TRI_ASSERT_EXPENSIVE(i < n);
|
||||
|
||||
if (array->_table[i]._document != nullptr) {
|
||||
// add the element itself
|
||||
result.emplace_back(*(array->_table[i]._document));
|
||||
|
||||
// add the overflow elements
|
||||
auto current = array->_table[i]._next;
|
||||
while (current != nullptr) {
|
||||
result.emplace_back(*(current->_document));
|
||||
current = current->_next;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include "Basics/Common.h"
|
||||
#include "Basics/vector.h"
|
||||
#include "VocBase/document-collection.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- forward declarations
|
||||
|
@ -121,13 +122,12 @@ TRI_vector_pointer_t TRI_LookupByKeyHashArrayMulti (TRI_hash_array_multi_t const
|
|||
struct TRI_index_search_value_s const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief lookups an element given a key and a state
|
||||
/// @brief lookups an element given a key
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vector_pointer_t TRI_LookupByKeyHashArrayMulti (TRI_hash_array_multi_t const*,
|
||||
struct TRI_index_search_value_s const*,
|
||||
struct TRI_hash_index_element_multi_s*&,
|
||||
size_t);
|
||||
int TRI_LookupByKeyHashArrayMulti (TRI_hash_array_multi_t const*,
|
||||
struct TRI_index_search_value_s const*,
|
||||
std::vector<TRI_doc_mptr_copy_t>&);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief adds an element to the array
|
||||
|
|
|
@ -312,6 +312,29 @@ static TRI_vector_pointer_t HashIndex_find (TRI_hash_index_t* hashIndex,
|
|||
return results;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief locates a key within the hash array part
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int HashIndex_find (TRI_hash_index_t* hashIndex,
|
||||
TRI_index_search_value_t* key,
|
||||
std::vector<TRI_doc_mptr_copy_t>& result) {
|
||||
|
||||
// .............................................................................
|
||||
// A find request means that a set of values for the "key" was sent. We need
|
||||
// to locate the hash array entry by key.
|
||||
// .............................................................................
|
||||
|
||||
TRI_hash_index_element_t* found = TRI_FindByKeyHashArray(&hashIndex->_hashArray, key);
|
||||
|
||||
if (found != nullptr) {
|
||||
// unique hash index: maximum number is 1
|
||||
result.emplace_back(*(found->_document));
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- multi hash array management
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -676,25 +699,18 @@ TRI_vector_pointer_t TRI_LookupHashIndex (TRI_index_t* idx,
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief locates entries in the hash index given shaped json objects
|
||||
/// this function uses the state passed to it to return a fragment of the
|
||||
/// total result - the next call to the function can resume at the state where
|
||||
/// it was left off last
|
||||
/// note: state is ignored for unique indexes as there will be at most one
|
||||
/// item in the result
|
||||
/// it is the callers responsibility to destroy the result
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vector_pointer_t TRI_LookupHashIndex (TRI_index_t* idx,
|
||||
TRI_index_search_value_t* searchValue,
|
||||
TRI_hash_index_element_multi_t*& next,
|
||||
size_t batchSize) {
|
||||
int TRI_LookupHashIndex (TRI_index_t* idx,
|
||||
TRI_index_search_value_t* searchValue,
|
||||
std::vector<TRI_doc_mptr_copy_t>& documents) {
|
||||
TRI_hash_index_t* hashIndex = (TRI_hash_index_t*) idx;
|
||||
|
||||
if (hashIndex->base._unique) {
|
||||
return HashIndex_find(hashIndex, searchValue);
|
||||
return HashIndex_find(hashIndex, searchValue, documents);
|
||||
}
|
||||
|
||||
return TRI_LookupByKeyHashArrayMulti(&hashIndex->_hashArrayMulti, searchValue, next, batchSize);
|
||||
return TRI_LookupByKeyHashArrayMulti(&hashIndex->_hashArrayMulti, searchValue, documents);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "HashIndex/hash-array.h"
|
||||
#include "HashIndex/hash-array-multi.h"
|
||||
#include "VocBase/index.h"
|
||||
#include "VocBase/document-collection.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- forward declarations
|
||||
|
@ -132,18 +133,12 @@ TRI_vector_pointer_t TRI_LookupHashIndex (TRI_index_t*,
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief locates entries in the hash index given shaped json objects
|
||||
/// this function uses the state passed to it to return a fragment of the
|
||||
/// total result - the next call to the function can resume at the state where
|
||||
/// it was left off last
|
||||
/// note: state is ignored for unique indexes as there will be at most one
|
||||
/// item in the result
|
||||
/// it is the callers responsibility to destroy the result
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vector_pointer_t TRI_LookupHashIndex (TRI_index_t*,
|
||||
struct TRI_index_search_value_s*,
|
||||
struct TRI_hash_index_element_multi_s*&,
|
||||
size_t);
|
||||
int TRI_LookupHashIndex (TRI_index_t*,
|
||||
struct TRI_index_search_value_s*,
|
||||
std::vector<TRI_doc_mptr_copy_t>&);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue