* 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:
Ingo Weinhold
2010-01-25 12:18:20 +00:00
parent dc6a27e9b5
commit b20de45ebd
+57 -16
View File
@@ -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;