#pragma once #include #include "ecsmemorypool_global.h" class MemoryPage; /// /// 内存页访问控制块 /// struct PageControlBlock { 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; // 元素类型标识码 uint64_t curr_access_usec = 0; // 最近访问时间点,lsb:us uint32_t acc_count_per_cycle = 0; // 单周期内累积访问次数 uint32_t backup = 0; std::mutex access_protected; // 内存数据访问保护锁 }; /// /// 元素访问控制块 /// struct ElementControlBlock { uint32_t refer_count = 0; // 外部元素的引用数量,活跃标志 uint16_t element_index = 0; // 本元素在Page中的索引 uint16_t backup_1 = 0; MemoryPage* page_refer = nullptr; // 页面关联指针 void* extend_bind = nullptr; // 绑定控制块内存指针 }; /// /// 内存页面16K大小 /// class ECSMEMORYPOOL_EXPORT MemoryPage { private: PageControlBlock pcb; unsigned char data_buffer[16 * 1024 - (sizeof(PageControlBlock) / 8 + 1) * 8] = {}; public: /// /// 构建内存页 /// /// 原始element尺寸 explicit MemoryPage(uint16_t raw_esize_16B, uint64_t typecode); /// /// 内存存储的数据元素的尺寸 /// /// uint16_t chunkSize() const; /// /// 获取当前活跃元素数量 /// /// 变化值 /// 当前元素数量 uint16_t getActiveCount(uint16_t inc = 0) const; /// /// 记录单次访问时间 /// /// void accessRecord(uint64_t timepoint_usec); /// /// 清除访问次数记录 /// /// 上一周期累积次数 uint32_t timesClear(); /// /// 获取访问记录 /// /// {最近访问时间,累积次数} std::pair getRecords() const; /// /// 加锁,在release之前不能访问本类型任何接口,否则会造成死锁 /// void lock(); /// /// 解锁 /// void release(); /// /// 获取element元素数据访问指针 /// /// 元素索引 /// 是否设置 /// 数据指针 ElementControlBlock* getChunkPtr(int index); /// /// 元素类型码 /// /// uint64_t elementTypeCode() const; /// /// 获取单个元素尺寸 /// /// 字节数量 uint16_t chunkRawSize() const; /// /// 获取元素数量 /// /// uint16_t maxChunkCapacity() const; }; /// /// 内存元素访问接口 /// class ECSMEMORYPOOL_EXPORT MemoryElement { protected: ElementControlBlock* const data_ptr; public: static const uint32_t data_buffer_offset; static uint32_t validOffset(); static uint32_t rawSize(uint32_t data_type_size); /// /// 数据活跃状态 /// /// static bool isActived(ElementControlBlock* refer); /// /// 构建内存元素访问接口 /// /// MemoryElement(ElementControlBlock* access_bind); /// /// 提取关联元素尺寸 /// /// uint16_t typeSize() const; /// /// 更新最终访问时间 /// /// void accessUpdate(uint64_t time_usec); /// /// 设置数据活跃状态 /// /// void referAdd(); /// /// 设置数据活跃状态 /// /// void referSub(); /// /// 锁定数据,返回数据存储内存指针 /// /// unsigned char* dataLock(); /// /// 解锁数据 /// void release(); };