重整Pool,Stack,Queue模板

This commit is contained in:
hyzboy 2020-07-24 17:13:41 +08:00
parent 95f8e803d3
commit e62d52181b
6 changed files with 248 additions and 196 deletions

View File

@ -6,36 +6,58 @@
namespace hgl namespace hgl
{ {
template<typename T> template<typename T>
void Pool<T>::PreMalloc(int num) void Pool<T>::PreMalloc(int num,bool set_to_max_count)
{ {
if(num<=0)return; if(num<=0)return;
for(int i=0;i<num;i++) for(int i=0;i<num;i++)
Inactive.Push(Create()); Inactive.Push(Create());
count+=num; alloc_count+=num;
if(count>history_max) if(alloc_count>history_max)
history_max=count; history_max=alloc_count;
if(set_to_max_count)
max_count=alloc_count;
} }
template<typename T> template<typename T>
T Pool<T>::Acquire() int Pool<T>::SetMaxCount(int mc)
{ {
T result; if(mc<0)
return(mc);
if(!Inactive.Pop(result)) if(mc==0)
{ {
result=Create(); max_count=0;
return 0;
count++; }
if(count>history_max)
history_max=count;
} }
Active.Add(result); template<typename T>
bool Pool<T>::Acquire(T &value)
{
if(!Inactive.Pop(value))
{
if(max_count>0&&alloc_count>=max_count)
return(false);
return(result); result=Create();
alloc_count++;
if(alloc_count>history_max)
history_max=alloc_count;
}
Active.Add(value);
return(true);
}
template<typename T>
bool Pool<T>::Get(T &value)
{
return Inactive.Pop(value);
} }
template<typename T> template<typename T>
@ -45,10 +67,10 @@ namespace hgl
if(!Inactive.Pop(result)) if(!Inactive.Pop(result))
{ {
count++; alloc_count++;
if(count>history_max) if(alloc_count>history_max)
history_max=count; history_max=alloc_count;
} }
Active.Add(result); Active.Add(result);
@ -74,11 +96,11 @@ namespace hgl
} }
template<typename T> template<typename T>
int Pool<T>::Release(T *vl,int count) int Pool<T>::Release(T *vl,int alloc_count)
{ {
int total=0; int total=0;
for(int i=0;i<count;i++) for(int i=0;i<alloc_count;i++)
{ {
if(Release(*vl)) if(Release(*vl))
++total; ++total;
@ -92,53 +114,47 @@ namespace hgl
template<typename T> template<typename T>
int Pool<T>::ReleaseAll() int Pool<T>::ReleaseAll()
{ {
int count=Active.GetCount(); int alloc_count=Active.GetCount();
T *p=Active.GetData();
for(int i=0;i<count;i++) Inactive.Push(Active.GetData(),alloc_count);
Inactive.Push(*p++);
Active.ClearData(); Active.ClearData();
return(count); return(alloc_count);
}
template<typename T>
void Pool<T>::Clear(T *dp,int dc)
{
for(int i=0;i<ic;i++)
{
Clear(*dp);
++dp;
}
} }
template<typename T> template<typename T>
void Pool<T>::ClearInactive() void Pool<T>::ClearInactive()
{ {
T result; T *p=Inactive.GetData();
int ic=Inactive.GetCount();
count-=Inactive.GetCount(); alloc_count-=ic;
while(Inactive.Pop(result)) Clear(p,ic);
Clear(result);
Inactive.ClearData();
} }
template<typename T> template<typename T>
void Pool<T>::ClearAll() void Pool<T>::ClearAll()
{ {
{ //不能直接调ClearInactive Clear(Inactive.GetData(),Inactive.GetCount());
T result; Inactive.ClearData();
count-=Inactive.GetCount(); Clear(Active.GetData(),Active.GetCount());
Active.ClearData();
while(Inactive.Pop(result)) alloc_count=0;
Clear(result);
}
{
int n=Active.GetCount();
T *p=Active.GetData();
while(n--)
{
Clear(*p);
++p;
}
Active.Clear();
}
count=0;
} }
}//namespace hgl }//namespace hgl
#endif//HGL_POOL_CPP #endif//HGL_POOL_CPP

View File

@ -18,28 +18,35 @@ namespace hgl
List<T> Active; List<T> Active;
Queue<T> Inactive; Queue<T> Inactive;
int count; int alloc_count; ///<已分配的数据数量
int history_max; int max_count; ///<最大可分配数量
int history_max; ///<历史最大数量
protected: protected:
virtual T Create()=0; ///<创建数据 virtual T Create()=0; ///<创建数据
virtual void Clear(T)=0; ///<清除数据 virtual void Clear(T)=0; ///<清除数据
void Clear(T *,int);
public: //属性 public: //属性
virtual int GetActiveCount() const{return Active.GetCount();} ///<取得活动数据数量 int GetMaxCount() const{return max_count;} ///<最大最大限制
virtual int GetInactiveCount() const{return Inactive.GetCount();} ///<取得非活动数据数量 int GetActiveCount() const{return Active.GetCount();} ///<取得活动数据数量
virtual int GetHistoryMaxCount()const{return history_max;} ///<取得历史性最大数据数量 int GetInactiveCount() const{return Inactive.GetCount();} ///<取得非活动数据数量
int GetHistoryMaxCount()const{return history_max;} ///<取得历史性最大数据数量
public: public:
Pool(){count=0;history_max=0;} Pool(){alloc_count=0;history_max=0;max_count=0;}
virtual ~Pool()=default; virtual ~Pool()=default;
virtual void PreMalloc(int); ///<预分配空间 virtual void PreMalloc(int,bool set_to_max=false); ///<预分配空间
virtual T Acquire(); ///<申请一个数据 virtual int SetMaxCount(int); ///<设定最大数量限制
virtual bool Acquire(T &); ///<申请一个数据(如果没有空余,创建新的)
virtual bool Get(T &); ///<获取一个数据(如果没有空余,返回失败)
virtual void Append(T); ///<添加一个数据 virtual void Append(T); ///<添加一个数据
virtual bool Release(T); ///<释放一个数据 virtual bool Release(T); ///<释放一个数据
virtual int Release(T *,int); ///<释放一批数据 virtual int Release(T *,int); ///<释放一批数据

View File

@ -10,7 +10,7 @@ namespace hgl
template<typename T> template<typename T>
Queue<T>::Queue(int m) Queue<T>::Queue(int m)
{ {
count=0; cur_count=0;
if(m) if(m)
{ {
@ -20,30 +20,59 @@ namespace hgl
} }
else max_count=0; else max_count=0;
mem_count=max_count; alloc_count=max_count;
} }
template<typename T> template<typename T>
Queue<T>::~Queue() Queue<T>::~Queue()
{ {
if(count||max_count)hgl_free(items); if(cur_count||max_count)hgl_free(items);
}
template<typename T>
bool Queue<T>::AllocMemory(int count)
{
if(max_count)
if(count>max_count)return(false);
if(cur_count)
{
if(count>alloc_count)
{
alloc_count=power_to_2(count);
items=(T *)hgl_realloc(items,alloc_count*sizeof(T));
}
}
else
{
alloc_count=power_to_2(count);
items=hgl_aligned_malloc<T>(alloc_count);
}
return(true);
} }
/** /**
* *
*/ */
template<typename T> template<typename T>
void Queue<T>::SetMax(int m) bool Queue<T>::SetMaxCount(int m)
{ {
if(max_count||(!max_count&&count)) if(max_count)
items=(T *)hgl_realloc(items,m*sizeof(T)); {
else if(max_count==m)return(true);
items=hgl_aligned_malloc<T>(m); }
if(cur_count)
{
if(cur_count>m)
return(false);
}
max_count=m; max_count=m;
mem_count=m; return(true);
if(count>=max_count)count=max_count-1;
} }
/** /**
@ -53,13 +82,13 @@ namespace hgl
void Queue<T>::Clear() void Queue<T>::Clear()
{ {
if(max_count==0) if(max_count==0)
if(count) if(cur_count)
{ {
hgl_free(items); hgl_free(items);
mem_count=0; alloc_count=0;
} }
count=0; cur_count=0;
} }
/** /**
@ -68,7 +97,7 @@ namespace hgl
template<typename T> template<typename T>
void Queue<T>::ClearData() void Queue<T>::ClearData()
{ {
count=0; cur_count=0;
} }
/** /**
@ -79,7 +108,7 @@ namespace hgl
template<typename T> template<typename T>
bool Queue<T>::Peek(T &t) bool Queue<T>::Peek(T &t)
{ {
if(count) if(cur_count)
{ {
// t=items[0]; // t=items[0];
memcpy(&t,items,sizeof(T)); memcpy(&t,items,sizeof(T));
@ -96,15 +125,15 @@ namespace hgl
template<typename T> template<typename T>
bool Queue<T>::Delete(int index) bool Queue<T>::Delete(int index)
{ {
if(index<0||index>=count) if(index<0||index>=cur_count)
return(false); return(false);
count--; cur_count--;
if(count) if(cur_count)
{ {
if(index<count) if(index<cur_count)
memmove(items+index,items+index+1,(count-index)*sizeof(T)); memmove(items+index,items+index+1,(cur_count-index)*sizeof(T));
} }
return(true); return(true);
@ -118,25 +147,25 @@ namespace hgl
template<typename T> template<typename T>
bool Queue<T>::Pop(T &t) bool Queue<T>::Pop(T &t)
{ {
if(count) if(cur_count)
{ {
// t=items[0]; // t=items[0];
memcpy(&t,items,sizeof(T)); memcpy(&t,items,sizeof(T));
count--; cur_count--;
if(max_count==0) if(max_count==0)
{ {
if(count) if(cur_count)
{ {
//memcpy(items,items+1,count*sizeof(T)); //memcpy(items,items+1,count*sizeof(T));
memmove(items,items+1,count*sizeof(T)); memmove(items,items+1,cur_count*sizeof(T));
// items=(T *)hgl_realloc(items,count*sizeof(T)); // items=(T *)hgl_realloc(items,count*sizeof(T));
} }
} }
else else
{ {
memcpy(items,items+1,count*sizeof(T)); memcpy(items,items+1,cur_count*sizeof(T));
} }
return(true); return(true);
@ -154,32 +183,29 @@ namespace hgl
template<typename T> template<typename T>
bool Queue<T>::Push(const T &data) bool Queue<T>::Push(const T &data)
{ {
if(max_count) if(!AllocMemory(cur_count+1))
{ return(false);
if(count>=max_count)return(false);
}
else
{
if(count)
{
if(count+1>mem_count)
{
mem_count=power_to_2(count+1);
items=(T *)hgl_realloc(items,mem_count*sizeof(T));
}
}
else
{
items=hgl_aligned_malloc<T>(1);
mem_count=1;
}
}
// items[count++]=data; // items[count++]=data;
memcpy(items+count,&data,sizeof(T)); memcpy(items+cur_count,&data,sizeof(T));
count++; cur_count++;
return(true);
}
/**
*
* @param dp
* @param dc
*/
template<typename T>
bool Queue<T>::Push(T *dp,const int dc)
{
if(!AllocMemory(cur_count+dc))
return(false);
memcpy(items+cur_count,dp,sizeof(T)*dc);
cur_count+=dc;
return(true); return(true);
} }
@ -187,11 +213,11 @@ namespace hgl
template<typename T> template<typename T>
int Queue<T>::Find(const T &data) int Queue<T>::Find(const T &data)
{ {
if(count<=0) if(cur_count<=0)
return(-1); return(-1);
T *p=items; T *p=items;
for(int i=0;i<count;i++) for(int i=0;i<cur_count;i++)
{ {
if(*p==data) if(*p==data)
return(i); return(i);
@ -205,21 +231,21 @@ namespace hgl
template<typename T> template<typename T>
void Queue<T>::operator =(const Queue<T> &ori) void Queue<T>::operator =(const Queue<T> &ori)
{ {
if(ori.count==0)return; if(ori.cur_count==0)return;
Clear(); Clear();
max_count=ori.count; max_count=ori.cur_count;
count=ori.count; cur_count=ori.cur_count;
if(max_count==0) if(max_count==0)
mem_count=count; alloc_count=cur_count;
else else
mem_count=max_count; alloc_count=max_count;
items=hgl_aligned_malloc<T>(mem_count); items=hgl_aligned_malloc<T>(alloc_count);
memcpy(items,ori.items,mem_count*sizeof(T)); memcpy(items,ori.items,alloc_count*sizeof(T));
} }
} }
@ -228,7 +254,7 @@ namespace hgl
template<typename T> template<typename T>
void QueueObject<T>::Clear() void QueueObject<T>::Clear()
{ {
int n=Queue<T *>::count; int n=Queue<T *>::cur_count;
while(n--) while(n--)
delete Queue<T *>::items[n]; delete Queue<T *>::items[n];

View File

@ -13,20 +13,22 @@ namespace hgl
{ {
protected: protected:
int max_count; int max_count; ///<最大可分配空间数量
int mem_count; int alloc_count; ///<已分配的空间数量
int count; int cur_count;
T *items; T *items;
protected:
bool AllocMemory(int);
public: //属性 public: //属性
T * GetData ()const{return items;} ///<取得原始数据 T * GetData ()const{return items;} ///<取得原始数据
int GetCount()const{return count;} ///<取得数据数量 int GetCount ()const{return cur_count;} ///<取得数据数量
int GetMax()const{return max_count;} ///<取得最大数量 int GetMaxCount ()const{return max_count;} ///<取得最大数量
void SetMax(int); ///<设置最大数量 bool SetMaxCount (int); ///<设置最大数量
T *GetData(){return items;} ///<取得原始数据
public: //方法 public: //方法
@ -36,6 +38,7 @@ namespace hgl
bool Peek (T &); ///<尝试访问一个数据 bool Peek (T &); ///<尝试访问一个数据
bool Pop (T &); ///<弹出一个数据 bool Pop (T &); ///<弹出一个数据
bool Push (const T &); ///<压入一个数据 bool Push (const T &); ///<压入一个数据
bool Push (T *,int); ///<压入一批数据
int Find (const T &); ///<查找队列中这个数据的编号 int Find (const T &); ///<查找队列中这个数据的编号
bool Delete (int); ///<删除队列中指定编号的数据 bool Delete (int); ///<删除队列中指定编号的数据
@ -45,7 +48,7 @@ namespace hgl
bool GetItem (int n,T &ti) ///<取得指定项数据 bool GetItem (int n,T &ti) ///<取得指定项数据
{ {
if(n<0||n>=count)return(false); if(n<0||n>=cur_count)return(false);
ti=items[n]; ti=items[n];
return(true); return(true);
@ -65,7 +68,7 @@ namespace hgl
T *operator[](int n)const T *operator[](int n)const
{ {
if(n<0||n>=Queue<T *>::count)return(nullptr); if(n<0||n>=Queue<T *>::cur_count)return(nullptr);
return Queue<T *>::items[n]; return Queue<T *>::items[n];
} }

View File

@ -11,7 +11,7 @@ namespace hgl
template<typename T> template<typename T>
Stack<T>::Stack(int m) Stack<T>::Stack(int m)
{ {
count=0; cur_count=0;
if(m) if(m)
{ {
@ -22,38 +22,38 @@ namespace hgl
else else
max_count=0; max_count=0;
mem_count=max_count; alloc_count=max_count;
} }
template<typename T> template<typename T>
Stack<T>::~Stack() Stack<T>::~Stack()
{ {
if(count||max_count)hgl_free(items); if(cur_count||max_count)hgl_free(items);
} }
/** /**
* *
*/ */
template<typename T> template<typename T>
void Stack<T>::SetMax(int m) void Stack<T>::SetMaxCount(int m)
{ {
if(m<=0)return; if(m<=0)return;
if(mem_count==0) if(alloc_count==0)
{ {
mem_count=power_to_2(m); alloc_count=power_to_2(m);
items=hgl_aligned_malloc<T>(mem_count); items=hgl_aligned_malloc<T>(alloc_count);
} }
else else
if(mem_count<m) if(alloc_count<m)
{ {
mem_count=power_to_2(m); alloc_count=power_to_2(m);
items=(T *)hgl_realloc(items,mem_count*sizeof(T)); items=(T *)hgl_realloc(items,alloc_count*sizeof(T));
} }
max_count=m; max_count=m;
if(count>=max_count)count=max_count-1; if(cur_count>=max_count)cur_count=max_count-1;
} }
template<typename T> template<typename T>
@ -64,7 +64,7 @@ namespace hgl
if(c>max_count) if(c>max_count)
return(false); return(false);
count=c; cur_count=c;
return(true); return(true);
} }
@ -75,21 +75,21 @@ namespace hgl
void Stack<T>::Clear() void Stack<T>::Clear()
{ {
if(max_count==0) if(max_count==0)
if(count) if(cur_count)
{ {
hgl_free(items); hgl_free(items);
mem_count=0; alloc_count=0;
} }
count=0; cur_count=0;
} }
template<typename T> template<typename T>
bool Stack<T>::GetItem(int n,T &data) bool Stack<T>::GetItem(int n,T &data)
{ {
if(n<0||n>=count) if(n<0||n>=cur_count)
{ {
LOG_ERROR(OS_TEXT("从堆栈中按索引<") + OSString(n) + OS_TEXT(">取数据,超出正常范围<")+OSString(count) + OS_TEXT(">")); LOG_ERROR(OS_TEXT("从堆栈中按索引<") + OSString(n) + OS_TEXT(">取数据,超出正常范围<")+OSString(cur_count) + OS_TEXT(">"));
return(false); return(false);
} }
@ -106,10 +106,10 @@ namespace hgl
template<typename T> template<typename T>
bool Stack<T>::Peek(T &t) bool Stack<T>::Peek(T &t)
{ {
if(count) if(cur_count)
{ {
memcpy(&t,items+(count-1),sizeof(T)); memcpy(&t,items+(cur_count-1),sizeof(T));
// t=items[count-1]; // t=items[cur_count-1];
return(true); return(true);
} }
else else
@ -124,22 +124,22 @@ namespace hgl
template<typename T> template<typename T>
bool Stack<T>::Pop(T &t) bool Stack<T>::Pop(T &t)
{ {
if(count) if(cur_count)
{ {
// t=items[--count]; // t=items[--cur_count];
count--; cur_count--;
memcpy(&t,items+count,sizeof(T)); memcpy(&t,items+cur_count,sizeof(T));
if(max_count==0) if(max_count==0)
{ {
if(count==0) if(cur_count==0)
{ {
hgl_free(items); hgl_free(items);
mem_count=0; alloc_count=0;
} }
//else //else
//items=(T *)hgl_realloc(items,count*sizeof(T)); //items=(T *)hgl_realloc(items,cur_count*sizeof(T));
} }
return(true); return(true);
@ -159,30 +159,30 @@ namespace hgl
{ {
if(max_count) if(max_count)
{ {
if(count>=max_count)return(false); if(cur_count>=max_count)return(false);
} }
else else
{ {
if(count) if(cur_count)
{ {
if(count+1>mem_count) if(cur_count+1>alloc_count)
{ {
mem_count=power_to_2(count+1); alloc_count=power_to_2(cur_count+1);
items=(T *)hgl_realloc(items,mem_count*sizeof(T)); items=(T *)hgl_realloc(items,alloc_count*sizeof(T));
} }
} }
else else
{ {
items=hgl_aligned_malloc<T>(1); items=hgl_aligned_malloc<T>(1);
mem_count=1; alloc_count=1;
} }
} }
// items[count++]=data; // items[cur_count++]=data;
memcpy(items+count,&data,sizeof(T)); memcpy(items+cur_count,&data,sizeof(T));
count++; cur_count++;
return(true); return(true);
} }
@ -195,33 +195,33 @@ namespace hgl
* @return false * @return false
*/ */
template<typename T> template<typename T>
bool Stack<T>::MultiPush(T *data,int data_count) bool Stack<T>::Push(T *data,int data_count)
{ {
if(max_count) if(max_count)
{ {
if(count>=max_count)return(false); if(cur_count>=max_count)return(false);
} }
else else
{ {
if(count) if(cur_count)
{ {
if(count+data_count>mem_count) if(cur_count+data_count>alloc_count)
{ {
mem_count=power_to_2(count+data_count); alloc_count=power_to_2(cur_count+data_count);
items=(T *)hgl_realloc(items,mem_count*sizeof(T)); items=(T *)hgl_realloc(items,alloc_count*sizeof(T));
} }
} }
else else
{ {
items=hgl_aligned_malloc<T>(data_count); items=hgl_aligned_malloc<T>(data_count);
mem_count=data_count; alloc_count=data_count;
} }
} }
memcpy(items+count,data,data_count*sizeof(T)); memcpy(items+cur_count,data,data_count*sizeof(T));
count+=data_count; cur_count+=data_count;
return(true); return(true);
} }
@ -229,21 +229,21 @@ namespace hgl
template<typename T> template<typename T>
void Stack<T>::operator =(const Stack<T> &ori) void Stack<T>::operator =(const Stack<T> &ori)
{ {
if(ori.count==0)return; if(ori.cur_count==0)return;
Clear(); Clear();
max_count=ori.count; max_count=ori.cur_count;
count=ori.count; cur_count=ori.cur_count;
if(max_count==0) if(max_count==0)
mem_count=count; alloc_count=cur_count;
else else
mem_count=max_count; alloc_count=max_count;
items=hgl_aligned_malloc<T>(mem_count); items=hgl_aligned_malloc<T>(alloc_count);
memcpy(items,ori.items,mem_count*sizeof(T)); memcpy(items,ori.items,alloc_count*sizeof(T));
} }
}//namespace hgl }//namespace hgl
@ -252,7 +252,7 @@ namespace hgl
template<typename T> template<typename T>
void StackObject<T>::Clear() void StackObject<T>::Clear()
{ {
for(int i=0;i<this->count;i++) for(int i=0;i<this->cur_count;i++)
delete this->items[i]; delete this->items[i];
Stack<T *>::Clear(); Stack<T *>::Clear();

View File

@ -14,17 +14,17 @@ namespace hgl
protected: protected:
int max_count; int max_count;
int mem_count; int alloc_count;
int count; int cur_count;
T *items; T *items;
public: //属性 public: //属性
int GetCount() const{return count;} ///<取得堆栈中数据的个数 int GetCount () const{return cur_count;} ///<取得堆栈中数据的个数
bool SetCount (int c); ///<直接设置堆栈中数据的个数 bool SetCount (int c); ///<直接设置堆栈中数据的个数
int GetMax () const{return max_count;} ///<取得堆栈中的最大数据个数 int GetMaxCount () const{return max_count;} ///<取得堆栈中的最大数据个数
void SetMax (int); ///<设置堆栈中的最大数据个数 void SetMaxCount (int); ///<设置堆栈中的最大数据个数
T * GetData () {return items;} ///<取得原始数据 T * GetData () {return items;} ///<取得原始数据
@ -36,7 +36,7 @@ namespace hgl
bool Peek(T &); ///<尝试访问一个数据 bool Peek(T &); ///<尝试访问一个数据
virtual bool Pop(T &); ///<弹出一个数据 virtual bool Pop(T &); ///<弹出一个数据
bool Push(T &); ///<压入一个数据 bool Push(T &); ///<压入一个数据
bool MultiPush(T *,int); ///<放入多个数据 bool Push(T *,int); ///<压入多个数据
virtual void Clear(); ///<清除所有数据 virtual void Clear(); ///<清除所有数据