void* TRI_InsertKeyAssociativeSynced (TRI_associative_synced_t* array, void const* key, void* element) { uint64_t hash; uint64_t i; void* old; // check for out-of-memory if (array->_nrAlloc == array->_nrUsed) { TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return NULL; } // compute the hash hash = array->hashKey(array, key); i = hash % array->_nrAlloc; #ifdef TRI_INTERNAL_STATS // update statistics array->_nrAdds++; #endif // search the table TRI_WriteLockReadWriteLock(&array->_lock); while (array->_table[i] != NULL && ! array->isEqualKeyElement(array, key, array->_table[i])) { i = (i + 1) % array->_nrAlloc; #ifdef TRI_INTERNAL_STATS array->_nrProbesA++; #endif } old = array->_table[i]; // if we found an element, return if (old != NULL) { TRI_WriteUnlockReadWriteLock(&array->_lock); return old; } // add a new element to the associative array array->_table[i] = element; array->_nrUsed++; // if we were adding and the table is more than half full, extend it if (array->_nrAlloc < 2 * array->_nrUsed) { ResizeAssociativeSynced(array); } TRI_WriteUnlockReadWriteLock(&array->_lock); return NULL; }
void* TRI_InsertKeyAssociativeSynced (TRI_associative_synced_t* array, void const* key, void* element, bool overwrite) { uint64_t hash; uint64_t i; void* old; // compute the hash hash = array->hashKey(array, key); // search the table TRI_WriteLockReadWriteLock(&array->_lock); // check for out-of-memory if (array->_nrAlloc == array->_nrUsed && ! overwrite) { TRI_WriteUnlockReadWriteLock(&array->_lock); TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return NULL; } i = hash % array->_nrAlloc; while (array->_table[i] != NULL && ! array->isEqualKeyElement(array, key, array->_table[i])) { i = TRI_IncModU64(i, array->_nrAlloc); } old = array->_table[i]; // if we found an element, return if (old != NULL) { if (overwrite) { array->_table[i] = element; } TRI_WriteUnlockReadWriteLock(&array->_lock); return old; } // add a new element to the associative array array->_table[i] = element; array->_nrUsed++; // if we were adding and the table is more than half full, extend it if (array->_nrAlloc < 2 * array->_nrUsed) { ResizeAssociativeSynced(array, (uint32_t) (2 * array->_nrAlloc + 1)); } TRI_WriteUnlockReadWriteLock(&array->_lock); return NULL; }
void* TRI_InsertKeyAssociativeSynced (TRI_associative_synced_t* array, void const* key, void* element) { uint64_t hash; uint64_t i; union { void const* c; void* v; } old; // compute the hash hash = array->hashKey(array, key); i = hash % array->_nrAlloc; // update statistics array->_nrAdds++; // search the table TRI_WriteLockReadWriteLock(&array->_lock); while (array->_table[i] != NULL && ! array->isEqualKeyElement(array, key, array->_table[i])) { i = (i + 1) % array->_nrAlloc; array->_nrProbesA++; } old.c = array->_table[i]; // if we found an element, return if (old.c != NULL) { TRI_WriteUnlockReadWriteLock(&array->_lock); return old.v; } // add a new element to the associative array array->_table[i] = element; array->_nrUsed++; // if we were adding and the table is more than half full, extend it if (array->_nrAlloc < 2 * array->_nrUsed) { ResizeAssociativeSynced(array); } TRI_WriteUnlockReadWriteLock(&array->_lock); return NULL; }