1
0
Fork 0

prevent exceptions

This commit is contained in:
Jan Steemann 2014-06-14 15:05:54 +02:00
parent 964af24fe7
commit 37a30b420d
5 changed files with 93 additions and 95 deletions

View File

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

View File

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

View File

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

View File

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

View File

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