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;
|
||||
}
|
||||
|
||||
size_t total = document->_primaryIndex._nrAlloc;
|
||||
size_t pos = TRI_UInt32Random() % total;
|
||||
uint32_t total = (uint32_t) document->_primaryIndex._nrAlloc;
|
||||
uint32_t pos = TRI_UInt32Random() % total;
|
||||
void** beg = document->_primaryIndex._table;
|
||||
|
||||
while (beg[pos] == 0) {
|
||||
|
@ -564,7 +564,7 @@ namespace triagens {
|
|||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
ids.reserve(document->_primaryIndex._nrUsed);
|
||||
ids.reserve((size_t) document->_primaryIndex._nrUsed);
|
||||
|
||||
void** ptr = document->_primaryIndex._table;
|
||||
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
|
||||
// ...........................................................................
|
||||
|
||||
vector<TRI_doc_mptr_copy_t> filtered;
|
||||
|
||||
trx.lockRead();
|
||||
|
||||
// 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);
|
||||
|
||||
|
|
|
@ -3033,7 +3033,7 @@ static int FillIndex (TRI_document_collection_t* document,
|
|||
|
||||
if (idx->sizeHint != nullptr) {
|
||||
// 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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,68 +39,55 @@
|
|||
/// @brief initial number of elements in the index
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define INITIAL_SIZE (11)
|
||||
constexpr uint64_t InitialSize () {
|
||||
return 11;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool ResizePrimaryIndex (TRI_primary_index_t* idx,
|
||||
uint32_t targetSize) {
|
||||
void** oldTable;
|
||||
uint32_t oldAlloc;
|
||||
uint32_t j;
|
||||
uint64_t targetSize) {
|
||||
TRI_ASSERT(targetSize > 0);
|
||||
|
||||
oldTable = idx->_table;
|
||||
oldAlloc = idx->_nrAlloc;
|
||||
void** oldTable = idx->_table;
|
||||
|
||||
idx->_nrAlloc = targetSize;
|
||||
#ifdef TRI_INTERNAL_STATS
|
||||
idx->_nrResizes++;
|
||||
#endif
|
||||
|
||||
idx->_table = (void**) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, (size_t) (idx->_nrAlloc * sizeof(void*)), true);
|
||||
idx->_table = static_cast<void**>(TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, (size_t) (targetSize * sizeof(void*)), true));
|
||||
|
||||
if (idx->_table == nullptr) {
|
||||
idx->_nrAlloc = oldAlloc;
|
||||
idx->_table = oldTable;
|
||||
|
||||
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
|
||||
for (j = 0; j < oldAlloc; j++) {
|
||||
if (oldTable[j] != nullptr) {
|
||||
AddNewElement(idx, oldTable[j]);
|
||||
if (element != nullptr) {
|
||||
uint64_t const hash = element->_hash;
|
||||
uint64_t i, k;
|
||||
|
||||
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);
|
||||
idx->_nrAlloc = targetSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -113,13 +100,9 @@ static inline bool IsEqualKeyElement (TRI_doc_mptr_t const* header,
|
|||
void 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
|
||||
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) {
|
||||
TRI_doc_mptr_t const* e = static_cast<TRI_doc_mptr_t const*>(element);
|
||||
|
||||
if (hash != e->_hash) {
|
||||
return false;
|
||||
}
|
||||
return (strcmp(key, TRI_EXTRACT_MARKER_KEY(e)) == 0); // ONLY IN INDEX, PROTECTED by RUNTIME
|
||||
return (hash == e->_hash &&
|
||||
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->_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;
|
||||
}
|
||||
|
||||
idx->_nrAlloc = INITIAL_SIZE;
|
||||
idx->_nrAlloc = InitialSize();
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
@ -182,14 +165,22 @@ void* TRI_LookupByKeyPrimaryIndex (TRI_primary_index_t* idx,
|
|||
}
|
||||
|
||||
// compute the hash
|
||||
uint64_t hash = TRI_FnvHashString((char const*) key);
|
||||
uint64_t i = hash % idx->_nrAlloc;
|
||||
uint64_t const hash = TRI_FnvHashString((char const*) key);
|
||||
uint64_t const n = idx->_nrAlloc;
|
||||
uint64_t i, k;
|
||||
|
||||
i = k = hash % n;
|
||||
|
||||
TRI_ASSERT_EXPENSIVE(n > 0);
|
||||
|
||||
// search the table
|
||||
while (idx->_table[i] != nullptr && ! IsEqualHashElement((char const*) key, hash, idx->_table[i])) {
|
||||
i = TRI_IncModU64(i, idx->_nrAlloc);
|
||||
for (; i < n && idx->_table[i] != nullptr && ! IsEqualHashElement((char const*) key, hash, idx->_table[i]); ++i);
|
||||
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 idx->_table[i];
|
||||
}
|
||||
|
@ -204,20 +195,27 @@ int TRI_InsertKeyPrimaryIndex (TRI_primary_index_t* idx,
|
|||
void const** found) {
|
||||
*found = nullptr;
|
||||
|
||||
if (idx->_nrAlloc < 2 * idx->_nrUsed) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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];
|
||||
|
||||
// if we found an element, return
|
||||
|
@ -227,23 +225,9 @@ int TRI_InsertKeyPrimaryIndex (TRI_primary_index_t* idx,
|
|||
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
|
||||
idx->_table[i] = (void*) header;
|
||||
idx->_nrUsed++;
|
||||
++idx->_nrUsed;
|
||||
|
||||
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 const* key) {
|
||||
uint64_t hash = TRI_FnvHashString((char const*) key);
|
||||
uint64_t i = hash % idx->_nrAlloc;
|
||||
uint64_t const hash = TRI_FnvHashString((char const*) key);
|
||||
uint64_t const n = idx->_nrAlloc;
|
||||
uint64_t i, k;
|
||||
|
||||
i = k = hash % n;
|
||||
|
||||
// search the table
|
||||
while (idx->_table[i] != nullptr && ! IsEqualHashElement((char const*) key, hash, idx->_table[i])) {
|
||||
i = TRI_IncModU64(i, idx->_nrAlloc);
|
||||
for (; i < n && idx->_table[i] != nullptr && ! IsEqualHashElement((char const*) key, hash, idx->_table[i]); ++i);
|
||||
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 (idx->_table[i] == nullptr) {
|
||||
return nullptr;
|
||||
|
@ -273,10 +263,10 @@ void* TRI_RemoveKeyPrimaryIndex (TRI_primary_index_t* idx,
|
|||
idx->_nrUsed--;
|
||||
|
||||
// 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) {
|
||||
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))) {
|
||||
idx->_table[i] = idx->_table[k];
|
||||
|
@ -284,7 +274,7 @@ void* TRI_RemoveKeyPrimaryIndex (TRI_primary_index_t* idx,
|
|||
i = k;
|
||||
}
|
||||
|
||||
k = TRI_IncModU64(k, idx->_nrAlloc);
|
||||
k = TRI_IncModU64(k, n);
|
||||
}
|
||||
|
||||
// return success
|
||||
|
|
|
@ -43,8 +43,8 @@ struct TRI_doc_mptr_t;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct TRI_primary_index_s {
|
||||
uint32_t _nrAlloc; // the size of the table
|
||||
uint32_t _nrUsed; // the number of used entries
|
||||
uint64_t _nrAlloc; // the size of the table
|
||||
uint64_t _nrUsed; // the number of used entries
|
||||
|
||||
void** _table; // the table itself
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue