更新内存池接口
This commit is contained in:
parent
54b8dc4b48
commit
3fd47f6bfe
|
|
@ -7,22 +7,110 @@
|
||||||
#include <memory_pages.h>
|
#include <memory_pages.h>
|
||||||
|
|
||||||
template<typename T>
|
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::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.loadFrom(in) } -> std::same_as<void>;
|
||||||
{ t.saveTo(out) } -> 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(); }
|
||||||
|
|
||||||
class ECSMEMORYPOOL_EXPORT ECSMemoryPool{
|
T* dataLock() {
|
||||||
|
return (T*)(MemoryElement::dataLock());
|
||||||
|
}
|
||||||
|
void unlock() {
|
||||||
|
MemoryElement::release();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ECSMEMORYPOOL_EXPORT ECSMemoryPool {
|
||||||
private:
|
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_code,page_ptr> 内存页存储
|
||||||
|
/// </summary>
|
||||||
|
QMultiHash<uint64_t, MemoryPage*> _storage_pages;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ECSMemoryPool();
|
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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,19 @@ MemoryPage::MemoryPage(uint16_t element_size, uint64_t typecode)
|
||||||
pcb.typecode_of_element = 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) {
|
void MemoryPage::accessRecord(uint64_t timepoint_usec) {
|
||||||
std::lock_guard<std::mutex> g(pcb.access_protected);
|
std::lock_guard<std::mutex> g(pcb.access_protected);
|
||||||
pcb.curr_access_usec = timepoint_usec;
|
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);
|
return std::make_pair(pcb.curr_access_usec, pcb.acc_count_per_cycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
ElementControlBlock* MemoryPage::getElementPtr(int index) {
|
ElementControlBlock* MemoryPage::getSlicePtr(int index) {
|
||||||
auto member_cnt = elementCount();
|
auto member_cnt = maxSliceCount();
|
||||||
auto element_size = elementSize();
|
auto element_size = sliceRawSize();
|
||||||
|
|
||||||
ElementControlBlock* element_ptr = nullptr;
|
ElementControlBlock* element_ptr = nullptr;
|
||||||
if (index >= 0 && index < member_cnt) {
|
if (index >= 0 && index < member_cnt) {
|
||||||
|
|
@ -66,19 +79,19 @@ uint64_t MemoryPage::elementTypeCode() const
|
||||||
return pcb.typecode_of_element;
|
return pcb.typecode_of_element;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t MemoryPage::elementSize() const {
|
uint16_t MemoryPage::sliceRawSize() const {
|
||||||
auto data_ptr = const_cast<MemoryPage*>(this);
|
auto data_ptr = const_cast<MemoryPage*>(this);
|
||||||
std::lock_guard<std::mutex> g(data_ptr->pcb.access_protected);
|
std::lock_guard<std::mutex> g(data_ptr->pcb.access_protected);
|
||||||
return pcb.byte_count_per_element;
|
return pcb.byte_count_per_element;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t MemoryPage::elementCount() const {
|
uint16_t MemoryPage::maxSliceCount() const {
|
||||||
uint16_t cnt = sizeof(data_buffer);
|
uint16_t cnt = sizeof(data_buffer);
|
||||||
return cnt / this->elementSize();
|
return cnt / this->sliceRawSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
// element =================================================================
|
// element =================================================================
|
||||||
const uint32_t MemoryElement::buffer_offset = MemoryElement::validOffset();
|
const uint32_t MemoryElement::data_buffer_offset = MemoryElement::validOffset();
|
||||||
|
|
||||||
uint32_t MemoryElement::validOffset()
|
uint32_t MemoryElement::validOffset()
|
||||||
{
|
{
|
||||||
|
|
@ -98,10 +111,10 @@ uint32_t MemoryElement::rawSize(uint32_t data_type_size)
|
||||||
MemoryElement::MemoryElement(ElementControlBlock* access_bind)
|
MemoryElement::MemoryElement(ElementControlBlock* access_bind)
|
||||||
: data_ptr((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;
|
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)
|
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);
|
data_ptr->page_refer->accessRecord(time_usec);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t MemoryElement::isActived() const
|
bool MemoryElement::isActived(ElementControlBlock* refer)
|
||||||
{
|
{
|
||||||
data_ptr->page_refer->lock();
|
refer->page_refer->lock();
|
||||||
auto mark = data_ptr->active_mark;
|
auto mark = refer->refer_count;
|
||||||
data_ptr->page_refer->release();
|
refer->page_refer->release();
|
||||||
return mark;
|
return mark;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryElement::setActive(uint8_t ste)
|
void MemoryElement::referAdd()
|
||||||
{
|
{
|
||||||
data_ptr->page_refer->lock();
|
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();
|
data_ptr->page_refer->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* MemoryElement::dataLock()
|
unsigned char* MemoryElement::dataLock()
|
||||||
{
|
{
|
||||||
data_ptr->page_refer->lock();
|
data_ptr->page_refer->lock();
|
||||||
return ((unsigned char*)data_ptr) + buffer_offset;
|
return ((unsigned char*)data_ptr) + data_buffer_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryElement::release()
|
void MemoryElement::release()
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ class MemoryPage;
|
||||||
/// 内存页访问控制块
|
/// 内存页访问控制块
|
||||||
/// </summary>
|
/// </summary>
|
||||||
struct PageControlBlock {
|
struct PageControlBlock {
|
||||||
uint16_t active_entities_count = 0; // 活跃element数量,决定是否需要卸载
|
uint16_t active_elements_count = 0; // 活跃element数量,决定是否需要卸载
|
||||||
uint16_t byte_count_per_element = 32; // 单个element大小,16的倍数
|
uint16_t byte_count_per_element = 32; // 单个element大小,16的倍数,带ElementControlBlock
|
||||||
uint32_t total_buffer_size = 0; // 可用数据缓冲区大小
|
uint32_t total_buffer_size = 0; // 可用数据缓冲区大小
|
||||||
|
|
||||||
uint64_t typecode_of_element = 0; // 元素类型标识码
|
uint64_t typecode_of_element = 0; // 元素类型标识码
|
||||||
|
|
@ -25,9 +25,9 @@ struct PageControlBlock {
|
||||||
/// 元素访问控制块
|
/// 元素访问控制块
|
||||||
/// </summary>
|
/// </summary>
|
||||||
struct ElementControlBlock {
|
struct ElementControlBlock {
|
||||||
uint8_t active_mark = 0; // 活跃标志
|
uint32_t refer_count = 0; // 外部元素的引用数量,活跃标志
|
||||||
uint8_t backup_1 = 0;
|
|
||||||
uint16_t element_index = 0; // 本元素在Page中的索引
|
uint16_t element_index = 0; // 本元素在Page中的索引
|
||||||
|
uint16_t backup_1 = 0;
|
||||||
|
|
||||||
MemoryPage* page_refer = nullptr; // 页面关联指针
|
MemoryPage* page_refer = nullptr; // 页面关联指针
|
||||||
void* extend_bind = nullptr; // 绑定控制块内存指针
|
void* extend_bind = nullptr; // 绑定控制块内存指针
|
||||||
|
|
@ -50,6 +50,19 @@ public:
|
||||||
/// <param name="raw_esize_16B">原始element尺寸</param>
|
/// <param name="raw_esize_16B">原始element尺寸</param>
|
||||||
explicit MemoryPage(uint16_t raw_esize_16B, uint64_t typecode);
|
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>
|
||||||
/// 记录单次访问时间
|
/// 记录单次访问时间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -81,7 +94,7 @@ public:
|
||||||
/// <param name="index">元素索引</param>
|
/// <param name="index">元素索引</param>
|
||||||
/// <param name="active_set">是否设置</param>
|
/// <param name="active_set">是否设置</param>
|
||||||
/// <returns>数据指针</returns>
|
/// <returns>数据指针</returns>
|
||||||
ElementControlBlock* getElementPtr(int index);
|
ElementControlBlock* getSlicePtr(int index);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 元素类型码
|
/// 元素类型码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -91,12 +104,12 @@ public:
|
||||||
/// 获取单个元素尺寸
|
/// 获取单个元素尺寸
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>字节数量</returns>
|
/// <returns>字节数量</returns>
|
||||||
uint16_t elementSize() const;
|
uint16_t sliceRawSize() const;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取元素数量
|
/// 获取元素数量
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
uint16_t elementCount() const;
|
uint16_t maxSliceCount() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -105,9 +118,9 @@ public:
|
||||||
class MemoryElement {
|
class MemoryElement {
|
||||||
private:
|
private:
|
||||||
ElementControlBlock* const data_ptr;
|
ElementControlBlock* const data_ptr;
|
||||||
static const uint32_t buffer_offset;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const uint32_t data_buffer_offset;
|
||||||
static uint32_t validOffset();
|
static uint32_t validOffset();
|
||||||
static uint32_t rawSize(uint32_t data_type_size);
|
static uint32_t rawSize(uint32_t data_type_size);
|
||||||
|
|
||||||
|
|
@ -121,7 +134,7 @@ public:
|
||||||
/// 提取关联元素尺寸
|
/// 提取关联元素尺寸
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
uint32_t typeSize() const;
|
uint16_t typeSize() const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新最终访问时间
|
/// 更新最终访问时间
|
||||||
|
|
@ -133,12 +146,17 @@ public:
|
||||||
/// 数据活跃状态
|
/// 数据活跃状态
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
uint8_t isActived() const;
|
static bool isActived(ElementControlBlock *refer);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置数据活跃状态
|
/// 设置数据活跃状态
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ste"></param>
|
/// <param name="ste"></param>
|
||||||
void setActive(uint8_t ste);
|
void referAdd();
|
||||||
|
/// <summary>
|
||||||
|
/// 设置数据活跃状态
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ste"></param>
|
||||||
|
void referSub();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 锁定数据,返回数据存储内存指针
|
/// 锁定数据,返回数据存储内存指针
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue