#ifndef _KOK_HASHTABLE_H_
#define _KOK_HASHTABLE_H_
#pragma once
#include "Alloc.h"
#include "Assert.h"
#include "MemoryPool.h"
namespace KOK
{
namespace
{
static const int PRIMECOUNT = 28;
static const unsigned int c_nPrimeList[PRIMECOUNT] =
{
53ul, 97ul, 193ul, 389ul, 769ul,
1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
1610612741ul, 3221225473ul, 4294967291ul
};
}
template <class Key, class Value, class KeyOfValue, class EqualFn>
class CHashTable
{
template <class NodeValue>
struct CEntryNode
{
typedef CEntryNode<NodeValue>* LinkType;
LinkType pNext;
NodeValue value;
inline CEntryNode() { pNext = NULL; }
};
template <class NodeValue>
struct CBucketNode
{
typedef CBucketNode<NodeValue>* BucketLinkType;
typedef CEntryNode<NodeValue>* EntryLinkType;
BucketLinkType pNextBucket;
EntryLinkType pFirstEntry;
inline CBucketNode() { pNextBucket = NULL; pFirstEntry = NULL; }
};
public:
typedef Value ValueType;
typedef Value* Pointer;
typedef Value& Reference;
typedef const Value* ConstPointer;
typedef const Value& ConstReference;
typedef size_t SizeType;
typedef ptrdiff_t DiffType;
protected:
typedef CBucketNode<Value> BucketNode;
typedef CBucketNode<Value>* BucketLinkType;
typedef CEntryNode<Value> EntryNode;
typedef CEntryNode<Value>* EntryLinkType;
protected:
SizeType m_nEntryCount_;
LinkType* m_ppbuckets_;
KeyOfValue m_keyOfValue_;
EqualFn m_equalFn_;
MemoryPool* m_pMemoryPool_;
SizeType m_nBucketCount_;
protected:
void Init();
void Clear();
static const unsigned int GetNextPrime(const unsigned int c_nCount)
{
const unsigned int* pFirst = c_nPrimeList;
const unsigned int* pLast = c_nPrimeList + PRIMECOUNT;
const unsigned int* pPos = pFirst;
while(pPos != pLast)
{
if(*pPos < c_nCount)
pPos++;
}
return pPos==pLast ? *(pLast-1) : *pPos;
}
inline bool NeedToResize()
{
if(m_nEntryCount_ >= 0.75 * m_nBucketCount_)
return true;
return false;
}
inline SizeType GetHashIndex(ConstReference c_value)
{
return m_keyOfValue_(c_value)
}
public:
CHashTable();
~CHashTable();
void InsertUnique(ConstReference c_value);
inline KeyOfValue GetKeyOfValue() const { return m_keyOfValue_; }
inline EqualFn GetEqualKey() const { return m_equalFn_; }
inline SizeType GetSize() const { return m_nCount_; }
};
template <class Key, class Value, class KeyOfValue, class EqualFn, class Alloc>
void CHashTable<Key, Value, KeyOfValue, EqualFn, Alloc>::Init()
{
m_nEntryCount_ = 0;
m_nBucketCount_ = GetNextPrime(0);
m_pMemoryPool_ = new MemoryPool();
m_ppbuckets_ = NEWARRAY(m_pMemoryPool_, CBucketNode, m_nBucketCount_);
}
template <class Key, class Value, class KeyOfValue, class EqualFn, class Alloc>
void CHashTable<Key, Value, KeyOfValue, EqualFn, Alloc>::Clear()
{
delete m_pMemoryPool_;
}
template <class Key, class Value, class KeyOfValue, class EqualFn, class Alloc>
void CHashTable<Key, Value, KeyOfValue, EqualFn, Alloc>::InsertUnique(ConstReference c_value)
{
}
}
#endif