From acd28db2b8305f618c9f07d5fba88acf2dfcd671 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Sun, 24 Mar 2024 02:40:08 +0800 Subject: [PATCH] added a newly data class that it's DataChain --- inc/hgl/type/DataChain.h | 93 +++++++++++++++++ src/CMakeLists.txt | 17 ++- src/Type/DataChain.cpp | 216 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 321 insertions(+), 5 deletions(-) create mode 100644 inc/hgl/type/DataChain.h create mode 100644 src/Type/DataChain.cpp diff --git a/inc/hgl/type/DataChain.h b/inc/hgl/type/DataChain.h new file mode 100644 index 0000000..53b8a37 --- /dev/null +++ b/inc/hgl/type/DataChain.h @@ -0,0 +1,93 @@ +#pragma once + +#include +#include + +namespace hgl +{ + /** + * 数据链管理器(注:它只管理这个链,并不管理数据)
+ * 它的思想是将空间分配成一个个固定长度的单位,然后通过链表来管理这些单位的使用情况。 + * 当用户释放一个空间时,会自动合并相邻的空间节点。如果没有相邻的空间节点,会自动创建一个新的空间节点。 + * 当用户申请一个新的空间时,会自动查找最适合的空间节点。 + */ + class DataChain + { + SeriesInt series; ///<序号池 + + int max_count; ///<最大数量 + + public: + + /** + * 用户数据节点信息 + */ + struct UserNode + { + 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 UserNode + + protected: + + DataStackPool ud_pool; ///<用户数据占用信息池 + + SortedSets ud_set; ///<用户数据占用合集 + + #ifdef _DEBUG + public: + #else + protected: + #endif// + + /** + * 数据块链表节点 + */ + 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;} + + #ifdef _DEBUG + ChainNode *GetStartNode()const{return start;} + ChainNode *GetEndNode ()const{return end;} + #endif// + + public: + + DataChain(const int mc); + virtual ~DataChain()=default; + + UserNode *Acquire(const int acquire_count); ///<请求一个数据区块 + bool Release(UserNode *ud); ///<释放一个数据区块 + };//class DataChain +}//namespace hgl diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b379e69..ba9a664 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,12 +15,15 @@ SET(CORE_PLATFORM_HEADER_FILES ${CORE_PLATFORM_HEADER_FILES} SET(TYPE_INCLUDE_PATH ${CMCORE_ROOT_INCLUDE_PATH}/hgl/type) -file(GLOB TYPE_TEMPLATE_HEADER ${TYPE_INCLUDE_PATH}/*.h) +SET(TYPE_COLLECTION_SOURCE ${TYPE_INCLUDE_PATH}/Collection.h + Type/Collection.cpp) + +SOURCE_GROUP("DataType\\Collection" FILES ${TYPE_COLLECTION_SOURCE}) -SET(TYPE_SOURCE_FILES Type/Collection.cpp) +SET(TYPE_DATA_CHAIN_SOURCE ${TYPE_INCLUDE_PATH}/DataChain.h + Type/DataChain.cpp) -SOURCE_GROUP("DataType\\Collection" FILES ${TYPE_INCLUDE_PATH}/Collection.h - ${COLLECTION_SOURCE}) +SOURCE_GROUP("DataType\\DataChain" FILES ${TYPE_DATA_CHAIN_SOURCE}) SET(ACTIVE_MANAGER_FILES ${TYPE_INCLUDE_PATH}/ActiveIDManager.h ${TYPE_INCLUDE_PATH}/ActiveMemoryBlockManager.h @@ -28,6 +31,8 @@ SET(ACTIVE_MANAGER_FILES ${TYPE_INCLUDE_PATH}/ActiveIDManager.h Type/ActiveIDManager.cpp Type/ActiveMemoryBlockManager.cpp) +file(GLOB TYPE_TEMPLATE_HEADER ${TYPE_INCLUDE_PATH}/*.h) + SOURCE_GROUP("DataType\\ActiveManager" FILES ${ACTIVE_MANAGER_FILES}) SET(SYSTEM_INFO_SOURCE ${CORE_PLATFORM_INCLUDE_PATH}/SystemInfo.h @@ -217,13 +222,15 @@ add_cm_library(CMCore "CM" ${CORE_PLATFORM_HEADER_FILES} ${STRING_HEADER_FILES} ${TEXT_HEADER_FILES} ${TEXT_SOURCE_FILES} - ${ACTIVE_MANAGER_FILES} ${TYPE_TEMPLATE_HEADER} ${TYPE_SOURCE_FILES} + ${TYPE_COLLECTION_SOURCE} + ${TYPE_DATA_CHAIN_SOURCE} + ${IO_SOURCE_FILES} ${MATH_HEADER_FILES} diff --git a/src/Type/DataChain.cpp b/src/Type/DataChain.cpp new file mode 100644 index 0000000..729a5f1 --- /dev/null +++ b/src/Type/DataChain.cpp @@ -0,0 +1,216 @@ +#include + +namespace hgl +{ + DataChain::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; + } + + DataChain::UserNode *DataChain::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; + + UserNode *ud=ud_pool.Acquire(); + + ud->start=start->start; + ud->count=acquire_count; + + ud_set.Add(ud); + + start->start+=acquire_count; + start->count=free_count; + + 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; + + UserNode *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 DataChain::Release(DataChain::UserNode *ud) + { + if(!ud) + return(false); + + 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扩充 + + free_count+=ud->count; //空闲数量增加 + ud_set.Delete(ud); + return(true); + } + else if(cur->start==ud_end) //接在一起了 + { + cur->count+=ud->count; + cur->start-=ud->count; + + free_count+=ud->count; //空闲数量增加 + ud_set.Delete(ud); + return(true); + } + + next=cur->next; + + if(next) + { + if(next->start==ud_end) //下一个块接着,那就合并 + { + next->count+=ud->count; //count扩充 + next->start-=ud->count; //start前移,理论上==ud->start,调试时检查一下 + + free_count+=ud->count; //空闲数量增加 + ud_set.Delete(ud); + 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; + + free_count+=ud->count; //空闲数量增加 + ud_set.Delete(ud); + return(true); + } + else //next->startstart>=ud->start) //这个块在中间,那就是出错了 + { + // LOG_ERROR(OS_TEXT("DataChain::Release, block cross.")); + return(false); + } + } + } + else //都没下一个了,那这个就当下一个吧 + { + ChainNode *new_cn=node_pool.Acquire(); + + new_cn->start=ud->start; + new_cn->count=ud->count; + + if(cur==start) //卧槽这是第一个 + { + new_cn->prev=nullptr; + new_cn->next=cur; + + cur->prev=new_cn; + + start=new_cn; + } + else + { + new_cn->prev=cur; + new_cn->next=nullptr; + + cur->next=new_cn; + end=new_cn; + } + + free_count+=ud->count; //空闲数量增加 + ud_set.Delete(ud); + return(true); + } + + cur=next; + }while(cur<=end); + + //未找到?? + return(false); + } +}//namespace hgl