diff --git a/datatype/DataBlockTest.cpp b/datatype/DataBlockTest.cpp index 02762b9..a8fbe68 100644 --- a/datatype/DataBlockTest.cpp +++ b/datatype/DataBlockTest.cpp @@ -4,55 +4,11 @@ #include #include +#include"DataChain.h" + using namespace std; using namespace hgl; -template class SerialsPool -{ - T MaxCount; ///<最大数量 - T *Serials; ///<序列数据 - T *EndPointer,*AccessPointer; ///<结束指针,访问指针 - -public: - - Serials(const T &count) - { - MaxCount=count; - Serials=new T[MaxCount]; - EndPointer=Serials+MaxCount; - AccessPointer=EndPointer; - - for(T i=0;i=EndPointer) - return(false); - - *AccessPointer=s; - ++AccessPointer; - - return(true); - } -};//template class Serials /** * 数据块管理器 @@ -70,11 +26,11 @@ class DataBlockManager private: - int block_bytes; ///<单个数据块字节数 - int block_count; ///<数据块数量 - uint64 total_bytes; ///<总字节数 + int block_bytes; ///<单个数据块字节数 + int block_count; ///<数据块数量 + uint64 total_bytes; ///<总字节数 - AbstractMemoryAllocator *allocator; ///<内存分配器 + AbstractMemoryAllocator *allocator; ///<内存分配器 private: diff --git a/datatype/DataChain.h b/datatype/DataChain.h new file mode 100644 index 0000000..35e143d --- /dev/null +++ b/datatype/DataChain.h @@ -0,0 +1,256 @@ +#pragma once + +#include +#include + +namespace hgl +{ + /** + * 数据链管理器(注:它只管理这个链,并不管理数据)
+ * 它的思想是将空间分配成一个个固定长度的单位,然后通过链表来管理这些单位的使用情况。 + * 当用户释放一个空间时,会自动合并相邻的空间节点。如果没有相邻的空间节点,会自动创建一个新的空间节点。 + * 当用户申请一个新的空间时,会自动查找最适合的空间节点。 + */ + class DataChain + { + SeriesInt series; ///<序号池 + + int max_count; ///<最大数量 + + protected: + + /** + * 用户数据占用信息 + */ + struct UserData + { + private: + + int start; ///<起始数据块 + int count; ///<占用数据块数量 + + friend class DataChain; + + public: + + const int GetStart()const{return start;} + const int GetCount()const{return count;} + const int GetEnd()const{return start+count;} + };//struct UserData + + DataStackPool ud_pool; ///<用户数据占用信息池 + + SortedSets ud_set; ///<用户数据占用合集 + + protected: + + /** + * 数据块链表节点 + */ + struct ChainNode + { + ChainNode *prev; + ChainNode *next; + + int start; ///<起始数据块 + int count; ///<数据块数量 + + public: + + const int GetEnd()const{return start+count;} + };//struct ChainNode + + DataStackPool node_pool; ///<链表节点池 + + int free_count; ///<空闲数据块数量 + + ChainNode *start,*end; + + public: + + const int GetMaxCount ()const{return max_count;} + const int GetFreeCount ()const{return free_count;} + + public: + + DataChain(const int mc):series(mc),node_pool(mc),ud_pool(mc) + { + max_count=mc; + free_count=mc; + + ud_set.PreAlloc(mc); + + start=node_pool.Acquire(); + end=start; + + start->prev=nullptr; + start->next=nullptr; + start->start=0; + start->count=max_count; + } + + virtual ~DataChain()=default; + + UserData *Acquire(const int acquire_count) + { + if(acquire_count<=0) + return(nullptr); + + if(acquire_count>free_count) + return(nullptr); + + if(acquire_count>max_count) + return(nullptr); + + if(start==end) + { + free_count-=acquire_count; + + start->start=acquire_count; + start->count=free_count; + + UserData *ud=ud_pool.Acquire(); + + ud->start=0; + ud->count=acquire_count; + + ud_set.Add(ud); + + return(ud); + } + + ChainNode *cn=start; + ChainNode *fit=nullptr; + + do + { + if(cn->count==acquire_count) //长度正合适,那就用这一段 + { + fit=cn; + break; + } + + if(cn->count>acquire_count) //长度够了 + { + if(!fit //没有合适的,先记下这个 + ||fit->count>cn->count) //这个更小,更合适 + fit=cn; + } + + cn=cn->next; + }while(cn!=end); + + if(!fit) //没有合适的 + return(nullptr); + + free_count-=acquire_count; + + UserData *ud=ud_pool.Acquire(); + + ud->start=fit->start; + ud->count=acquire_count; + + ud_set.Add(ud); + + if(fit->count==acquire_count) //正好合适 + { + if(fit->prev) + fit->prev->next=fit->next; + else + start=fit->next; + + if(fit->next) + fit->next->prev=fit->prev; + else + end=fit->prev; + + node_pool.Release(fit); + } + else + { + fit->start+=acquire_count; + fit->count-=acquire_count; + } + + return(ud); + } + + bool Release(UserData *ud) + { + if(!ud) + return(nullptr); + + if(!ud_set.IsMember(ud)) + return(false); + + const int ud_end=ud->GetEnd(); + + ChainNode *cur=start; + ChainNode *next; + int cur_end; + + do + { + cur_end=cur->GetEnd(); + + if(cur_end==ud->start) //接在一起了 + { + cur->count+=ud->count; //count扩充 + + return(true); + } + + next=cur->next; + + if(next) + { + if(next->start==ud_end) //下一个块接着,那就合并 + { + next->count+=ud->count; //count扩充 + next->start-=ud->count; //start前移,理论上==ud->start,调试时检查一下 + + return(true); + } + else + if(next->start>ud_end) //下一个块不接着,但是在后面,那就新建一个节点 + { + ChainNode *new_cn=node_pool.Acquire(); + + new_cn->prev=cur; + new_cn->next=next; + new_cn->start=ud->start; + new_cn->count=ud->count; + + cur->next=new_cn; + next->prev=new_cn; + + return(true); + } + else //next->startprev=cur; + new_cn->next=nullptr; + new_cn->start=ud->start; + new_cn->count=ud->count; + + cur->next=new_cn; + end=new_cn; + + return(true); + } + + cur=next; + }while(cur<=end); + } + };//class DataChain +}//namespace hgl + + +理论上写完了,下一步写编写测试程序