Erlang中的大型可变字节数组

时间:2011-08-15 23:01:07

标签: arrays memory erlang byte minecraft

当我在Erlang中编写一个简单的Minecraft服务器应用程序时,我现在关注如何有效地存储和修改块数据的问题。 对于那些不了解Minecraft内部的人:我需要在内存中存储大量高达32kB的二进制文件(100-1000)。在此之前,Erlang的内置二进制文件就足够了。但是服务器必须经常读取和更改这些二进制文件中的一些字节(通过它们的id),我不想一直复制它们。
一个很好的功能是从/向Erlang的标准二进制文件导入和导出。

是否有任何Erlang扩展或数据库或我可以使用的任何内容?

3 个答案:

答案 0 :(得分:9)

由于二进制文件是只读的,我可以考虑以下方法(假设您期望高变化率):

  1. 在叶子中使用具有相对较小的不可变二进制文件的树状结构。在这种情况下,当您修改数据时,您只需要重新创建小叶二进制+所有节点直到根。假设变化对某个位置是“本地的”,我认为,你可以从octo-tree开始。
  2. 使用“大”二进制文件+更改列表(可以是简单的函数列表)。当您需要修改世界时,只需将新功能添加到列表中即可。当有人要求世界状态时,请使用基本二进制并应用列表中的所有更改。不时“压缩”所有更改并准备新的基线状态二进制文件。这可以与之前的方法结合使用(树叶中具有二元/变化对的树)。
  3. 将可变世界管理移至外部代码。您可以使用NIFsPorts。我想,那将是最快的方式。此外,我认为实施它会相对容易。 API的第一个版本可以像world:new(X, Y, Z) -> ref(); world:get(Ref, X, Y, Z); world:set(Ref, X, Y, Z, Value);
  4. 一样简单

答案 1 :(得分:3)

我的建议是使用“绳索”结构。基本上是一个树状结构,通常是一个splay或finger树,你只允许更改树的部分。以正确的方式执行此操作可以让您充分利用这两个方面:不变性和快速更新。

我不知道绳索实现,但这是你想要做的。

另一种方法是使用ets作为可变数组。这种事情很快。

第三种选择是使用空间树结构来表示您的世界。像盲人一样,我会抓住八角形或类似BSP的结构。

答案 2 :(得分:0)

1000个32kb的二进制文件并不是什么大问题。你说换一些字节?也许如果您只记录二进制文件可以包含的不同部分或经常修改的部分会更好,这样您就可以修改二进制文件的某些部分而无需复制其他部分。使用ets,您不必担心等待gc'ed的一堆二进制副本。它仍然制作副本,它仍然是gc'ed但不是与进程相同的方式。您也可以使用fullsweep_after opt更频繁地进行流程清理。