init
This commit is contained in:
184
Gateway/srvlib/include/container/binary_list.h
Normal file
184
Gateway/srvlib/include/container/binary_list.h
Normal 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
|
||||
|
||||
183
Gateway/srvlib/include/container/bz_hash_table.h
Normal file
183
Gateway/srvlib/include/container/bz_hash_table.h
Normal 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
|
||||
403
Gateway/srvlib/include/container/linked_list.h
Normal file
403
Gateway/srvlib/include/container/linked_list.h
Normal 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
|
||||
|
||||
41
Gateway/srvlib/include/container/linked_list_ex.h
Normal file
41
Gateway/srvlib/include/container/linked_list_ex.h
Normal 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
|
||||
|
||||
|
||||
50
Gateway/srvlib/include/container/lock_list.h
Normal file
50
Gateway/srvlib/include/container/lock_list.h
Normal 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
|
||||
|
||||
81
Gateway/srvlib/include/container/obj_list.h
Normal file
81
Gateway/srvlib/include/container/obj_list.h
Normal 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
|
||||
|
||||
|
||||
58
Gateway/srvlib/include/container/queue_list.h
Normal file
58
Gateway/srvlib/include/container/queue_list.h
Normal 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
|
||||
|
||||
129
Gateway/srvlib/include/container/static_array_list.h
Normal file
129
Gateway/srvlib/include/container/static_array_list.h
Normal 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
|
||||
|
||||
|
||||
165
Gateway/srvlib/include/container/static_hash_table.h
Normal file
165
Gateway/srvlib/include/container/static_hash_table.h
Normal 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
|
||||
331
Gateway/srvlib/include/container/str_hash_table.h
Normal file
331
Gateway/srvlib/include/container/str_hash_table.h
Normal 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
|
||||
|
||||
195
Gateway/srvlib/include/container/vector.h
Normal file
195
Gateway/srvlib/include/container/vector.h
Normal 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
|
||||
|
||||
Reference in New Issue
Block a user