added a newly data class that it's DataChain
This commit is contained in:
parent
182f307541
commit
acd28db2b8
93
inc/hgl/type/DataChain.h
Normal file
93
inc/hgl/type/DataChain.h
Normal file
@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
|
||||
#include<hgl/type/DataStackPool.h>
|
||||
#include<hgl/type/SortedSets.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 数据链管理器(注:它只管理这个链,并不管理数据)<br>
|
||||
* 它的思想是将空间分配成一个个固定长度的单位,然后通过链表来管理这些单位的使用情况。
|
||||
* 当用户释放一个空间时,会自动合并相邻的空间节点。如果没有相邻的空间节点,会自动创建一个新的空间节点。
|
||||
* 当用户申请一个新的空间时,会自动查找最适合的空间节点。
|
||||
*/
|
||||
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<UserNode> ud_pool; ///<用户数据占用信息池
|
||||
|
||||
SortedSets<UserNode *> 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<ChainNode> 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
|
@ -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}
|
||||
|
216
src/Type/DataChain.cpp
Normal file
216
src/Type/DataChain.cpp
Normal file
@ -0,0 +1,216 @@
|
||||
#include<hgl/type/DataChain.h>
|
||||
|
||||
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->start<ud_end
|
||||
{
|
||||
if(next->start>=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
|
Loading…
x
Reference in New Issue
Block a user