Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}