34 #define Bit2Size(bits) ( (int)(1<<(bits)) ) 41 template <
class KeyT,
class DataT>
class LHash;
50 inline const char *
Map_copyKey(
const char *key) {
return strdup(key); }
57 inline void Map_freeKey(
const char *key) { free((
void*)key); }
113 template <
class KeyT>
115 inline bool Map_equalKey(KeyT key1, KeyT key2) {
return (key1 == key2); }
116 inline bool Map_equalKey(
float key1,
float key2) {
return fabs(key1 - key2) < 1e-2; }
117 inline bool Map_equalKey(
double key1,
double key2) {
return fabs(key1 - key2) < 1e-15; }
118 inline bool Map_equalKey(
const char *pStr1,
const char *pStr2) {
return strcmp(pStr1, pStr2) == 0; }
121 #define HashMask(nbits) (~((~0L)<<(nbits))) 128 inline unsigned long LHash_hashKey(
unsigned long key,
unsigned maxBits)
132 return (((key * 1103515245 + 12345) >> (30 - maxBits)) &
HashMask(maxBits));
136 template <
class KeyT>
181 for (; *key; key++) {
182 i += (i << 3) + *key;
191 template <
class KeyT>
194 inline bool LHash_IncSort(
const char *p1,
const char *p2) {
return strcmp(p2, p1) <= 0; }
208 template <
class KeyT,
class DataT>
225 static int nLocateNum;
226 static double fLocateStep;
231 LHash(
int nSize = 0) :m_nMaxBits(0), m_pUnit(NULL), m_nUnitNum(0) { Reset(nSize); }
235 int GetNum()
const {
return m_nUnitNum; }
245 return sizeof(*this) + GetSize() *
sizeof(Unit);
250 if (nSize <
Bit2Size(cn_MinLHashBits))
252 return (
int)((nSize + 1) / cf_HashRatio);
257 int maxBits, maxUnits;
262 if (maxBits > cn_MaxLHashBits) {
263 cout <<
"[LHash] Alloc: needed bits over cn_MaxLashBits" << endl;
274 m_pUnit =
new Unit[maxUnits];
276 m_nMaxBits = maxBits;
280 for (
int i = 0; i<maxUnits; i++)
288 int maxUnits =
Bit2Size(m_nMaxBits);
289 for (
int i = 0; i<maxUnits; i++){
306 Alloc(RoundSize(nSize));
312 int nMaxUnit =
Bit2Size(m_nMaxBits);
313 for (
int i = 0; i<nMaxUnit; i++) {
325 int nMaxUnit =
Bit2Size(m_nMaxBits);
326 for (
int i = 0; i<nMaxUnit; i++) {
328 m_pUnit[i].value = d;
333 inline bool Locate(KeyT key,
int &index)
const 341 if (m_nMaxBits < cn_MinLHashBits)
344 for (
int i = 0; i<m_nUnitNum; i++) {
362 for (
int i = nHash;; i = (i + 1) %
Bit2Size(m_nMaxBits)) {
392 DataT *
Find(KeyT key,
bool &bFound)
395 if ((bFound = Locate(key, index))) {
396 return &(m_pUnit[index].value);
405 return Find(key, bFound);
415 if ((bFound = Locate(key, index))) {
416 return &(m_pUnit[index].value);
419 int nNewSize = RoundSize(m_nUnitNum + 1);
421 if (nNewSize >
Bit2Size(m_nMaxBits)) {
422 Unit *pOldUnit = m_pUnit;
423 int nOldUnitNum = m_nUnitNum;
424 int nOldMaxUnit =
Bit2Size(m_nMaxBits);
428 m_nUnitNum = nOldUnitNum;
430 if (m_nMaxBits < cn_MinLHashBits) {
432 memcpy(m_pUnit, pOldUnit,
sizeof(pOldUnit[0])*nOldUnitNum);
436 for (
int i = 0; i<nOldMaxUnit; i++) {
437 KeyT curKey = pOldUnit[i].key;
439 Locate(curKey, index);
440 memcpy(&(m_pUnit[index]), &(pOldUnit[i]),
sizeof(pOldUnit[i]));
453 memset(&(m_pUnit[index].value), 0,
sizeof(m_pUnit[index].value));
454 new (&(m_pUnit[index].value)) DataT;
457 return &(m_pUnit[index].value);
464 return Insert(key, bFound);
475 for (
int i = 0; i<maxSize; i++) {
476 KeyT thisKey = other.
m_pUnit[i].key;
481 new (&(m_pUnit[i].value)) DataT;
483 m_pUnit[i].value = other.
m_pUnit[i].value;
498 template <
class KeyT,
class DataT>
500 template <
class KeyT,
class DataT>
508 template <
class KeyT,
class DataT>
515 bool(*m_sortFun)(KeyT, KeyT);
529 delete[] m_pSortedKey;
542 delete[] m_pSortedKey;
545 if (m_phash->
GetNum() > 0) {
546 m_pSortedKey =
new KeyT[m_phash->
GetNum()];
550 for (
int i = 0; i<maxSize; i++) {
552 m_pSortedKey[curKey] = m_phash->
m_pUnit[i].key;
558 for (
int i = 0; i<curKey - 1; i++) {
559 for (
int j = i + 1; j<curKey; j++) {
560 if (!m_sortFun(m_pSortedKey[i], m_pSortedKey[j])) {
561 KeyT t = m_pSortedKey[i];
562 m_pSortedKey[i] = m_pSortedKey[j];
584 if (m_nCurIndex == m_phash->
GetNum())
587 key = m_pSortedKey[m_nCurIndex++];
588 return m_phash->
Find(key);
592 for (; m_nCurIndex < m_phash->
GetSize(); m_nCurIndex++) {
593 key = m_phash->
m_pUnit[m_nCurIndex].key;
595 return &(m_phash->
m_pUnit[m_nCurIndex++].value);
bool Locate(KeyT key, int &index) const
Find the key.
const int c_IntNokeyValue
nokey value for int
bool Map_equalKey(const char *pStr1, const char *pStr2)
DataT * Next(KeyT &key)
get next value
void Alloc(int nSize)
Allocate the buffer.
LHashIter(LHash< KeyT, DataT > *phash, bool(*sort)(KeyT, KeyT)=0)
constructor
const short c_ShortNokeyValue
nokey value for short
int m_nUnitNum
The unit number add to the hash.
int m_nMaxBits
The bit number of the memory buffer. (2^m_nMaxBits is the memory size)
const int cn_MinLHashBits
if the bits of hash less than this value, using linear table
void Clean()
Clean the hash, but don't release the buffer.
size_t TotalMemCost()
Compute the whole memory cost of hash structure.
bool LHash_IncSort(const char *p1, const char *p2)
const double c_doubleNokeyValue
nokey value for double
int GetSize() const
Get the buffer size of hash.
int RoundSize(int nSize)
calculate the buffer size need to be allocated
Unit * m_pUnit
pointer to the buffer.
const float cf_HashRatio
fill-rate of the hash.
void Init()
initialize the iter
LHash(int nSize=0)
constructor
const long c_LongNokeyValue
nokey value for long
unsigned long LHash_hashKey(const char *key, unsigned maxBits)
hash for string
void Map_freeKey(const char *key)
Free a key, if the key is string.
void Release()
Release the buffer.
int GetNum() const
Get the unit number.
void Map_noKey(double &key)
DataT * Insert(KeyT key)
Insert a value.
const unsigned c_UIntNokeyValue
nokey value for unsigned int
const long unsigned c_ULongNokeyValue
nokey value for unsigned long
bool Map_noKeyP(double &key)
DataT * Insert(KeyT key, bool &bFound)
Insert a value.
int GetMaxBits() const
Get the buffer size bits.
void Reset(int nSize)
Reset the hash buffer.
DataT * Find(KeyT key)
Find a value.
const float c_floatNokeyValue
nokey value for float
const char * Map_copyKey(const char *key)
Copy a string key.
const long long c_LLongNokeyValue
nokey value for longlong
const int cn_MaxLHashBits
the maximum bits number support by hast
void Copy(LHash< KeyT, DataT > &other)
Copy hash.
void Fill(DataT d)
Set all the values to d.
define all the code written by Bin Wang.
const short unsigned c_UShortNokeyValue
nokey value for unsigned short
DataT * Find(KeyT key, bool &bFound)
Find a value.
const Unit * GetBuffer() const
Get the buffer.