WsComponentPool/ECSMemoryPool/memory_pages.h

168 lines
3.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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