completed Pool<>,improved List<>/Queue<>
This commit is contained in:
parent
e1f6ee9b12
commit
3fc8005877
@ -38,7 +38,7 @@ namespace hgl
|
||||
template<typename T> static int FindDataPositionInArray(const T *data_list,const int count,const T &data)
|
||||
{
|
||||
if(!data_list)return(-1);
|
||||
if(count<=0)return(-2);
|
||||
if(count<=0)return(-1);
|
||||
|
||||
const T *p=data_list;
|
||||
|
||||
@ -51,7 +51,7 @@ namespace hgl
|
||||
++p;
|
||||
}
|
||||
|
||||
return -3;
|
||||
return -1;
|
||||
}
|
||||
|
||||
template<typename T,typename O> static int FindDataPositionInArray(const T &data_list,const O &data)
|
||||
|
@ -26,7 +26,6 @@ namespace hgl
|
||||
|
||||
virtual bool OnActive (T *,int count=1){return true;} ///<切换到激活
|
||||
virtual bool OnIdle (T *,int count=1){return true;} ///<切换到空闲
|
||||
virtual bool OnClear (T *,int count=1){return true;} ///<被释放
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -78,7 +78,7 @@ namespace hgl
|
||||
* @param data 要添加的数据对象
|
||||
* @param n 要添加的数据个数
|
||||
* @return 这个数据的索引号
|
||||
* @return -1 出错
|
||||
* @return >0 出错
|
||||
*/
|
||||
virtual int RepeatAdd(const T &data,int n)
|
||||
{
|
||||
@ -115,11 +115,11 @@ namespace hgl
|
||||
|
||||
int Add(const List<T> &l){return Add(l.items,l.count);} ///<增加一批数据
|
||||
|
||||
virtual void Free(){data_array.Free();} ///<清除所有数据
|
||||
virtual void Free(){data_array.Free();} ///<清除所有数据
|
||||
virtual void ClearData(){data_array.Clear();} ///<清除所有数据,但不清空缓冲区
|
||||
|
||||
virtual int Find(const T &data)const{return data_array.Find(data);} ///<查找指定数据的索引
|
||||
virtual bool IsExist(const T &flag)const{return Find(flag)!=-1;} ///<确认数据项是否存在
|
||||
virtual bool IsExist(const T &flag)const{return Find(flag)>=0;} ///<确认数据项是否存在
|
||||
|
||||
virtual bool Delete(int start,int num=1){return data_array.Delete(start,num);} ///<删除指定索引的数据
|
||||
virtual bool DeleteMove(int start,int num=1){return data_array.DeleteMove(start,num);} ///<删除指定索引的数据,将后面紧邻的数据前移
|
||||
@ -152,7 +152,7 @@ namespace hgl
|
||||
|
||||
++data;
|
||||
|
||||
if(index!=-1)
|
||||
if(index>=0)
|
||||
if(Delete(index))
|
||||
++result;
|
||||
}
|
||||
|
@ -1,35 +0,0 @@
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
template<typename T> class _ObjectPool:public Pool<T *> ///对象池
|
||||
{
|
||||
protected:
|
||||
|
||||
virtual T *Create()=0;
|
||||
|
||||
virtual void Clear(T *obj) { if(obj)delete obj; }
|
||||
|
||||
public:
|
||||
|
||||
using Pool<T *>::Pool;
|
||||
virtual ~_ObjectPool(){Pool<T *>::ClearAll();}
|
||||
|
||||
virtual bool Release(T *obj) override ///<释放一个数据
|
||||
{
|
||||
if(!obj)return(true);
|
||||
|
||||
return Pool<T *>::Release(obj);
|
||||
}
|
||||
};//template<typename T> class _ObjectPool
|
||||
|
||||
template<typename T> class ObjectPool:public _ObjectPool<T> ///对象池
|
||||
{
|
||||
virtual T *Create()override{return(new T());}
|
||||
|
||||
public:
|
||||
|
||||
using _ObjectPool<T>::_ObjectPool;
|
||||
virtual ~ObjectPool(){_ObjectPool<T>::ClearAll();}
|
||||
};//template<typename T> class ObjectPool
|
||||
|
||||
}//namespace hgl
|
@ -1,181 +0,0 @@
|
||||
#ifndef HGL_POOL_CPP
|
||||
#define HGL_POOL_CPP
|
||||
|
||||
#include<hgl/type/DataType.h>
|
||||
#include<hgl/type/Pool.h>
|
||||
namespace hgl
|
||||
{
|
||||
template<typename T>
|
||||
void Pool<T>::PreAlloc(int num,bool set_to_max_count)
|
||||
{
|
||||
if(num<=0)return;
|
||||
|
||||
for(int i=0;i<num;i++)
|
||||
{
|
||||
T value=Create();
|
||||
Inactive.Push(value);
|
||||
}
|
||||
|
||||
alloc_count+=num;
|
||||
if(alloc_count>history_max)
|
||||
history_max=alloc_count;
|
||||
|
||||
if(set_to_max_count)
|
||||
max_count=alloc_count;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int Pool<T>::SetMaxCount(int mc)
|
||||
{
|
||||
if(mc<0)
|
||||
return(mc);
|
||||
|
||||
if(mc==0)
|
||||
{
|
||||
max_count=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
max_count=mc;
|
||||
return mc;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Pool<T>::Acquire(T &value)
|
||||
{
|
||||
if(!Inactive.Pop(value))
|
||||
{
|
||||
if(max_count>0&&alloc_count>=max_count)
|
||||
return(false);
|
||||
|
||||
value=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)
|
||||
{
|
||||
if(!Inactive.Pop(value))
|
||||
return(false);
|
||||
|
||||
Active.Add(value);
|
||||
return(true);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Pool<T>::Append(T value)
|
||||
{
|
||||
T result;
|
||||
|
||||
if(!Inactive.Pop(result))
|
||||
{
|
||||
alloc_count++;
|
||||
|
||||
if(alloc_count>history_max)
|
||||
history_max=alloc_count;
|
||||
}
|
||||
|
||||
Active.Add(result);
|
||||
|
||||
result=value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Pool<T>::Release(T value)
|
||||
{
|
||||
int index=Active.Find(value);
|
||||
|
||||
if(index!=-1)
|
||||
{
|
||||
Active.Delete(index);
|
||||
|
||||
Inactive.Push(value);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int Pool<T>::Release(T *vl,int alloc_count)
|
||||
{
|
||||
int total=0;
|
||||
|
||||
for(int i=0;i<alloc_count;i++)
|
||||
{
|
||||
if(Release(*vl))
|
||||
++total;
|
||||
|
||||
++vl;
|
||||
}
|
||||
|
||||
return(total);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int Pool<T>::ReleaseAll()
|
||||
{
|
||||
int alloc_count=Active.GetCount();
|
||||
|
||||
Inactive.Push(Active.GetData(),alloc_count);
|
||||
|
||||
Active.ClearData();
|
||||
return(alloc_count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Pool<T>::Clear(T *dp,int dc)
|
||||
{
|
||||
for(int i=0;i<dc;i++)
|
||||
{
|
||||
Clear(*dp);
|
||||
++dp;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Pool<T>::ClearActive()
|
||||
{
|
||||
T *p=Active.GetData();
|
||||
int ac=Active.GetCount();
|
||||
|
||||
Inactive.Push(p,ac);
|
||||
|
||||
Active.ClearData();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Pool<T>::ClearInactive()
|
||||
{
|
||||
T *p=Inactive.GetData();
|
||||
int ic=Inactive.GetCount();
|
||||
|
||||
alloc_count-=ic;
|
||||
|
||||
Clear(p,ic);
|
||||
|
||||
Inactive.Clear();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Pool<T>::ClearAll()
|
||||
{
|
||||
Clear(Inactive.GetData(),Inactive.GetCount());
|
||||
Inactive.Clear();
|
||||
|
||||
Clear(Active.GetData(),Active.GetCount());
|
||||
Active.ClearData();
|
||||
|
||||
alloc_count=0;
|
||||
}
|
||||
}//namespace hgl
|
||||
#endif//HGL_POOL_CPP
|
@ -1,65 +1,202 @@
|
||||
#ifndef HGL_POOL_INCLUDE
|
||||
#define HGL_POOL_INCLUDE
|
||||
#pragma once
|
||||
|
||||
#include<hgl/type/List.h>
|
||||
#include<hgl/type/Queue.h>
|
||||
#include<hgl/type/SortedSets.h>
|
||||
#include<hgl/type/LifetimeCallback.h>
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 数据池模板用于管于两个队列,一个在用的,一个空闲的
|
||||
* 数据池模板用于管于两个队列,一个在用的,一个空闲的。默认情部下空闲队列使用Queue模板管理(先入先出,总是使用最早扔进去的数据,可手动换成Stack性能更好),活动队列使用List模板管理(无序)。
|
||||
*/
|
||||
template<typename T> class Pool ///数据池
|
||||
template<typename T,typename AT,typename IT,typename DEFAULT_DLC> class _Pool ///数据池
|
||||
{
|
||||
protected:
|
||||
|
||||
List<T> Active;
|
||||
Queue<T> Inactive;
|
||||
DEFAULT_DLC default_dlc;
|
||||
|
||||
int alloc_count; ///<已分配的数据数量
|
||||
int max_count; ///<最大可分配数量
|
||||
AT Active;
|
||||
IT Inactive;
|
||||
|
||||
int max_active_count;
|
||||
int history_max; ///<历史最大数量
|
||||
|
||||
void UpdateHistoryMax()
|
||||
{
|
||||
if(Active.GetCount()+Inactive.GetCount()>history_max)
|
||||
history_max=Active.GetCount()+Inactive.GetCount();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual T Create()=0; ///<创建数据
|
||||
virtual void Clear(T)=0; ///<清除数据
|
||||
|
||||
void Clear(T *,int);
|
||||
DataLifetimeCallback<T> *dlc; ///<数据生命周期回调函数
|
||||
|
||||
public: //属性
|
||||
|
||||
int GetMaxCount() const{return max_count;} ///<最大最大限制
|
||||
int GetActiveCount() const{return Active.GetCount();} ///<取得活动数据数量
|
||||
int GetInactiveCount() const{return Inactive.GetCount();} ///<取得非活动数据数量
|
||||
int GetHistoryMaxCount()const{return history_max;} ///<取得历史性最大数据数量
|
||||
|
||||
T * GetActiveData() const{return Active.GetData();} ///<取得所有活跃数据
|
||||
T * GetInactiveData() const{return Inactive.GetData();} ///<取得所有非活跃数据
|
||||
DataArray<T> & GetActiveArray(){return Active.GetArray();} ///<取得所有活跃数据
|
||||
|
||||
bool IsActive (const T &data)const{return Active.IsExist(data);} ///<是否为活跃的
|
||||
bool IsInactive (const T &data)const{return Inactive.IsExist(data);} ///<是否为非活跃的
|
||||
|
||||
bool IsFull()const ///<活跃队列是否已满
|
||||
{
|
||||
if(max_active_count>0&&Active.GetCount()>=max_active_count)
|
||||
return(true);
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Pool(){alloc_count=0;history_max=0;max_count=0;}
|
||||
virtual ~Pool()=default;
|
||||
_Pool()
|
||||
{
|
||||
max_active_count=0;
|
||||
history_max=0;
|
||||
dlc=&default_dlc;
|
||||
}
|
||||
virtual ~_Pool()=default;
|
||||
|
||||
virtual void PreAlloc(int,bool set_to_max=false); ///<预分配空间
|
||||
virtual void SetDataLifetimeCallback(DataLifetimeCallback<T> *cb) ///<设定数据生命周期回调函数
|
||||
{
|
||||
dlc=cb?cb:&default_dlc;
|
||||
}
|
||||
|
||||
virtual int SetMaxCount(int); ///<设定最大数量限制
|
||||
virtual void PreAlloc(int count,bool set_to_max=false) ///<预分配空间
|
||||
{
|
||||
Active.PreAlloc(count);
|
||||
Inactive.PreAlloc(count);
|
||||
|
||||
virtual bool Acquire(T &); ///<申请一个数据(如果没有空余,创建新的)
|
||||
virtual bool Get(T &); ///<获取一个数据(如果没有空余,返回失败)
|
||||
virtual void Append(T); ///<添加一个数据
|
||||
virtual bool Release(T); ///<释放一个数据
|
||||
virtual int Release(T *,int); ///<释放一批数据
|
||||
virtual int ReleaseAll(); ///<释放所有数据
|
||||
if(set_to_max)
|
||||
max_active_count=count;
|
||||
}
|
||||
|
||||
bool IsActive(const T &data)const{return Active.IsExist(data);}
|
||||
bool IsInactive(const T &data)const{return Inactive.IsExist(data);}
|
||||
virtual void SetMaxActiveCount(int mc){max_active_count=mc;} ///<设定最大活跃数量限制
|
||||
|
||||
virtual void ClearActive(); ///<清除所有活跃的
|
||||
virtual void ClearInactive(); ///<清除所有空闲的
|
||||
virtual void ClearAll(); ///<清除所有的
|
||||
};//template<typename T> class Pool
|
||||
virtual bool Create(T &value) ///<创建一个数据,并放置在活跃队列中
|
||||
{
|
||||
if(IsFull())
|
||||
return(false);
|
||||
|
||||
if(!dlc->Create(&value))
|
||||
return(false);
|
||||
|
||||
Active.Add(value);
|
||||
UpdateHistoryMax();
|
||||
return(true);
|
||||
}
|
||||
|
||||
virtual bool GetOrCreate(T &value) ///<获取一个数据(如果没有空余,创建新的)
|
||||
{
|
||||
if(!Inactive.Pop(value))
|
||||
{
|
||||
if(IsFull())
|
||||
return(false);
|
||||
|
||||
if(!dlc->Create(&value))
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
dlc->OnActive(&value);
|
||||
}
|
||||
|
||||
Active.Add(value);
|
||||
UpdateHistoryMax();
|
||||
return(true);
|
||||
}
|
||||
|
||||
virtual bool Get(T &value) ///<获取一个数据(如果没有空余,返回失败)
|
||||
{
|
||||
if(!Inactive.Pop(value))
|
||||
return(false);
|
||||
|
||||
dlc->OnActive(&value);
|
||||
|
||||
Active.Add(value);
|
||||
return(true);
|
||||
}
|
||||
|
||||
virtual bool Append(T value) ///<添加一个外部创建的数据入活跃队列
|
||||
{
|
||||
if(IsFull())
|
||||
return(false);
|
||||
|
||||
Active.Add(value);
|
||||
|
||||
UpdateHistoryMax();
|
||||
return(true);
|
||||
}
|
||||
|
||||
virtual bool Release(T value) ///<释放一个数据
|
||||
{
|
||||
int index=Active.Find(value);
|
||||
|
||||
if(index>=0)
|
||||
{
|
||||
Active.Delete(index);
|
||||
|
||||
if(!Inactive.Push(value))
|
||||
return(false);
|
||||
|
||||
dlc->OnIdle(&value);
|
||||
return(true);
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
virtual int Release(T *vl,int count) ///<释放一批数据
|
||||
{
|
||||
if(!vl||count<=0)
|
||||
return(0);
|
||||
|
||||
int result=0;
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
if(Release(vl[i]))
|
||||
++result;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
virtual void ReleaseActive() ///<释放所有活跃数据
|
||||
{
|
||||
dlc->OnIdle(Active.GetData(),Active.GetCount());
|
||||
|
||||
Inactive.Push(Active.GetData(),Active.GetCount());
|
||||
Active.ClearData();
|
||||
}
|
||||
|
||||
virtual void ClearActive()
|
||||
{
|
||||
dlc->Clear(Active.GetData(),Active.GetCount());
|
||||
|
||||
Active.ClearData();
|
||||
}
|
||||
|
||||
virtual void ClearInactive() ///<清除所有非活跃数据
|
||||
{
|
||||
Inactive.Clear(dlc);
|
||||
}
|
||||
};//template<typename T,typename AT,typename IT> class _Pool
|
||||
|
||||
template<typename T> using Pool =_Pool<T, List<T>, Queue<T>, DataLifetimeCallback<T>>; ///<数据池模板
|
||||
|
||||
template<typename T> class ObjectPool:public _Pool<T *, List<T *>, ObjectQueue<T>, DefaultObjectLifetimeCallback<T>> ///<对象池
|
||||
{
|
||||
public:
|
||||
|
||||
using _Pool<T *, List<T *>, ObjectQueue<T>, DefaultObjectLifetimeCallback<T>>::_Pool;
|
||||
|
||||
virtual ~ObjectPool() override
|
||||
{
|
||||
ClearActive();
|
||||
ClearInactive();
|
||||
}
|
||||
};
|
||||
}//namespace hgl
|
||||
#include<hgl/type/Pool.cpp>
|
||||
#endif//HGL_POOL_INCLUDE
|
||||
|
@ -133,9 +133,11 @@ namespace hgl
|
||||
if(dlc)
|
||||
{
|
||||
if(data_array[read_index].GetCount()>read_offset) //还有没读完的,需要清掉
|
||||
dlc->Clear(data_array[read_index].GetData()+read_offset,
|
||||
data_array[read_index].GetCount()-read_offset);
|
||||
|
||||
dlc->Clear(data_array[read_index].GetData()+read_offset,
|
||||
data_array[read_index].GetCount()-read_offset);
|
||||
dlc->Clear(data_array[write_index].GetData(),
|
||||
data_array[write_index].GetCount());
|
||||
}
|
||||
|
||||
data_array[0].Clear();
|
||||
@ -167,17 +169,24 @@ namespace hgl
|
||||
return Queue<T *>::Push(obj);
|
||||
}
|
||||
|
||||
virtual T *Pop()
|
||||
virtual bool Push(T **obj_list,int count)
|
||||
{
|
||||
T *obj;
|
||||
if(!obj_list)return(false);
|
||||
|
||||
if(!Queue<T *>::Pop(obj))
|
||||
return(nullptr);
|
||||
|
||||
return obj;
|
||||
return Queue<T *>::Push(obj_list,count);
|
||||
}
|
||||
|
||||
void Clear(ObjectLifetimeCallback<T> *olc=nullptr)
|
||||
//virtual T *Pop()
|
||||
//{
|
||||
// T *obj;
|
||||
|
||||
// if(!Queue<T *>::Pop(obj))
|
||||
// return(nullptr);
|
||||
|
||||
// return obj;
|
||||
//}
|
||||
|
||||
void Clear(DataLifetimeCallback<T *> *olc=nullptr)
|
||||
{
|
||||
if(!olc)
|
||||
olc=&default_olc;
|
||||
@ -185,7 +194,7 @@ namespace hgl
|
||||
Queue<T *>::Clear(olc);
|
||||
}
|
||||
|
||||
void Free(ObjectLifetimeCallback<T> *olc=nullptr)
|
||||
void Free(DataLifetimeCallback<T *> *olc=nullptr)
|
||||
{
|
||||
ObjectQueue<T>::Clear(olc);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user