Files
mir_server/Gateway/srvlib/include/container/bz_hash_table.h
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

184 lines
3.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef _BZ_HASH_TABLE_H_
#define _BZ_HASH_TABLE_H_
/************************
* һ<><D2BB><EFBFBD><EFBFBD>װ<EFBFBD>˱<EFBFBD>ѩhash<73><EFBFBD><E3B7A8>hashtable
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǹ̶<C7B9><CCB6>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>ܶ<EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬʱ<CDAC><CAB1><EFBFBD>ṩɾ<E1B9A9><C9BE><EFBFBD>Ľӿ<C4BD>
* Ϊ<><EFBFBD><E1B9A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*************************/
#include "memory/base_allocator.hpp"
#include "bzhash.h"
template <typename T>
class BZHashTable
{
public:
BZHashTable(size_t len)
{
assert(len > 0);
max_size_ = len;
data_ = NULL;
size_ = 0;
}
virtual ~BZHashTable()
{
clear();
}
// <20><>չ<EFBFBD>ϣ<EFBFBD><CFA3>
void clear()
{
if (size_ > 0)
{
for (int i = (int)(max_size_ - 1); i > -1; --i)
{
if (data_[i].exists)
{
data_[i].value.~T();
}
}
}
if (data_) realloc(data_, 0);
data_ = NULL;
size_ = 0;
}
inline size_t count() const { return size_; }
protected:
template <typename TA>
class HashNode
{
public:
bool exists; // <20>Ƿ񱣴<C7B7><F1B1A3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
unsigned int hash1; //<2F><>ϣֵ1
unsigned int hash2; //<2F><>ϣֵ2
unsigned int hash3; //<2F><>ϣֵ3
TA value; //<2F><><EFBFBD><EFBFBD>ֵ
};
typedef HashNode<T> NodeType;
public:
//ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
inline T* get(const char* key)
{
int idx = getIndex(key);
return (idx >= 0) ? &data_[idx].value : NULL;
}
//ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
inline const T* get(const char* key) const
{
int idx = getIndex(key);
return (idx >= 0) ? &data_[idx].value : NULL;
}
inline T* put(const char* key)
{
if (size_ >= max_size_)
{
#ifdef _DEBUG
DbgAssert(false);
#endif
return NULL; // no free
}
if (!data_)
{
data_ = (HashNode<T> *)realloc(NULL, sizeof(HashNode<T>) * max_size_);
for (size_t i = 0; i < max_size_; ++i)
{
data_[i].exists = false;
}
}
unsigned int hash1, hash2, hash3, idx, start;
hash1 = ::bzhashstr(key, 0);
hash2 = ::bzhashstr(key, 1);
hash3 = ::bzhashstr(key, 2);
start = idx = hash1 % (unsigned int)max_size_;
do
{
NodeType *node = data_ + idx;
//<2F><><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>û<EFBFBD><C3BB>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><C3B5><EFBFBD>λ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
if (!node->exists)
{
node->exists = true;
node->hash1 = hash1;
node->hash2 = hash2;
node->hash3 = hash3;
size_++;
new (&node->value)T();
return &node->value;
}
#ifdef _DEBUG
else if (node->hash1 == hash1 && node->hash2 == hash2 && node->hash3 == hash3)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD><EFBFBD><EFBFBD>ȷʵ<C8B7><CAB5><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD>
//DebugBreak();
}
#endif
idx = (idx + 1) % (unsigned int)max_size_;
}
while (start != idx);
return NULL;
}
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD>ڱ<EFBFBD><DAB1>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>
int getIndex(const char* sKey) const
{
if (!data_) return -1;
unsigned int hash1, hash2, hash3;
hash1 = ::bzhashstr(sKey, 0);
hash2 = ::bzhashstr(sKey, 1);
hash3 = ::bzhashstr(sKey, 2);
size_t start = hash1 % max_size_, idx = start;
while (data_[idx].exists)
{
if (data_[idx].hash2 == hash2 && data_[idx].hash3 == hash3)
return (int)idx;
else
idx = (idx + 1) % max_size_;
if (idx == start)
break;
}
return -1;
}
protected:
//<2F>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EBBAAF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>c<EFBFBD><63><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>reallocʵ<63><CAB5><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBA1A2>չ<EFBFBD>Լ<EFBFBD><D4BC>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
virtual void* realloc(void* p, size_t s)
{
#ifdef _MSC_VER
static BaseAllocator alloc("bzhashtable");
if (s > 0)
{
return alloc.ReAllocBuffer(p, s);
}
else
{
if (p)
{
alloc.FreeBuffer(p);
}
return NULL;
}
return alloc.ReAllocBuffer(p, s);
#else
return ::realloc(p, s);
#endif
}
protected:
size_t max_size_;
size_t size_;
HashNode<T> *data_; //<2F><>ϣ<EFBFBD><CFA3>
};
#endif