From cc1653fca67c6a9b81c5f1c1bb03bb49d3d4d539 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Wed, 20 Mar 2024 02:17:56 +0800 Subject: [PATCH] added DataBlockTest.cpp, it can't run. --- CMakeLists.txt | 3 + datatype/DataBlockTest.cpp | 202 +++++++++++++++++++++++++++++++++++++ 2 files changed, 205 insertions(+) create mode 100644 datatype/DataBlockTest.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index be32316..1cc34dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,9 @@ set_example_project_folder("DataType/DataArray" PoolTest) add_executable(MapTest datatype/MapTest.cpp) set_example_project_folder("DataType/DataArray" MapTest) +add_executable(DataBlockTest datatype/DataBlockTest.cpp) +set_example_project_folder("DataType/DataArray" DataBlockTest) + #################################################################################################### add_executable(1_ActiveIDManagerTest datatype/ActiveIDManagerTest.cpp) diff --git a/datatype/DataBlockTest.cpp b/datatype/DataBlockTest.cpp new file mode 100644 index 0000000..f089937 --- /dev/null +++ b/datatype/DataBlockTest.cpp @@ -0,0 +1,202 @@ +#include +#include +#include +#include +#include + +using namespace std; +using namespace hgl; + +/** + * 数据块管理器 + */ +class DataBlockManager +{ + enum class ErrorCode + { + Success=0, ///<成功 + + AcquireLengthError =-1, ///<申请长度错误 + FreeBlockNotEnough =-2, ///<没有足够的空间 + NotFitSegments =-3, ///<没有合适的数据块 + }; + +private: + + int block_bytes; ///<单个数据块字节数 + int block_count; ///<数据块数量 + uint64 total_bytes; ///<总字节数 + + AbstractMemoryAllocator *allocator; ///<内存分配器 + +private: + + /** + * 用户数据 + */ + struct UserData + { + int bytes; ///<数据长度 + int block_count; ///<占用数据块数量 + int block_start; ///<起始数据块 + };//struct UserData + + /** + * 数据块链表节点 + */ + struct BlockChainNode + { + BlockChainNode *prev; + BlockChainNode *next; + + int start; ///<起始数据块 + int count; ///<数据块数量 + };//struct BlockChainNode + + BlockChainNode *bcn_data; ///<数据块链表节点数据 + Stack bcn_stack; + + int free_block_count; + + BlockChainNode *bcn_start; + BlockChainNode *bcn_end; + + + List user_data_list; + +private: + + DataBlockManager(AbstractMemoryAllocator *aba,const int bs,const int bc) + { + allocator=aba; + + block_bytes=bs; + block_count=bc; + total_bytes=block_bytes*block_count; + + free_block_count=block_count; + + bcn_data=new BlockChainNode[block_count]; + { + BlockChainNode *p=bcn_data; + + for(int i=0;iprev=nullptr; + bcn_start->next=nullptr; + bcn_start->start=0; + bcn_start->count=block_count; + + bcn_end=bcn_start; + } + +protected: + + const int GetBlockBytes ()const{return block_bytes;} ///<取得单个数据块字节数 + const int GetBlockMaxCount()const{return block_count;} ///<取得数据块最大数量 + const uint64 GetTotalBytes ()const{return total_bytes;} ///<取得总字节数 + + const int GetFreeBlockCount()const{return free_block_count;} ///<取得剩余可用数据块数量总合(注:不代表直接申请这么大的块能成功) + +public: + + virtual ~DataBlockManager() + { + delete[] bcn_data; + SAFE_CLEAR(allocator); + } + + /** + * 请求数据块 + * @param acquire_bytes 请求的字节数 + * @param start_block 返回的起始数据块 + */ + ErrorCode Acquire(const int acquire_bytes,int *start_block) + { + if(acquire_bytes<=0) + return ErrorCode::AcquireLengthError; + + UserData ud; + + ud.bytes=acquire_bytes; + ud.block_count=(acquire_bytes+block_bytes-1)/block_bytes; + + if(ud.block_count>free_block_count) + return ErrorCode::FreeBlockNotEnough; + + if(bcn_start==bcn_end) //链接中只有一个节点,那就是空的了 + { + free_block_count-=ud.block_count; + + bcn_start->start=ud.block_count; + bcn_start->count=free_block_count; + + ud.block_start=0; + + user_data_list.Add(ud); + + *start_block=0; + return ErrorCode::Success; + } + + BlockChainNode *bcn=bcn_start; + BlockChainNode *fit=nullptr; + + do + { + if(bcn->count==ud.block_count) //正合适 + { + fit=bcn;break; + } + + if(bcn->count>ud.block_count) + { + if(!fit //没有合适的,先记下这个 + ||fit->count>bcn->count) //这个更小,更合适 + fit=bcn; + } + + bcn=bcn->next; + }while(bcn!=bcn_end); + + if(!fit) //没有合适的 + return ErrorCode::NotFitSegments; + + free_block_count-=ud.block_count; + + ud.block_start=fit->start; + + if(fit->count==ud.block_count) //属于正好的,那方便,直接移除这个节点 + { + fit->prev->next=fit->next; + fit->next->prev=fit->prev; + + bcn_stack.Push(fit); //收回这个链表节点 + } + else + { + fit->start+=ud.block_count; + fit->count-=ud.block_count; + } + + user_data_list.Add(ud); + + *start_block=ud.block_start; + return ErrorCode::Success; + } + + ErrorCode Release() + { + } +};//class DataBlockManager + +DataBlockManager *CreateDataBlockManager() +{ +}