This commit is contained in:
aixianling
2025-01-09 17:45:40 +08:00
commit 5c9f1dae4a
3482 changed files with 1146531 additions and 0 deletions

View File

@@ -0,0 +1,184 @@
#ifndef _BINARY_LIST_H_
#define _BINARY_LIST_H_
/******************************************************************
*
* 封装二分法,实现查找,插入,删除等操作
*
*****************************************************************/
#include <assert.h>
#include "container/vector.h"
#include "container/static_array_list.h"
namespace container
{
template <typename T, int ONE_TIME_NUM = 16>
class BinaryList: public Vector<T, ONE_TIME_NUM>
{
public:
BinaryList(BaseAllocator* alloc = NULL): Vector<T, ONE_TIME_NUM>(alloc)
{
}
virtual ~BinaryList()
{
}
int add_item(const T& item)
{
//id加到列表中
int low = 0;
int high = this->count_ - 1;
while (low <= high)
{
int mid = ((unsigned)(low + high)) >> 1;
const T& mid_item = this->data_ptr_[mid];
if (mid_item < item)
low = mid + 1;
else
high = mid - 1;
}
this->insert(low, item);
return low;
}
void remove_item(const T& item, bool del_repeat = false)
{
int idx = find(item);
if (idx < 0) return;
if (del_repeat)
{
this->remove(idx);
return;
}
int endidx = idx;
for (--idx; idx >= 0; idx--)
{
if (this->data_ptr_[idx] != item) break;
}
for (++endidx; endidx < this->count_; endidx++)
{
if (this->data_ptr_[endidx] != item) break;
}
this->remove(idx + 1, endidx - 1 - idx);
}
int find(const T& item)
{
int low = 0;
int high = this->count_ - 1;
while (low <= high)
{
int mid = ((unsigned int)(low + high)) >> 1;
const T& mid_item = this->data_ptr_[mid];
if (mid_item < item)
low = mid + 1;
else if (mid_item > item)
high = mid - 1;
else
return mid; // key found
}
return -1; // key not found.
}
};
};
namespace container
{
template <typename T, int ONE_TIME_NUM = 16>
class StaticBinaryList : public StaticArrayList<T, ONE_TIME_NUM>
{
public:
StaticBinaryList()
{
}
virtual ~StaticBinaryList()
{
}
int add_item(const T& item)
{
//id加到列表中
int low = 0;
int high = this->count_ - 1;
while (low <= high)
{
int mid = ((unsigned)(low + high)) >> 1;
const T& mid_item = this->data_ptr_[mid];
if (mid_item < item)
low = mid + 1;
else
high = mid - 1;
}
this->insert(low, item);
return low;
}
void remove_item(const T& item, bool del_repeat = false)
{
int idx = find(item);
if (idx < 0) return;
if (del_repeat)
{
this->remove(idx);
return;
}
int endidx = idx;
for (--idx; idx >= 0; idx--)
{
if (this->data_ptr_[idx] != item) break;
}
for (++endidx; endidx < this->count_; endidx++)
{
if (this->data_ptr_[endidx] != item) break;
}
this->remove(idx + 1, endidx - 1 - idx);
}
int find(const T& item)
{
int low = 0;
int high = this->count_ - 1;
while (low <= high)
{
int mid = ((unsigned int)(low + high)) >> 1;
const T& mid_item = this->data_ptr_[mid];
if (mid_item < item)
low = mid + 1;
else if (mid_item > item)
high = mid - 1;
else
return mid; // key found
}
return -1; // key not found.
}
};
};
#endif

View File

@@ -0,0 +1,183 @@
#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

View File

@@ -0,0 +1,403 @@
#ifndef _LINKED_LIST_H_
#define _LINKED_LIST_H_
/******************************************************************
*
* $ 链表类 $
*
* 实现动态添加、插入节点。与Vector一样链表类也是一个容器类但与
* Vector比较链表在进行删除节点的时候能够更大的发挥效率缺点则是比列表
* 更加浪费内存内存开销为3~4倍且在随机访问的时候效率极低。
*
*****************************************************************/
#include <assert.h>
#include "memory/objpool.hpp"
namespace container
{
template <typename T>
class BaseLinkedList;
template <typename T>
class ListIterator;
/*************************
* 链表节点类
**************************/
template <typename T>
class LinkedNode
{
public:
LinkedNode() {}
inline operator T& ()
{
return data_;
}
T data_;
public:
LinkedNode<T>* prev_;
LinkedNode<T>* next_;
BaseLinkedList<T>* self_;
};
/*************************
* 链表迭代器类
**************************/
template <typename T>
class ListIterator
{
friend class BaseLinkedList<T>;
public:
ListIterator()
{
list_ = NULL;
enuming_ = NULL;
prev_ = next_ = NULL;
}
ListIterator(BaseLinkedList<T>& list)
{
//list_ = NULL;
//enuming_ = NULL;
//prev_ = next_ = NULL;
//setList(list);
//wuzhihong edit
list_ = &list;
enuming_ = NULL;
next_ = NULL;
prev_ = list.iterator_;
if (prev_) prev_->next_ = this;
list.iterator_ = this;
}
~ListIterator()
{
if (list_)
{
if (prev_) prev_->next_ = next_;
if (next_) next_->prev_ = prev_;
if (this == list_->iterator_)
list_->iterator_ = prev_;
list_ = NULL;
enuming_ = NULL;
prev_ = next_ = NULL;
}
}
//重新设置遍历对象
inline void setList(BaseLinkedList<T>& list)
{
this->~ListIterator();
list_ = &list;
enuming_ = NULL;
next_ = NULL;
prev_ = list.iterator_;
if (prev_) prev_->next_ = this;
list.iterator_ = this;
}
//移除一个节点,方便在迭代的过程中移除节点从而破坏迭代过程
inline void remove(LinkedNode<T>* pNode, bool boFree = true)
{
if (pNode == enuming_)
enuming_ = pNode->prev_;
list_->remove(pNode, boFree);
}
//从头开始遍历节点
inline LinkedNode<T>* first()
{
return enuming_ = list_->first();
}
//遍历下一个节点
inline LinkedNode<T>* next()
{
return enuming_ = (enuming_ ? enuming_->next_ : list_->first());
}
//当前遍历到的节点
inline LinkedNode<T>* current()
{
return enuming_;
}
private:
LinkedNode<T>* enuming_;
BaseLinkedList<T>* list_;
ListIterator<T>* prev_;
ListIterator<T>* next_;
};
/*************************
* 链表类
**************************/
template <typename T>
class BaseLinkedList
{
friend class ListIterator<T>;
public:
typedef T InstancesType;
typedef LinkedNode<T> NodeType;
typedef ListIterator<T> Iterator;
public:
BaseLinkedList(ObjPool< LinkedNode<T> >* alloc = NULL)
{
first_node_ = last_node_ = NULL;
iterator_ = NULL;
count_ = 0;
allocator_ = alloc;
}
virtual ~BaseLinkedList()
{
clear();
}
//获取第一个节点
inline LinkedNode<T>* first()
{
return first_node_;
}
//获取最后一个节点
inline LinkedNode<T>* last()
{
return last_node_;
}
//获取节点数量
inline int count() const
{
return count_;
}
/* 在pNode节点的前面插入新节点
* 如果pNode为空则表示插入到链表的起始位置
*/
LinkedNode<T>* linkBefore(const T& data, LinkedNode<T>* node = NULL)
{
assert(!node || node->self_ == this);
if (!node) node = first_node_;
LinkedNode<T>* pPrev = node ? node->prev_ : NULL;
LinkedNode<T>* new_node = allocNode();
new_node->data_ = data;
new_node->prev_ = pPrev;
new_node->next_ = node;
if (pPrev)
pPrev->next_ = new_node;
else first_node_ = new_node;
if (node)
node->prev_ = new_node;
else last_node_ = new_node;
new_node->self_ = this;
count_++;
return new_node;
}
/* 在pNode节点的后面插入新节点
* 如果pNode为空则表示插入到链表的末尾
*/
LinkedNode<T>* linkAfter(const T& data, LinkedNode<T>* pNode = NULL)
{
assert(!pNode || pNode->self_ == this);
if (!pNode) pNode = last_node_;
LinkedNode<T>* pNext = pNode ? pNode->next_ : NULL;
LinkedNode<T>* pNewNode = allocNode();
pNewNode->data_ = data;
pNewNode->prev_ = pNode;
pNewNode->next_ = pNext;
if (pNext)
pNext->prev_ = pNewNode;
else last_node_ = pNewNode;
if (pNode)
pNode->next_ = pNewNode;
else first_node_ = pNewNode;
pNewNode->self_ = this;
count_++;
return pNewNode;
}
/* 在pNode节点的前面插入新节点
* 如果pNode为空则表示插入到链表的起始位置
*/
LinkedNode<T>* linkBefore(LinkedNode<T>* new_node, LinkedNode<T>* node = NULL)
{
assert(!node || node->self_ == this);
if (!node) node = first_node_;
LinkedNode<T>* pPrev = node ? node->prev_ : NULL;
new_node->prev_ = pPrev;
new_node->next_ = node;
if (pPrev)
pPrev->next_ = new_node;
else first_node_ = new_node;
if (node)
node->prev_ = new_node;
else last_node_ = new_node;
new_node->self_ = this;
count_++;
return new_node;
}
//重载linkAfer插入一个已有的node
LinkedNode<T>* Transfer(LinkedNode<T>* pNewNode, LinkedNode<T>* pNode = NULL)
{
assert(!pNode || pNode->self_ == this);
assert(pNewNode->self_ == NULL);
if (!pNode) pNode = last_node_;
LinkedNode<T>* pNext = pNode ? pNode->next_ : NULL;
pNewNode->prev_ = pNode;
pNewNode->next_ = pNext;
if (pNext)
pNext->prev_ = pNewNode;
else last_node_ = pNewNode;
if (pNode)
pNode->next_ = pNewNode;
else first_node_ = pNewNode;
pNewNode->self_ = this;
count_++;
return pNewNode;
}
//将数据插入到链表头部
inline LinkedNode<T>* linkAtFirst(const T& data)
{
return linkBefore(data, first_node_);
}
//将数据添加到链表尾部
inline LinkedNode<T>* linkAtLast(const T& data)
{
return linkAfter(data, last_node_);
}
inline LinkedNode<T>* TransferAtLast(LinkedNode<T>* pNewNode)
{
return Transfer(pNewNode, last_node_);
}
//通过索引获取链表节点
LinkedNode<T>* getNodeAt(int nIndex)
{
for (LinkedNode<T>* pNode = first_node_; pNode; pNode = pNode->next_)
{
if (nIndex <= 0)
return pNode;
nIndex--;
}
return NULL;
}
/* 移除一个链表节点
* ★注意★ 如果正在通过迭代器遍历链表则移除操作必须调用迭代器的CLinkedListIterator::remove函数
*/
inline void remove(LinkedNode<T>* node, bool free_flag = true)
{
if (node && node->self_ == this)
{
//移除节点
if (node->prev_)
node->prev_->next_ = node->next_;
if (node->next_)
node->next_->prev_ = node->prev_;
if (node == first_node_)
first_node_ = node->next_;
if (node == last_node_)
last_node_ = node->prev_;
//从所有迭代器中测试并修正当前遍历节点
if (iterator_)
{
Iterator* it = iterator_;
while (it)
{
if (node == it->enuming_)
it->enuming_ = node->prev_;
it = it->prev_;
}
}
node->self_ = NULL;
//销毁节点
if (free_flag) freeNode(node);
count_--;
assert(count_ >= 0);
}
}
//清空链表
virtual void clear()
{
LinkedNode<T>* pNode = first_node_, *pNextNode;
while (pNode)
{
pNextNode = pNode->next_;
freeNode(pNode);
pNode = pNextNode;
}
first_node_ = last_node_ = NULL;
count_ = 0;
}
protected:
/* 申请一个链表节点对象默认的操作时使用new申请内存并构造
* 子类可通过覆盖此方法实现链表节点的内存管理
*/
virtual LinkedNode<T>* allocNode()
{
if (allocator_)
{
return allocator_->Alloc();
}
else
{
return new LinkedNode<T>;
}
}
/* 销毁一个链表节点对象默认的操作时使用delete析构并释放内存
* 子类可通过覆盖此方法实现链表节点的内存管理
*/
virtual void freeNode(LinkedNode<T>* pNode)
{
if (allocator_)
{
allocator_->Free(pNode);
}
else
{
delete pNode;
}
}
private:
LinkedNode<T>* first_node_;
LinkedNode<T>* last_node_;
Iterator* iterator_;
int count_;
ObjPool< LinkedNode<T> >* allocator_;
};
};
#endif

View File

@@ -0,0 +1,41 @@
#ifndef _LINKED_LIST_EX_H_
#define _LINKED_LIST_EX_H_
#include <set>
/*
使用内存管理器扩展了一下List链表,
*/
namespace container
{
template<typename DATA,int ONE_TIME_COUNT=1024>
class LinkedListEx:
public BaseLinkedList<DATA>
{
public:
typedef ObjPool<LinkedNode<DATA>, ONE_TIME_COUNT> LinkNodeMgr;
virtual ~LinkedListEx()
{
this->clear();
}
protected:
virtual LinkedNode<DATA>* allocNode()
{
LinkedNode<DATA>* result = node_pool_->Alloc();
return result;
}
virtual void freeNode(LinkedNode<DATA> *pNode)
{
node_pool_->Free(pNode);//放回内存池
}
public:
static LinkNodeMgr* node_pool_;
};
}
#endif

View File

@@ -0,0 +1,50 @@
#ifndef _MBASE_LOCKLIST_H_
#define _MBASE_LOCKLIST_H_
#include "container/vector.h"
#include "x_lock.h"
namespace container
{
using namespace lock;
template <typename T>
class LockList :
public Vector<T>
{
public:
typedef Vector<T> Inherited;
typedef LockList<T> ListClass;
private:
Mutex *lock_;//数据锁
public:
LockList(Mutex *lock = NULL):Inherited()
{
lock_ = lock;
}
//获取列表锁对象
inline Mutex* getLock(){ return lock_; }
//设置列表锁对象,函数返回旧的列表锁
Mutex* setLock(Mutex *lock)
{
Mutex *pOldLock = lock_;
lock_ = lock;
return pOldLock;
}
//对列表加锁
inline void lock()
{
assert(lock_);
if ( lock_ ) lock_->Lock();
}
//对列表解锁
inline void unlock()
{
if ( lock_ ) lock_->Unlock();
}
};
};
#endif

View File

@@ -0,0 +1,81 @@
#ifndef _OBJ_LIST_H_
#define _OBJ_LIST_H_
/************************************************************************
* 对象的缓存池,从池中取出的就是一个可用的对象,放到池中的对象不执行析构函数,
* 这样可避免执行构造函数和析构函数的开销,特别是需要分配内存的对象,可避免产生碎片
************************************************************************/
#include <assert.h>
#include "container/vector.h"
#include "memory/buffer_allocator.h"
namespace container
{
template <typename T, int ONE_TIME_COUNT=1024>
class ObjList : public AllocatorCounterItem
{
public:
ObjList(const char* namestr, const char* name2):AllocatorCounterItem(namestr),
all_obj_count_(0), free_obj_count_(0), allocator_(name2)
{
}
~ObjList()
{
assert(all_obj_count_ == free_obj_count_); // 内存泄漏?
// 释放内存
int count = free_.count();
T** list = free_;
for (int i = 0; i < count; ++i)
{
list[i]->~T();
}
count = all_.count();
list = all_;
for (int i = 0; i < count; ++i)
{
allocator_.FreeBuffer(list[i]);
}
allocator_.CheckFreeBuffers();
}
T* get()
{
if (free_.count() <= 0)
{
T* news = (T*)allocator_.AllocBuffer(sizeof(T) * ONE_TIME_COUNT);
all_.add(news);
all_obj_count_ += ONE_TIME_COUNT;
free_.reserve(all_obj_count_);
//循环调用构造函数
for (int i = 0; i < ONE_TIME_COUNT; ++i)
{
new(news)T();
free_[i] = news;
news++;
}
free_obj_count_ = ONE_TIME_COUNT;
free_.trunc(free_obj_count_);
}
assert(free_obj_count_ == free_.count());
--free_obj_count_;
T* result = free_[free_obj_count_];
free_.trunc(free_obj_count_);
return result;
}
void release(T* p)
{
if (!p) return;
free_.add(p);
free_obj_count_++;
}
private:
Vector<T*> all_;
Vector<T*> free_;
int all_obj_count_;
int free_obj_count_;
BufferAllocator allocator_;
};
};
#endif

View File

@@ -0,0 +1,58 @@
#ifndef _MBASE_QUEUELIST_H_
#define _MBASE_QUEUELIST_H_
#include "lock_list.h"
#include "container/vector.h"
namespace container
{
template <typename T>
class QueueList :
public LockList<T>
{
public:
typedef LockList<T> Inherited;
typedef QueueList<T> ListClass;
private:
Vector<T> append_list_; //数据追加列表
public:
//添加数据数据将在调用flush或tryFlush是被提交到自身列表中
inline void append(const T& data)
{
this->lock();
append_list_.add(data);
this->unlock();
}
inline void appendList(Vector<T> &list)
{
this->lock();
append_list_.addArray(list, list.count());
this->unlock();
}
inline void appendArray(T* data, int length)
{
this->lock();
append_list_.addArray(data, length);
this->unlock();
}
//获取追加数据数量
inline int appendCount()
{
return append_list_.count();
}
//提交由append调用添加的数据
inline void flush()
{
this->lock();
if ( append_list_.count() > 0 )
{
this->addList(append_list_);
append_list_.trunc(0);
}
this->unlock();
}
};
};
#endif

View File

@@ -0,0 +1,129 @@
/*
* 一个用来把固定大小的数组封装成类stl::vector的类
* 适用于不想用动态数组自动扩充内存的地方封装了add、insert、remove等方法易于使用仅此目的
* 缺点是数组是固定大小的(当然是在定义模板类的时候指定),不能自动根据需要扩展内存
*/
#ifndef _STATIC_ARRAY_LIST_H_
#define _STATIC_ARRAY_LIST_H_
namespace container
{
template<typename T,int MAX_NUM>
class StaticArrayList
{
protected:
T data_ptr_[MAX_NUM];
int count_;
public:
StaticArrayList(){
count_ = 0;
}
virtual ~StaticArrayList(){
count_ = 0;
}
inline operator T* () { return data_ptr_; }
inline operator T* () const { return const_cast<T*>(data_ptr_); }
int size() const { return count_; }
int count() const { return count_; }
int max_size() const { return MAX_NUM; }
int add(const T& data)
{
assert( count_ + 1 <= MAX_NUM );
memcpy(&data_ptr_[count_], &data, sizeof(data));
count_++;
return count_-1;
}
int push_back(const T& data)
{
return add(data);
}
void insert(const int index, const T& data)
{
assert( index > -1 && index <= count_ );
if ( index < count_ )
{
memmove(data_ptr_ + index + 1, data_ptr_ + index, sizeof(T) * (count_ - index) );
}
data_ptr_[index] = data;
count_++;
}
inline const T& get(const int index) const
{
assert( index > -1 && index < count_ );
return data_ptr_[index];
}
inline void set(const int index, const T &item)
{
assert( index > -1 && index < count_ );
data_ptr_[index] = item;
}
void remove(const int index)
{
assert( index > -1 && index < count_ );
remove( index, 1 );
}
void remove(const int index, const int num)
{
assert( index + num <= count_ );
if ( num > 0 )
{
memmove( data_ptr_ + index, data_ptr_ + index + num, sizeof(data_ptr_[0]) * (count_ - index - num) );
count_ -= num;
}
}
inline void clear()
{
count_ = 0;
}
inline void trunc(const int num)
{
assert( num > -1 && num <= MAX_NUM );
count_ = num;
}
inline void addArray(const T* data, int length)
{
assert ( count_ + length <= MAX_NUM );
memcpy(data_ptr_ + count_, data, length * sizeof(T));
count_ += length;
}
inline void addList(const Vector<T> &list)
{
addArray((T*)list, list.count_);
}
int index(const T& data) const
{
for ( int i = count_ - 1; i > -1; --i )
{
if ( data_ptr_[i] == data )
{
return i;
}
}
return -1;
}
};//end class StaticArrayList
}//end namespace container
#endif

View File

@@ -0,0 +1,165 @@
#ifndef _STATIC_HASH_TABLE_H_
#define _STATIC_HASH_TABLE_H_
/************************
* 一个封装了暴雪hash算法的hashtable
* 表长度是固定的,不能动态增长,同时不提供删除的接口
* 为提供更快的性能
*************************/
namespace container
{
template <typename T, int MAX_NODE_NUM>
class StaticHashTable
{
protected:
class HashNode
{
public:
bool exists_; // 是否保存有数据
uint64_t key_; // key
T value_; // 数据值
};
size_t size_;
size_t out_count_;
static const size_t MAX_SIZE_ = MAX_NODE_NUM * 2;
HashNode ptr_[MAX_SIZE_];
//Vector<HashNode, MAX_NODE_NUM> data_;
public:
StaticHashTable() : size_(0), out_count_(0)
{
//data_.reserve(MAX_SIZE_);
//ptr_ = data_;
clear();
}
virtual ~StaticHashTable()
{
clear();
}
// 清空哈希表
void clear()
{
size_ = 0;
out_count_ = 0;
memset(ptr_, 0, MAX_SIZE_ * sizeof(HashNode));
}
inline size_t count() const { return size_; }
public:
//通过键查找值
inline T* get(uint64_t key)
{
int idx = getIndex(key);
return (idx >= 0) ? &ptr_[idx].value_ : NULL;
}
inline T* put(uint64_t key, T& data)
{
if (size_ >= MAX_NODE_NUM) return NULL;
unsigned int start = key % MAX_NODE_NUM, idx = start;
do
{
HashNode *node = ptr_ + idx;
//如果该位置没有值,则设置到该位置,否则向后找到一个空位置
if (!node->exists_)
{
node->exists_ = true;
node->key_ = key;
size_++;
node->value_ = data;
if (idx >= MAX_NODE_NUM)
++out_count_;
return &(node->value_);
}
#ifdef _DEBUG
else if (node->key_ == key)
{
//调用者重复添加,或者确实出现错误!
DebugBreak();
}
#endif
++idx;
}
while (idx < MAX_SIZE_);
return NULL;
}
inline bool remove(uint64_t key)
{
int idx = getIndex(key);
if (idx < 0)
return false;
ptr_[idx].exists_ = false;
--size_;
if (idx >= MAX_NODE_NUM)
--out_count_;
// 往后寻找一个移上来替换
int start = idx;
++idx;
while (ptr_[idx].exists_ && idx < (int)MAX_SIZE_)
{
if (start >= MAX_NODE_NUM)
{
int cnt = (int)out_count_ - (start - MAX_NODE_NUM);
if (cnt > 0)
{
memmove(ptr_ + start, ptr_ + idx, cnt * sizeof(HashNode));
// 整块内存往前移动了一格,原来最后的那个格就可以设为false
ptr_[MAX_NODE_NUM + out_count_].exists_ = false;
}
break;
}
int key_idx = ptr_[idx].key_ % MAX_NODE_NUM;
if (key_idx <= start)
{
ptr_[start] = ptr_[idx];
ptr_[idx].exists_ = false;
start = idx;
if (idx >= MAX_NODE_NUM)
-- out_count_;
}
++idx;
}
return true;
}
// 获取键在表中的索引
int getIndex(uint64_t key) const
{
size_t start = key % MAX_NODE_NUM, idx = start;
while (ptr_[idx].exists_ && idx < MAX_SIZE_)
{
if (ptr_[idx].key_ == key)
return (int)idx;
else
++idx;
}
return -1;
}
void update(uint64_t key, const T& data)
{
int idx = getIndex(key);
if (idx >= 0)
{
ptr_[idx].value_ = data;
}
}
};
}
#endif

View File

@@ -0,0 +1,331 @@
#ifndef _STR_HASH_TABLE_H_
#define _STR_HASH_TABLE_H_
/************************************************************************
* <20><>ϣ<EFBFBD><CFA3>
*
* <20><>ϣ<EFBFBD><EFBFBD><E3B7A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ѩ<EFBFBD><D1A9>ϣ<EFBFBD><EFBFBD><E3B7A8>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>3<EFBFBD><33><EFBFBD><EFBFBD>ϣֵ<CFA3><D6B5><EFBFBD><EFBFBD><EFBFBD>жϣ<D0B6>һ<EFBFBD><D2BB><EFBFBD>̶<EFBFBD><CCB6>Ͽ<EFBFBD><CFBF>Լ<EFBFBD>
* <20><>ķ<EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD>ֳ<EFBFBD>ͻ<EFBFBD><CDBB>
*
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>hash<73><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>
* ʼ<><CABC><EFBFBD>ҿ<EFBFBD>λ<EFBFBD><CEBB>ֱ֪<D6AA><D6B1><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>α<EFBFBD><CEB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* <20>ӱ<EFBFBD><D3B1>в<EFBFBD><D0B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>hashֵ<68><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD>ϣֵ<CFA3><D6B5>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ʼ<EFBFBD><CABC><EFBFBD>ҿ<EFBFBD>λ<EFBFBD><CEBB>ֱ֪<D6AA><D6B1><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>α<EFBFBD><CEB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
*
************************************************************************/
#include "bzhash.h"
template <typename T>
class StrHashTable;
template <typename T>
class StrHashTableIterator
{
public:
StrHashTableIterator()
{
m_pTable = NULL;
m_nIndex = 0;
}
StrHashTableIterator(const StrHashTable<T>& table)
{
setTable(table);
}
inline void setTable(const StrHashTable<T>& table)
{
m_pTable = &table;
m_nIndex = 0;
}
inline T* first()
{
int nLen = (int)(m_pTable->m_nLen);
m_nIndex = 0;
while (m_nIndex < nLen)
{
typename StrHashTable<T>::NodeType* pNode =
&m_pTable->m_pTable[m_nIndex];
m_nIndex++;
if (pNode->hash1)
return &pNode->value;
}
return NULL;
}
inline T* next()
{
int nLen = (int)(m_pTable->m_nLen);
while (m_nIndex < nLen)
{
typename StrHashTable<T>::NodeType* pNode =
&m_pTable->m_pTable[m_nIndex];
m_nIndex++;
if (pNode->hash1) return &pNode->value;
}
return NULL;
}
private:
const StrHashTable<T>* m_pTable;
int m_nIndex;
};
template <typename T>
class StrHashTable
{
friend class StrHashTableIterator<T>;
public:
typedef StrHashTable<T> ClassType;
public:
StrHashTable(size_t len = 0)
{
m_pTable = NULL;
m_nLen = m_nFree = 0;
m_nInitSize = len;
if (len > MiniSize)
{
// <20><><EFBFBD>Ƴ<EFBFBD><C6B3>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4><CEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD>±<EFBFBD><C2B1><EFBFBD>޷<EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD>
size_t val;
for (int i = 0; i < 32; ++i)
{
val = size_t(1 << i);
if (len <= val)
{
m_nInitSize = val;
break;
}
}
}
else
{
m_nInitSize = MiniSize; // <20><><EFBFBD>Ƴ<EFBFBD><C6B3>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4><CEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD>±<EFBFBD><C2B1><EFBFBD>޷<EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD>
}
}
virtual ~StrHashTable()
{
clear();
}
//<2F><>չ<EFBFBD>ϣ<EFBFBD><CFA3>
void clear()
{
//ѭ<><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (int i = (int)m_nLen - 1; i > -1; --i)
{
if (m_pTable[i].hash1)
{
m_pTable[i].value.~T();
}
}
//<2F>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
if (m_pTable) realloc(m_pTable, 0);
m_pTable = NULL;
m_nLen = m_nFree = 0;
}
//<2F><>ȡ<EFBFBD><C8A1>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
inline size_t count() const
{
return m_nLen - m_nFree;
}
protected:
/** <20><><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD>ʹ<EFBFBD>õĹ<C3B5>ϣ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD>ݽṹ **/
template <typename TA>
class HashNode
{
public:
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* sKey)
{
int idx = getIndex(sKey);
return (idx >= 0) ? &m_pTable[idx].value : NULL;
}
//ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
inline const T* get(const char* sKey) const
{
int idx = getIndex(sKey);
return (idx >= 0) ? &m_pTable[idx].value : NULL;
}
/* ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
* <20><><EFBFBD>һ<EFBFBD><D2BB>hash<73><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <20><><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ʼ<EFBFBD><CABC><EFBFBD>ҿ<EFBFBD>λ<EFBFBD><CEBB>ֱ֪<D6AA><D6B1><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>α<EFBFBD><CEB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
inline T* put(const char* sKey)
{
unsigned int hash1, idx, start;
#ifdef _MSC_VER
unsigned int hash2, hash3;
#else
unsigned int __attribute__ ((unused)) hash2, hash3;
#endif
//<2F>ڴ<EFBFBD>ռ<D5BC><EFBFBD><E3A3AC><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>ռ<EFBFBD>
if (m_nFree <= 0)
{
size_t oldlen = m_nLen;
m_nLen = (oldlen <= 0) ? m_nInitSize : m_nLen << 1;//<2F><><EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4>
m_nFree = m_nLen - oldlen;
m_pTable = (NodeType*)realloc(m_pTable, m_nLen * sizeof(m_pTable[0]));
memset(&m_pTable[oldlen], 0, m_nFree * sizeof(m_pTable[0]));
}
hash1 = ::bzhashstr(sKey, 0);
hash2 = ::bzhashstr(sKey, 1);
hash3 = ::bzhashstr(sKey, 2);
start = idx = hash1 & ((unsigned int)m_nLen - 1);//<2F><><EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4>
do
{
NodeType* pNode = &m_pTable[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 (!pNode->hash1)
{
pNode->hash1 = hash1;
pNode->hash2 = ::bzhashstr(sKey, 1);
pNode->hash3 = ::bzhashstr(sKey, 2);
m_nFree--;
new(&pNode->value)T();
return &pNode->value;
}
#ifdef _DEBUG
else if (pNode->hash1 == hash1 && pNode->hash2 == hash2 && pNode->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)m_nLen - 1);//<2F><><EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4>
}
while (start != idx);
return NULL;
}
//ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
inline int update(const char* sKey, const T& value)
{
int idx = getIndex(sKey);
if (idx >= 0)
m_pTable[idx].value = value;
return idx;
}
//ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD>ֵ<EFBFBD><D6B5>û<EFBFBD><C3BB><EFBFBD>ҵ<EFBFBD><D2B5>򷵻<EFBFBD>-1
inline int remove(const char* sKey)
{
int idx = getIndex(sKey);
if (idx >= 0)
{
NodeType* pNode = &m_pTable[idx];
pNode->hash1 = pNode->hash2 = pNode->hash3 = 0;
m_nFree++;
pNode->value.~T();
return idx;
}
return -1;
}
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD>ڱ<EFBFBD><DAB1>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>
int getIndex(const char* sKey) const
{
unsigned int idx, start;
size_t len;
if (m_nLen <= 0)
return -1;
unsigned int hash1 = ::bzhashstr(sKey, 0);
unsigned int hash2 = ::bzhashstr(sKey, 1);
unsigned int hash3 = ::bzhashstr(sKey, 2);
//<2F><><EFBFBD>ȿ<EFBFBD>ʼ<EFBFBD>۰<EFBFBD><DBB0><EFBFBD><EFBFBD>
len = m_nLen;
while (len >= m_nInitSize)
{
idx = hash1 & ((unsigned int)len - 1);//<2F><><EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4>
NodeType* pNode = &m_pTable[idx];
if (pNode->hash1 == hash1 && pNode->hash2 == hash2 && pNode->hash3 == hash3)
{
return idx;
}
len >>= 1;
}
//<2F>۰<EFBFBD><DBB0><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>hashλ<68>ÿ<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
start = idx = hash1 & ((unsigned int)m_nLen - 1);//<2F><><EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4>
do
{
NodeType* pNode = &m_pTable[idx];
if (pNode->hash1 == hash1 && pNode->hash2 == hash2 && pNode->hash3 == hash3)
{
return idx;
}
idx = (idx + 1) & ((unsigned int)m_nLen - 1);//<2F><><EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4>
}
while (start != idx);
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 m_nInitSize;//<2F><><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
size_t m_nLen; //<2F><>ϣ<EFBFBD><CFA3><EFBFBD>ij<EFBFBD><C4B3><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4><CEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD>±<EFBFBD><C2B1><EFBFBD>޷<EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD>
size_t m_nFree; //<2F><><EFBFBD>нڵ<D0BD><DAB5><EFBFBD><EFBFBD><EFBFBD>
HashNode<T>* m_pTable; //<2F><>ϣ<EFBFBD><CFA3>
public:
static const size_t MiniSize = 16;//<2F><>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD>ȣ<EFBFBD><C8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD>Ĵη<C4B4><CEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD>±<EFBFBD><C2B1><EFBFBD>޷<EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD>
};
#endif

View File

@@ -0,0 +1,195 @@
#ifndef _VECTOR_H_
#define _VECTOR_H_
/******************************************************************
*
* 类std::vector 的动态数组类封装了部分接口也尽量与std::vector
* 接近.
* 注意可指定最小的内存数量默认是16每次扩展是翻倍
*
*****************************************************************/
#include <assert.h>
#include "memory/base_allocator.hpp"
namespace container
{
template <typename T, int ONE_TIME_NUM = 16>
class Vector
{
protected:
T* data_ptr_;
int max_size_;
int count_;
BaseAllocator* alloc;
public:
Vector(BaseAllocator* alloc = NULL)
{
data_ptr_ = NULL;
max_size_ = 0;
count_ = 0;
this->alloc = alloc;
}
virtual ~Vector()
{
empty();
}
inline int count() const
{
return count_;
}
inline int size() const
{
return count_;
}
inline int max_size() const
{
return max_size_;
}
void insert(const int index, const T& data)
{
assert(index > -1 && index <= count_);
if (count_ >= max_size_)
reserve((max_size_ > 0) ? max_size_ * 2 : ONE_TIME_NUM);
if (index < count_)
{
memmove(data_ptr_ + index + 1, data_ptr_ + index, sizeof(T) * (count_ - index));
}
data_ptr_[index] = data;
count_++;
}
int add(const T& data)
{
if (count_ >= max_size_)
reserve((max_size_ > 0) ? max_size_ * 2 : ONE_TIME_NUM);
memcpy(data_ptr_ + count_, &data, sizeof(data));
count_++;
return count_ - 1;
}
int push_back(const T& data)
{
return add(data);
}
inline T& get(const int index) const
{
assert(index > -1 && index < count_);
return data_ptr_[index];
}
inline void set(const int index, const T& item)
{
assert(index > -1 && index < count_);
data_ptr_[index] = item;
}
int index(const T& data) const
{
int i;
for (i = count_ - 1; i > -1; --i)
{
if (data_ptr_[i] == data)
{
return i;
}
}
return -1;
}
void remove(const int index)
{
assert(index > -1 && index < count_);
remove(index, 1);
}
void remove(const int index, const int count)
{
assert(index + count <= count_);
if (count > 0)
{
memmove(data_ptr_ + index, data_ptr_ + index + count, sizeof(data_ptr_[0]) * (count_ - index - count));
count_ -= count;
}
}
virtual void empty()
{
clear();
max_size_ = 0;
if (data_ptr_)
{
if (alloc) alloc->FreeBuffer(data_ptr_);
else free(data_ptr_);
data_ptr_ = NULL;
}
}
inline void clear()
{
count_ = 0;
}
inline void trunc(const int count)
{
assert(count > -1 && count <= max_size_);
count_ = count;
}
virtual void reserve(int count)
{
if (count > count_ && count != max_size_)
{
max_size_ = count;
if (alloc)
{
data_ptr_ = (T*) alloc->ReAllocBuffer(data_ptr_, sizeof(T) * count);
}
else
{
data_ptr_ = (T*)realloc(data_ptr_, sizeof(T) * count);
}
}
}
inline void addList(const Vector<T>& list)
{
addArray((T*)list, list.count_);
}
inline void addArray(T* data, int length)
{
if (count_ + length > max_size_)
reserve(count_ + length);
memcpy(data_ptr_ + count_, data, length * sizeof(T));
count_ += length;
}
inline int push(const T& data)
{
return add(data);
}
inline T pop()
{
if (count_ > 0)
{
count_--;
return data_ptr_[count_];
}
throw "stack was empty";
}
inline operator T* () const
{
return data_ptr_;
}
};
};
#endif