1
0
Fork 0

less copying hash index results

This commit is contained in:
Jan Steemann 2015-01-18 00:52:41 +01:00
parent 37ae686d4b
commit cacaddd5e0
7 changed files with 70 additions and 84 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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