#ifndef _KERNEL_UTIL_ATOMICS_HASH_TABLE_H
#define _KERNEL_UTIL_ATOMICS_HASH_TABLE_H
#include <util/OpenHashTable.h>
#include <util/atomic.h>
template<typename Definition, bool AutoExpand = true,
bool CheckDuplicates = false>
class AtomicsHashTable : public BOpenHashTable<Definition,
AutoExpand, CheckDuplicates> {
public:
typedef BOpenHashTable<Definition, AutoExpand, CheckDuplicates> HashTable;
typedef typename Definition::KeyType KeyType;
typedef typename Definition::ValueType ValueType;
AtomicsHashTable()
: HashTable() {}
AtomicsHashTable(const Definition& definition)
: HashTable(definition) {}
ValueType* InsertAtomic(ValueType* value)
{
KeyType key = HashTable::fDefinition.Key(value);
size_t index = HashTable::fDefinition.Hash(value) & (HashTable::fTableSize - 1);
HashTable::_Link(value) = NULL;
ValueType** link = &HashTable::fTable[index];
while (true) {
ValueType* existing = atomic_pointer_get(link);
if (existing == NULL) {
existing = atomic_pointer_test_and_set(link, value, existing);
if (existing == NULL) {
size_t& count = HashTable::fItemCount;
sizeof(size_t) == 4 ?
atomic_add((int32*)&count, 1) :
atomic_add64((int64*)&count, 1);
return NULL;
}
}
if (HashTable::fDefinition.Compare(key, existing))
return existing;
link = &HashTable::_Link(existing);
}
}
bool ResizeIfNeeded()
{
size_t resizeNeeded = HashTable::ResizeNeeded();
if (resizeNeeded == 0)
return true;
return HashTable::_Resize(resizeNeeded);
}
};
#endif