* Added optional allocator template parameter.
* Added optional parameter "void** oldTable" to Resize(). If given the old allocation for the table is returned instead of freeing it. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35278 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -31,18 +31,44 @@
|
|||||||
typedef int KeyType;
|
typedef int KeyType;
|
||||||
typedef Foo ValueType;
|
typedef Foo ValueType;
|
||||||
|
|
||||||
HashTableDefinition(const HashTableDefinition&) {}
|
size_t HashKey(int key) const
|
||||||
|
{
|
||||||
|
return key >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
size_t HashKey(int key) const { return key >> 1; }
|
size_t Hash(Foo* value) const
|
||||||
size_t Hash(Foo* value) const { return HashKey(value->bar); }
|
{
|
||||||
bool Compare(int key, Foo* value) const { return value->bar == key; }
|
return HashKey(value->bar);
|
||||||
Foo*& GetLink(Foo* value) const { return value->fNext; }
|
}
|
||||||
|
|
||||||
|
bool Compare(int key, Foo* value) const
|
||||||
|
{
|
||||||
|
return value->bar == key;
|
||||||
|
}
|
||||||
|
|
||||||
|
Foo*& GetLink(Foo* value) const
|
||||||
|
{
|
||||||
|
return value->fNext;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
struct MallocAllocator {
|
||||||
|
void* Allocate(size_t size) const
|
||||||
|
{
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Free(void* memory) const
|
||||||
|
{
|
||||||
|
free(memory);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename Definition, bool AutoExpand = true,
|
template<typename Definition, bool AutoExpand = true,
|
||||||
bool CheckDuplicates = false>
|
bool CheckDuplicates = false, typename Allocator = MallocAllocator>
|
||||||
class BOpenHashTable {
|
class BOpenHashTable {
|
||||||
public:
|
public:
|
||||||
typedef BOpenHashTable<Definition, AutoExpand, CheckDuplicates> HashTable;
|
typedef BOpenHashTable<Definition, AutoExpand, CheckDuplicates> HashTable;
|
||||||
@@ -51,9 +77,7 @@ public:
|
|||||||
|
|
||||||
static const size_t kMinimumSize = 8;
|
static const size_t kMinimumSize = 8;
|
||||||
|
|
||||||
// we use malloc() / free() for allocation. If in the future this
|
// All allocations are of power of 2 lengths.
|
||||||
// is revealed to be insufficient we can switch to a template based
|
|
||||||
// allocator. All allocations are of power of 2 lengths.
|
|
||||||
|
|
||||||
// regrowth factor: 200 / 256 = 78.125%
|
// regrowth factor: 200 / 256 = 78.125%
|
||||||
// 50 / 256 = 19.53125%
|
// 50 / 256 = 19.53125%
|
||||||
@@ -75,9 +99,19 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOpenHashTable(const Definition& definition, const Allocator& allocator)
|
||||||
|
:
|
||||||
|
fDefinition(definition),
|
||||||
|
fAllocator(allocator),
|
||||||
|
fTableSize(0),
|
||||||
|
fItemCount(0),
|
||||||
|
fTable(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
~BOpenHashTable()
|
~BOpenHashTable()
|
||||||
{
|
{
|
||||||
free(fTable);
|
fAllocator.Free(fTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t Init(size_t initialSize = kMinimumSize)
|
status_t Init(size_t initialSize = kMinimumSize)
|
||||||
@@ -259,15 +293,18 @@ public:
|
|||||||
unless \a force is \c true, in which case the supplied allocation is
|
unless \a force is \c true, in which case the supplied allocation is
|
||||||
used in any event.
|
used in any event.
|
||||||
Otherwise \c true is returned.
|
Otherwise \c true is returned.
|
||||||
|
If \a oldTable is non-null and resizing is successful, the old table
|
||||||
|
will not be freed, but will be returned via this parameter instead.
|
||||||
*/
|
*/
|
||||||
bool Resize(void* allocation, size_t size, bool force = false)
|
bool Resize(void* allocation, size_t size, bool force = false,
|
||||||
|
void** oldTable = NULL)
|
||||||
{
|
{
|
||||||
if (!force && size != ResizeNeeded()) {
|
if (!force && size != ResizeNeeded()) {
|
||||||
free(allocation);
|
fAllocator.Free(allocation);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_Resize((ValueType**)allocation, size / sizeof(ValueType*));
|
_Resize((ValueType**)allocation, size / sizeof(ValueType*), oldTable);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,7 +393,7 @@ protected:
|
|||||||
bool _Resize(size_t newSize)
|
bool _Resize(size_t newSize)
|
||||||
{
|
{
|
||||||
ValueType** newTable
|
ValueType** newTable
|
||||||
= (ValueType**)malloc(sizeof(ValueType*) * newSize);
|
= (ValueType**)fAllocator.Allocate(sizeof(ValueType*) * newSize);
|
||||||
if (newTable == NULL)
|
if (newTable == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -364,7 +401,7 @@ protected:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _Resize(ValueType** newTable, size_t newSize)
|
void _Resize(ValueType** newTable, size_t newSize, void** oldTable = NULL)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < newSize; i++)
|
for (size_t i = 0; i < newSize; i++)
|
||||||
newTable[i] = NULL;
|
newTable[i] = NULL;
|
||||||
@@ -379,7 +416,10 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(fTable);
|
if (oldTable != NULL)
|
||||||
|
*oldTable = fTable;
|
||||||
|
else
|
||||||
|
fAllocator.Free(fTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
fTableSize = newSize;
|
fTableSize = newSize;
|
||||||
@@ -406,6 +446,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Definition fDefinition;
|
Definition fDefinition;
|
||||||
|
Allocator fAllocator;
|
||||||
size_t fTableSize;
|
size_t fTableSize;
|
||||||
size_t fItemCount;
|
size_t fItemCount;
|
||||||
ValueType** fTable;
|
ValueType** fTable;
|
||||||
|
|||||||
Reference in New Issue
Block a user