1
0
Fork 0

Added a remove by key function to AssocUnique

This commit is contained in:
Michael Hackstein 2015-08-24 17:06:21 +02:00
parent ba8264eada
commit 5b6f8b7b8e
1 changed files with 105 additions and 35 deletions

View File

@ -298,6 +298,33 @@ namespace triagens {
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief finds an element equal to the given element.
////////////////////////////////////////////////////////////////////////////////
Element* find (Element* element) const {
uint64_t i = _hashElement(element);
Bucket const& b = _buckets[i & _bucketsMask];
uint64_t const n = b._nrAlloc;
i = i % n;
uint64_t k = i;
for (; i < n && b._table[i] != nullptr &&
! _isEqualElementElement(element, b._table[i]); ++i);
if (i == n) {
for (i = 0; i < k && b._table[i] != nullptr &&
! _isEqualElementElement(element, b._table[i]); ++i);
}
// ...........................................................................
// return whatever we found, this is nullptr if the thing was not found
// and otherwise a valid pointer
// ...........................................................................
return b._table[i];
}
////////////////////////////////////////////////////////////////////////////////
/// @brief finds an element given a key, returns NULL if not found
////////////////////////////////////////////////////////////////////////////////
@ -371,12 +398,86 @@ namespace triagens {
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief helper to heal a hole where we deleted something
////////////////////////////////////////////////////////////////////////////////
void healHole (Bucket& b, uint64_t i) {
// ...........................................................................
// remove item - destroy any internal memory associated with the
// element structure
// ...........................................................................
b._table[i] = nullptr;
b._nrUsed--;
uint64_t const n = b._nrAlloc;
// ...........................................................................
// and now check the following places for items to move closer together
// so that there are no gaps in the array
// ...........................................................................
uint64_t k = TRI_IncModU64(i, n);
while (b._table[k] != nullptr) {
uint64_t j = _hashElement(b._table[k]) % n;
if ((i < k && ! (i < j && j <= k)) || (k < i && ! (i < j || j <= k))) {
b._table[i] = b._table[k];
b._table[k] = nullptr;
i = k;
}
k = TRI_IncModU64(k, n);
}
if (b._nrUsed == 0) {
resizeInternal(b, initialSize(), true);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief removes an element from the array based on its key,
/// returns nullptr if the element
/// was not found and the old value, if it was successfully removed
////////////////////////////////////////////////////////////////////////////////
Element* removeByKey (Key const* key) {
uint64_t i = _hashKey(key);
Bucket& b = _buckets[i & _bucketsMask];
uint64_t const n = b._nrAlloc;
i = i % n;
uint64_t k = i;
for (; i < n && b._table[i] != nullptr &&
! _isEqualKeyElement(key, b._table[i]); ++i);
if (i == n) {
for (i = 0; i < k && b._table[i] != nullptr &&
! _isEqualKeyElement(key, b._table[i]); ++i);
}
Element* old = b._table[i];
// ...........................................................................
// if we did not find such an item return nullptr
// ...........................................................................
if (old == nullptr) {
healHole(b, i);
}
return old;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief removes an element from the array, returns nullptr if the element
/// was not found and the old value, if it was successfully removed
////////////////////////////////////////////////////////////////////////////////
Element* remove (Element* element) {
Element* remove (Element const* element) {
uint64_t i = _hashElement(element);
Bucket& b = _buckets[i & _bucketsMask];
@ -394,42 +495,11 @@ namespace triagens {
Element* old = b._table[i];
// ...........................................................................
// if we did not find such an item return error code
// if we did not find such an item return nullptr
// ...........................................................................
if (old == nullptr) {
return old;
}
// ...........................................................................
// remove item - destroy any internal memory associated with the
// element structure
// ...........................................................................
b._table[i] = nullptr;
b._nrUsed--;
// ...........................................................................
// and now check the following places for items to move closer together
// so that there are no gaps in the array
// ...........................................................................
k = TRI_IncModU64(i, n);
while (b._table[k] != nullptr) {
uint64_t j = _hashElement(b._table[k]) % n;
if ((i < k && ! (i < j && j <= k)) || (k < i && ! (i < j || j <= k))) {
b._table[i] = b._table[k];
b._table[k] = nullptr;
i = k;
}
k = TRI_IncModU64(k, n);
}
if (b._nrUsed == 0) {
resizeInternal(b, initialSize(), true);
if (old != nullptr) {
healHole(b, i);
}
return old;