0

我正在用 C++ 编写一个共享库,并且(主要是教育性的)目标是让库完成的每一点堆分配都生活在一个连续的块中,在库的特定部分初始化时分配。我在开始时用一个实现了这一点malloc,它实现了两个堆栈(一个大且不可弹出用于持久内存,一个具有额外的机器作为辅助运行时堆栈)和一个用于半持久数据的二进制伙伴系统。

鉴于这种自我强加的约束,在这变成 XY 情况之前,我将描述我要解决的问题。我的图书馆有这些项目,可以有一些属性、结构,比如AB. 我有更多类似 ECS 的数据扁平化,而不是具有单独继承的 OO 方法。项目只是 id,我记账谁在单独的数组中拥有每个属性。所以,如果我有 5 个项目,也许 {1, 3, 4, 5} 有属性 A 而 {2, 3, 4} 有属性 B,代码可能看起来像:

struct A;
struct B;

int whoHasA[] = {1,  3,  4,  5,  0};
A propertyA[] = {A1, A3, A4, A5, A::null()};

int whoHasB[] = {2,  3,  4,  0};
B propertyB[] = {B2, B3, B4, B::null()};

这些数组都可以按照我的约束进行分配,通过给它们一个固定的大小并通过空终止来“动态地”改变程序相关的大小,如数组中所示(我意识到这只是稀疏的临时实现数组。我喜欢它,因为我知道编写程序时的大小)。现在,我的库需要的功能如下。我希望我的用户能够创建项目实例(最多为某个最大数量),并在事后添加/删除属性。

为此,我希望我的用户按名称而不是繁琐的 id 来引用项目。然后我需要在我的 API 中公开以下函数

void CreateItem(const char* name);               //Store item name in a registry
void GiveProperty(const char* name, A property); //Append item's id to whoHasA and property to propertyA
void GiveProperty(const char* name, B property); //Append item's id to whoHasB and property to propertyB

我需要将名称存储在内存中,因为我想向脚本(当前是 Lua)公开类似的功能。想到的解决方案是某种关联映射,将字符串作为键,将项目 ID 作为值。std::unordered_map由于它在地图本身和std::string作为键的动态分配,我一直在避免。目前我正在做的就是定义一个const char** itemNames写入CreateItem的对象,并通过它们进行基本的线性搜索,charchar每个条目上进行比较。我没有对它进行基准测试,也不认为它会特别麻烦,但我问这个问题是希望有一个更优雅的解决方案,它更适合并且(理论上)更有效。

4

1 回答 1

0

一个可以查看的地方(作为模型)是基于文件的哈希图。一方面,将所有内容放在文件中意味着单个线性块(尽管在磁盘上),并处理将结构序列化到该块中。使用 mmap() 的实现将更接近我猜你想要构建的。

您可能想查看 Litwin 的线性哈希表,它会逐渐增长(单个哈希块)。

于 2021-09-04T16:01:10.817 回答