更新内存池接口

This commit is contained in:
codeboss 2025-09-11 22:01:42 +08:00
parent 54b8dc4b48
commit 3fd47f6bfe
3 changed files with 160 additions and 34 deletions

View File

@ -7,22 +7,110 @@
#include <memory_pages.h>
template<typename T>
concept CompenentType = requires(T t, const QJsonObject &in, QJsonObject out){
concept CompenentType = requires(T t, T other, const QJsonObject & in, QJsonObject & out) {
{ T::typeCode() } -> std::same_as<uint64_t>;
{ T::typeSize() } -> std::same_as<uint32_t>;
{ T::typeSize() } -> std::same_as<uint16_t>;
{ t.loadFrom(in) } -> std::same_as<void>;
{ t.saveTo(out) } -> std::same_as<void>;
};
/// <summary>
/// 组件引用符号
/// </summary>
/// <typeparam name="T"></typeparam>
template<typename T> class ComponentRefer : protected MemoryElement {
public:
ComponentRefer(ElementControlBlock* data) : MemoryElement(data) { referAdd(); }
virtual ~ComponentRefer() { referSub(); }
T* dataLock() {
return (T*)(MemoryElement::dataLock());
}
void unlock() {
MemoryElement::release();
}
};
class ECSMEMORYPOOL_EXPORT ECSMemoryPool {
private:
QList<std::shared_ptr<MemoryPage>> _storage_pages;
std::mutex _pool_protected_;
/// <summary>
/// 携带默认参数数据元素组件内存实例
/// </summary>
QHash<uint64_t, std::pair<uint16_t, void*>> _basic_component_memory_example;
/// <summary>
/// map<type_codepage_ptr> 内存页存储
/// </summary>
QMultiHash<uint64_t, MemoryPage*> _storage_pages;
public:
ECSMemoryPool();
template<CompenentType T> void registerComponent() {
/// <summary>
/// 注册携带默认参数的数据组件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="one"></param>
template<CompenentType T> void registerComponent(T one) {
std::lock_guard<std::mutex> lockx(_pool_protected_);
auto ptr = new char[T::typeSize()];
memcpy(ptr, &one, T::typeSize());
// 注册组件数据类型
auto type_code = T::typeCode();
auto type_size = T::typeSize();
_basic_component_memory_example[type_code] = std::make_pair<uint16_t, void*>(type_size, ptr);
}
/// <summary>
/// 创建一个新的数据组件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
template<CompenentType T> ComponentRefer<T> generate() {
std::lock_guard<std::mutex> lockx(_pool_protected_);
auto type_code = T::typeCode();
ElementControlBlock* refer_ptr = nullptr;
// 获取指定类型关联的内存页
QList<MemoryPage*> page_list = _storage_pages.values(type_code);
// 迭代内存页集合
for (auto page_ptr : page_list) {
auto max_element_cnt = page_ptr->maxSliceCount();
auto active_cnt = page_ptr->getActiveCount();
// 初级校核可用数量
if (active_cnt < max_element_cnt) {
// 逐个查找数据元素
for (auto eidx = 0; eidx < max_element_cnt; eidx++) {
auto slice_ptr = page_ptr->getSlicePtr(eidx);
// 访问排他
slice_ptr->page_refer->lock();
// 裁决元素可用性
if (!slice_ptr->refer_count) {
// 元素可用
slice_ptr->refer_count++;
refer_ptr = slice_ptr;
slice_ptr->page_refer->release();
// 跳转到元素重用
goto exists_reuse;
}
else {
slice_ptr->page_refer->release();
}
}
}
}
// 生成新的内存页
auto new_page = new MemoryPage(MemoryElement::rawSize(T::typeSize()), type_code);
_storage_pages->insert(type_code, new_page);
refer_ptr = new_page->getSlicePtr(0);
exists_reuse:
return ComponentRefer<T>(refer_ptr);
}
};

View File

@ -7,6 +7,19 @@ MemoryPage::MemoryPage(uint16_t element_size, uint64_t typecode)
pcb.typecode_of_element = typecode;
}
uint16_t MemoryPage::dataSliceSize() const
{
return pcb.byte_count_per_element - MemoryElement::data_buffer_offset;
}
uint16_t MemoryPage::getActiveCount(uint16_t inc) const
{
auto data_ptr = const_cast<MemoryPage*>(this);
std::lock_guard<std::mutex> g(data_ptr->pcb.access_protected);
data_ptr->pcb.active_elements_count += inc;
return data_ptr->pcb.active_elements_count;
}
void MemoryPage::accessRecord(uint64_t timepoint_usec) {
std::lock_guard<std::mutex> g(pcb.access_protected);
pcb.curr_access_usec = timepoint_usec;
@ -26,9 +39,9 @@ std::pair<uint64_t, uint32_t> MemoryPage::getRecords() const {
return std::make_pair(pcb.curr_access_usec, pcb.acc_count_per_cycle);
}
ElementControlBlock* MemoryPage::getElementPtr(int index) {
auto member_cnt = elementCount();
auto element_size = elementSize();
ElementControlBlock* MemoryPage::getSlicePtr(int index) {
auto member_cnt = maxSliceCount();
auto element_size = sliceRawSize();
ElementControlBlock* element_ptr = nullptr;
if (index >= 0 && index < member_cnt) {
@ -66,19 +79,19 @@ uint64_t MemoryPage::elementTypeCode() const
return pcb.typecode_of_element;
}
uint16_t MemoryPage::elementSize() const {
uint16_t MemoryPage::sliceRawSize() const {
auto data_ptr = const_cast<MemoryPage*>(this);
std::lock_guard<std::mutex> g(data_ptr->pcb.access_protected);
return pcb.byte_count_per_element;
}
uint16_t MemoryPage::elementCount() const {
uint16_t MemoryPage::maxSliceCount() const {
uint16_t cnt = sizeof(data_buffer);
return cnt / this->elementSize();
return cnt / this->sliceRawSize();
}
// element =================================================================
const uint32_t MemoryElement::buffer_offset = MemoryElement::validOffset();
const uint32_t MemoryElement::data_buffer_offset = MemoryElement::validOffset();
uint32_t MemoryElement::validOffset()
{
@ -98,10 +111,10 @@ uint32_t MemoryElement::rawSize(uint32_t data_type_size)
MemoryElement::MemoryElement(ElementControlBlock* access_bind)
: data_ptr((ElementControlBlock*)access_bind) {}
uint32_t MemoryElement::typeSize() const
uint16_t MemoryElement::typeSize() const
{
auto page_ptr = data_ptr->page_refer;
return ((PageControlBlock*)page_ptr)->byte_count_per_element - buffer_offset;
return page_ptr->sliceRawSize();
}
void MemoryElement::accessUpdate(uint64_t time_usec)
@ -109,25 +122,32 @@ void MemoryElement::accessUpdate(uint64_t time_usec)
data_ptr->page_refer->accessRecord(time_usec);
}
uint8_t MemoryElement::isActived() const
bool MemoryElement::isActived(ElementControlBlock* refer)
{
data_ptr->page_refer->lock();
auto mark = data_ptr->active_mark;
data_ptr->page_refer->release();
refer->page_refer->lock();
auto mark = refer->refer_count;
refer->page_refer->release();
return mark;
}
void MemoryElement::setActive(uint8_t ste)
void MemoryElement::referAdd()
{
data_ptr->page_refer->lock();
data_ptr->active_mark = ste;
data_ptr->refer_count++;
data_ptr->page_refer->release();
}
void MemoryElement::referSub()
{
data_ptr->page_refer->lock();
data_ptr->refer_count--;
data_ptr->page_refer->release();
}
unsigned char* MemoryElement::dataLock()
{
data_ptr->page_refer->lock();
return ((unsigned char*)data_ptr) + buffer_offset;
return ((unsigned char*)data_ptr) + data_buffer_offset;
}
void MemoryElement::release()

View File

@ -7,8 +7,8 @@ class MemoryPage;
/// 内存页访问控制块
/// </summary>
struct PageControlBlock {
uint16_t active_entities_count = 0; // 活跃element数量决定是否需要卸载
uint16_t byte_count_per_element = 32; // 单个element大小16的倍数
uint16_t active_elements_count = 0; // 活跃element数量决定是否需要卸载
uint16_t byte_count_per_element = 32; // 单个element大小16的倍数带ElementControlBlock
uint32_t total_buffer_size = 0; // 可用数据缓冲区大小
uint64_t typecode_of_element = 0; // 元素类型标识码
@ -25,9 +25,9 @@ struct PageControlBlock {
/// 元素访问控制块
/// </summary>
struct ElementControlBlock {
uint8_t active_mark = 0; // 活跃标志
uint8_t backup_1 = 0;
uint32_t refer_count = 0; // 外部元素的引用数量,活跃标志
uint16_t element_index = 0; // 本元素在Page中的索引
uint16_t backup_1 = 0;
MemoryPage* page_refer = nullptr; // 页面关联指针
void* extend_bind = nullptr; // 绑定控制块内存指针
@ -50,6 +50,19 @@ public:
/// <param name="raw_esize_16B">原始element尺寸</param>
explicit MemoryPage(uint16_t raw_esize_16B, uint64_t typecode);
/// <summary>
/// 内存存储的数据元素的尺寸
/// </summary>
/// <returns></returns>
uint16_t dataSliceSize() const;
/// <summary>
/// 获取当前活跃元素数量
/// </summary>
/// <param name="inc">变化值</param>
/// <returns>当前元素数量</returns>
uint16_t getActiveCount(uint16_t inc = 0) const;
/// <summary>
/// 记录单次访问时间
/// </summary>
@ -81,7 +94,7 @@ public:
/// <param name="index">元素索引</param>
/// <param name="active_set">是否设置</param>
/// <returns>数据指针</returns>
ElementControlBlock* getElementPtr(int index);
ElementControlBlock* getSlicePtr(int index);
/// <summary>
/// 元素类型码
/// </summary>
@ -91,12 +104,12 @@ public:
/// 获取单个元素尺寸
/// </summary>
/// <returns>字节数量</returns>
uint16_t elementSize() const;
uint16_t sliceRawSize() const;
/// <summary>
/// 获取元素数量
/// </summary>
/// <returns></returns>
uint16_t elementCount() const;
uint16_t maxSliceCount() const;
};
/// <summary>
@ -105,9 +118,9 @@ public:
class MemoryElement {
private:
ElementControlBlock* const data_ptr;
static const uint32_t buffer_offset;
public:
static const uint32_t data_buffer_offset;
static uint32_t validOffset();
static uint32_t rawSize(uint32_t data_type_size);
@ -121,7 +134,7 @@ public:
/// 提取关联元素尺寸
/// </summary>
/// <returns></returns>
uint32_t typeSize() const;
uint16_t typeSize() const;
/// <summary>
/// 更新最终访问时间
@ -133,12 +146,17 @@ public:
/// 数据活跃状态
/// </summary>
/// <returns></returns>
uint8_t isActived() const;
static bool isActived(ElementControlBlock *refer);
/// <summary>
/// 设置数据活跃状态
/// </summary>
/// <param name="ste"></param>
void setActive(uint8_t ste);
void referAdd();
/// <summary>
/// 设置数据活跃状态
/// </summary>
/// <param name="ste"></param>
void referSub();
/// <summary>
/// 锁定数据,返回数据存储内存指针