mirror of https://gitee.com/bigwinds/arangodb
prevent exceptions
This commit is contained in:
parent
964af24fe7
commit
37a30b420d
|
@ -501,8 +501,8 @@ namespace triagens {
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
return TRI_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t total = document->_primaryIndex._nrAlloc;
|
uint32_t total = (uint32_t) document->_primaryIndex._nrAlloc;
|
||||||
size_t pos = TRI_UInt32Random() % total;
|
uint32_t pos = TRI_UInt32Random() % total;
|
||||||
void** beg = document->_primaryIndex._table;
|
void** beg = document->_primaryIndex._table;
|
||||||
|
|
||||||
while (beg[pos] == 0) {
|
while (beg[pos] == 0) {
|
||||||
|
@ -564,7 +564,7 @@ namespace triagens {
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
return TRI_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
ids.reserve(document->_primaryIndex._nrUsed);
|
ids.reserve((size_t) document->_primaryIndex._nrUsed);
|
||||||
|
|
||||||
void** ptr = document->_primaryIndex._table;
|
void** ptr = document->_primaryIndex._table;
|
||||||
void** end = ptr + document->_primaryIndex._nrAlloc;
|
void** end = ptr + document->_primaryIndex._nrAlloc;
|
||||||
|
|
|
@ -1879,10 +1879,17 @@ static v8::Handle<v8::Value> JS_ByExampleQuery (v8::Arguments const& argv) {
|
||||||
// inside a read transaction
|
// inside a read transaction
|
||||||
// ...........................................................................
|
// ...........................................................................
|
||||||
|
|
||||||
|
vector<TRI_doc_mptr_copy_t> filtered;
|
||||||
|
|
||||||
trx.lockRead();
|
trx.lockRead();
|
||||||
|
|
||||||
// find documents by example
|
// find documents by example
|
||||||
vector<TRI_doc_mptr_copy_t> filtered = TRI_SelectByExample(trx.trxCollection(), n, pids, values);
|
try {
|
||||||
|
filtered = TRI_SelectByExample(trx.trxCollection(), n, pids, values);
|
||||||
|
}
|
||||||
|
catch (std::exception& ex) {
|
||||||
|
TRI_V8_EXCEPTION_MEMORY(scope);
|
||||||
|
}
|
||||||
|
|
||||||
trx.finish(res);
|
trx.finish(res);
|
||||||
|
|
||||||
|
|
|
@ -3033,7 +3033,7 @@ static int FillIndex (TRI_document_collection_t* document,
|
||||||
|
|
||||||
if (idx->sizeHint != nullptr) {
|
if (idx->sizeHint != nullptr) {
|
||||||
// give the index a size hint
|
// give the index a size hint
|
||||||
idx->sizeHint(idx, document->_primaryIndex._nrUsed);
|
idx->sizeHint(idx, (size_t) document->_primaryIndex._nrUsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -5216,7 +5216,8 @@ std::vector<TRI_doc_mptr_copy_t> TRI_SelectByExample (
|
||||||
TRI_doc_mptr_t** end = (TRI_doc_mptr_t**) ptr + document->_primaryIndex._nrAlloc;
|
TRI_doc_mptr_t** end = (TRI_doc_mptr_t**) ptr + document->_primaryIndex._nrAlloc;
|
||||||
|
|
||||||
for (; ptr < end; ++ptr) {
|
for (; ptr < end; ++ptr) {
|
||||||
if (*ptr != nullptr && IsExampleMatch(trxCollection, shaper, *ptr, length, pids, values)) {
|
if (*ptr != nullptr &&
|
||||||
|
IsExampleMatch(trxCollection, shaper, *ptr, length, pids, values)) {
|
||||||
filtered.push_back(**ptr);
|
filtered.push_back(**ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,68 +39,55 @@
|
||||||
/// @brief initial number of elements in the index
|
/// @brief initial number of elements in the index
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define INITIAL_SIZE (11)
|
constexpr uint64_t InitialSize () {
|
||||||
|
return 11;
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- private functions
|
// --SECTION-- private functions
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief adds a new element
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static void AddNewElement (TRI_primary_index_t* idx, void* element) {
|
|
||||||
uint64_t hash = ((TRI_doc_mptr_t const*) element)->_hash;
|
|
||||||
|
|
||||||
// search the table
|
|
||||||
uint64_t i = hash % idx->_nrAlloc;
|
|
||||||
|
|
||||||
while (idx->_table[i] != nullptr) {
|
|
||||||
i = TRI_IncModU64(i, idx->_nrAlloc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add a new element to the associative idx
|
|
||||||
idx->_table[i] = element;
|
|
||||||
idx->_nrUsed++;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief resizes the index
|
/// @brief resizes the index
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static bool ResizePrimaryIndex (TRI_primary_index_t* idx,
|
static bool ResizePrimaryIndex (TRI_primary_index_t* idx,
|
||||||
uint32_t targetSize) {
|
uint64_t targetSize) {
|
||||||
void** oldTable;
|
TRI_ASSERT(targetSize > 0);
|
||||||
uint32_t oldAlloc;
|
|
||||||
uint32_t j;
|
|
||||||
|
|
||||||
oldTable = idx->_table;
|
void** oldTable = idx->_table;
|
||||||
oldAlloc = idx->_nrAlloc;
|
|
||||||
|
|
||||||
idx->_nrAlloc = targetSize;
|
idx->_table = static_cast<void**>(TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, (size_t) (targetSize * sizeof(void*)), true));
|
||||||
#ifdef TRI_INTERNAL_STATS
|
|
||||||
idx->_nrResizes++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
idx->_table = (void**) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, (size_t) (idx->_nrAlloc * sizeof(void*)), true);
|
|
||||||
|
|
||||||
if (idx->_table == nullptr) {
|
if (idx->_table == nullptr) {
|
||||||
idx->_nrAlloc = oldAlloc;
|
|
||||||
idx->_table = oldTable;
|
idx->_table = oldTable;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
idx->_nrUsed = 0;
|
// table is already cleared by allocate, now copy old data
|
||||||
|
for (uint64_t j = 0; j < idx->_nrAlloc; j++) {
|
||||||
|
TRI_doc_mptr_t const* element = static_cast<TRI_doc_mptr_t const*>(oldTable[j]);
|
||||||
|
|
||||||
// table is already cleared by allocate, copy old data
|
if (element != nullptr) {
|
||||||
for (j = 0; j < oldAlloc; j++) {
|
uint64_t const hash = element->_hash;
|
||||||
if (oldTable[j] != nullptr) {
|
uint64_t i, k;
|
||||||
AddNewElement(idx, oldTable[j]);
|
|
||||||
|
i = k = hash % targetSize;
|
||||||
|
|
||||||
|
for (; i < targetSize && idx->_table[i] != nullptr; ++i);
|
||||||
|
if (i == targetSize) {
|
||||||
|
for (i = 0; i < k && idx->_table[i] != nullptr; ++i);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_ASSERT_EXPENSIVE(i < targetSize);
|
||||||
|
|
||||||
|
idx->_table[i] = (void*) element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, oldTable);
|
TRI_Free(TRI_UNKNOWN_MEM_ZONE, oldTable);
|
||||||
|
idx->_nrAlloc = targetSize;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -113,13 +100,9 @@ static inline bool IsEqualKeyElement (TRI_doc_mptr_t const* header,
|
||||||
void const* element) {
|
void const* element) {
|
||||||
TRI_doc_mptr_t const* e = static_cast<TRI_doc_mptr_t const*>(element);
|
TRI_doc_mptr_t const* e = static_cast<TRI_doc_mptr_t const*>(element);
|
||||||
|
|
||||||
if (header->_hash != e->_hash) {
|
|
||||||
// first compare hash values
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// only after that compare actual keys
|
// only after that compare actual keys
|
||||||
return (strcmp(TRI_EXTRACT_MARKER_KEY(header), TRI_EXTRACT_MARKER_KEY(e)) == 0); // ONLY IN INDEX, PROTECTED by RUNTIME
|
return (header->_hash == e->_hash &&
|
||||||
|
strcmp(TRI_EXTRACT_MARKER_KEY(header), TRI_EXTRACT_MARKER_KEY(e)) == 0); // ONLY IN INDEX, PROTECTED by RUNTIME
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -129,10 +112,8 @@ static inline bool IsEqualKeyElement (TRI_doc_mptr_t const* header,
|
||||||
static inline bool IsEqualHashElement (char const* key, uint64_t hash, void const* element) {
|
static inline bool IsEqualHashElement (char const* key, uint64_t hash, void const* element) {
|
||||||
TRI_doc_mptr_t const* e = static_cast<TRI_doc_mptr_t const*>(element);
|
TRI_doc_mptr_t const* e = static_cast<TRI_doc_mptr_t const*>(element);
|
||||||
|
|
||||||
if (hash != e->_hash) {
|
return (hash == e->_hash &&
|
||||||
return false;
|
strcmp(key, TRI_EXTRACT_MARKER_KEY(e)) == 0); // ONLY IN INDEX, PROTECTED by RUNTIME
|
||||||
}
|
|
||||||
return (strcmp(key, TRI_EXTRACT_MARKER_KEY(e)) == 0); // ONLY IN INDEX, PROTECTED by RUNTIME
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -147,11 +128,13 @@ int TRI_InitPrimaryIndex (TRI_primary_index_t* idx) {
|
||||||
idx->_nrAlloc = 0;
|
idx->_nrAlloc = 0;
|
||||||
idx->_nrUsed = 0;
|
idx->_nrUsed = 0;
|
||||||
|
|
||||||
if (nullptr == (idx->_table = (void**) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(void*) * INITIAL_SIZE, true))) {
|
idx->_table = static_cast<void**>(TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, (size_t) (InitialSize() * sizeof(void*)), true));
|
||||||
|
|
||||||
|
if (idx->_table == nullptr) {
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
return TRI_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
idx->_nrAlloc = INITIAL_SIZE;
|
idx->_nrAlloc = InitialSize();
|
||||||
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -182,14 +165,22 @@ void* TRI_LookupByKeyPrimaryIndex (TRI_primary_index_t* idx,
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute the hash
|
// compute the hash
|
||||||
uint64_t hash = TRI_FnvHashString((char const*) key);
|
uint64_t const hash = TRI_FnvHashString((char const*) key);
|
||||||
uint64_t i = hash % idx->_nrAlloc;
|
uint64_t const n = idx->_nrAlloc;
|
||||||
|
uint64_t i, k;
|
||||||
|
|
||||||
|
i = k = hash % n;
|
||||||
|
|
||||||
|
TRI_ASSERT_EXPENSIVE(n > 0);
|
||||||
|
|
||||||
// search the table
|
// search the table
|
||||||
while (idx->_table[i] != nullptr && ! IsEqualHashElement((char const*) key, hash, idx->_table[i])) {
|
for (; i < n && idx->_table[i] != nullptr && ! IsEqualHashElement((char const*) key, hash, idx->_table[i]); ++i);
|
||||||
i = TRI_IncModU64(i, idx->_nrAlloc);
|
if (i == n) {
|
||||||
|
for (i = 0; i < k && idx->_table[i] != nullptr && ! IsEqualHashElement((char const*) key, hash, idx->_table[i]); ++i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRI_ASSERT_EXPENSIVE(i < n);
|
||||||
|
|
||||||
// return whatever we found
|
// return whatever we found
|
||||||
return idx->_table[i];
|
return idx->_table[i];
|
||||||
}
|
}
|
||||||
|
@ -204,20 +195,27 @@ int TRI_InsertKeyPrimaryIndex (TRI_primary_index_t* idx,
|
||||||
void const** found) {
|
void const** found) {
|
||||||
*found = nullptr;
|
*found = nullptr;
|
||||||
|
|
||||||
|
if (idx->_nrAlloc < 2 * idx->_nrUsed) {
|
||||||
// check for out-of-memory
|
// check for out-of-memory
|
||||||
if (idx->_nrAlloc == idx->_nrUsed) {
|
if (! ResizePrimaryIndex(idx, (uint64_t) (2 * idx->_nrAlloc + 1))) {
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
return TRI_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute the hash
|
|
||||||
uint64_t hash = header->_hash;
|
|
||||||
uint64_t i = hash % idx->_nrAlloc;
|
|
||||||
|
|
||||||
// search the table
|
|
||||||
while (idx->_table[i] != nullptr && ! IsEqualKeyElement(header, idx->_table[i])) {
|
|
||||||
i = TRI_IncModU64(i, idx->_nrAlloc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t const n = idx->_nrAlloc;
|
||||||
|
uint64_t i, k;
|
||||||
|
|
||||||
|
TRI_ASSERT_EXPENSIVE(n > 0);
|
||||||
|
|
||||||
|
i = k = header->_hash % n;
|
||||||
|
|
||||||
|
for (; i < n && idx->_table[i] != nullptr && ! IsEqualKeyElement(header, idx->_table[i]); ++i);
|
||||||
|
if (i == n) {
|
||||||
|
for (i = 0; i < k && idx->_table[i] != nullptr && ! IsEqualKeyElement(header, idx->_table[i]); ++i);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_ASSERT_EXPENSIVE(i < n);
|
||||||
|
|
||||||
void* old = idx->_table[i];
|
void* old = idx->_table[i];
|
||||||
|
|
||||||
// if we found an element, return
|
// if we found an element, return
|
||||||
|
@ -227,23 +225,9 @@ int TRI_InsertKeyPrimaryIndex (TRI_primary_index_t* idx,
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we were adding and the table is more than half full, extend it
|
|
||||||
if (idx->_nrAlloc < 2 * idx->_nrUsed) {
|
|
||||||
if (! ResizePrimaryIndex(idx, (uint32_t) (2 * idx->_nrAlloc) + 1)) {
|
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// now we need to recalc the position
|
|
||||||
i = hash % idx->_nrAlloc;
|
|
||||||
// search the table
|
|
||||||
while (idx->_table[i] != nullptr && ! IsEqualKeyElement(header, idx->_table[i])) {
|
|
||||||
i = TRI_IncModU64(i, idx->_nrAlloc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add a new element to the associative idx
|
// add a new element to the associative idx
|
||||||
idx->_table[i] = (void*) header;
|
idx->_table[i] = (void*) header;
|
||||||
idx->_nrUsed++;
|
++idx->_nrUsed;
|
||||||
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -254,14 +238,20 @@ int TRI_InsertKeyPrimaryIndex (TRI_primary_index_t* idx,
|
||||||
|
|
||||||
void* TRI_RemoveKeyPrimaryIndex (TRI_primary_index_t* idx,
|
void* TRI_RemoveKeyPrimaryIndex (TRI_primary_index_t* idx,
|
||||||
void const* key) {
|
void const* key) {
|
||||||
uint64_t hash = TRI_FnvHashString((char const*) key);
|
uint64_t const hash = TRI_FnvHashString((char const*) key);
|
||||||
uint64_t i = hash % idx->_nrAlloc;
|
uint64_t const n = idx->_nrAlloc;
|
||||||
|
uint64_t i, k;
|
||||||
|
|
||||||
|
i = k = hash % n;
|
||||||
|
|
||||||
// search the table
|
// search the table
|
||||||
while (idx->_table[i] != nullptr && ! IsEqualHashElement((char const*) key, hash, idx->_table[i])) {
|
for (; i < n && idx->_table[i] != nullptr && ! IsEqualHashElement((char const*) key, hash, idx->_table[i]); ++i);
|
||||||
i = TRI_IncModU64(i, idx->_nrAlloc);
|
if (i == n) {
|
||||||
|
for (i = 0; i < k && idx->_table[i] != nullptr && ! IsEqualHashElement((char const*) key, hash, idx->_table[i]); ++i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRI_ASSERT_EXPENSIVE(i < n);
|
||||||
|
|
||||||
// if we did not find such an item return false
|
// if we did not find such an item return false
|
||||||
if (idx->_table[i] == nullptr) {
|
if (idx->_table[i] == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -273,10 +263,10 @@ void* TRI_RemoveKeyPrimaryIndex (TRI_primary_index_t* idx,
|
||||||
idx->_nrUsed--;
|
idx->_nrUsed--;
|
||||||
|
|
||||||
// and now check the following places for items to move here
|
// and now check the following places for items to move here
|
||||||
uint64_t k = TRI_IncModU64(i, idx->_nrAlloc);
|
k = TRI_IncModU64(i, n);
|
||||||
|
|
||||||
while (idx->_table[k] != nullptr) {
|
while (idx->_table[k] != nullptr) {
|
||||||
uint64_t j = (((TRI_doc_mptr_t const*) idx->_table[k])->_hash) % idx->_nrAlloc;
|
uint64_t j = (((TRI_doc_mptr_t const*) idx->_table[k])->_hash) % n;
|
||||||
|
|
||||||
if ((i < k && ! (i < j && j <= k)) || (k < i && ! (i < j || j <= k))) {
|
if ((i < k && ! (i < j && j <= k)) || (k < i && ! (i < j || j <= k))) {
|
||||||
idx->_table[i] = idx->_table[k];
|
idx->_table[i] = idx->_table[k];
|
||||||
|
@ -284,7 +274,7 @@ void* TRI_RemoveKeyPrimaryIndex (TRI_primary_index_t* idx,
|
||||||
i = k;
|
i = k;
|
||||||
}
|
}
|
||||||
|
|
||||||
k = TRI_IncModU64(k, idx->_nrAlloc);
|
k = TRI_IncModU64(k, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return success
|
// return success
|
||||||
|
|
|
@ -43,8 +43,8 @@ struct TRI_doc_mptr_t;
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
typedef struct TRI_primary_index_s {
|
typedef struct TRI_primary_index_s {
|
||||||
uint32_t _nrAlloc; // the size of the table
|
uint64_t _nrAlloc; // the size of the table
|
||||||
uint32_t _nrUsed; // the number of used entries
|
uint64_t _nrUsed; // the number of used entries
|
||||||
|
|
||||||
void** _table; // the table itself
|
void** _table; // the table itself
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue