9

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

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

4

3 回答 3

10

由于二进制文件是只读的,我可以考虑以下方法(假设您预计更改率很高):

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

我的建议是使用“绳索”结构。基本上是一个树状结构,通常是一个张开或手指树,您只允许更改树的一部分。以正确的方式执行此操作可以让您拥有两全其美:不变性和快速更新。

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

另一种方法是使用 ets 作为可变数组。对于那种事情来说,它是相当快的。

第三种选择是使用空间树结构来表示您的世界。八叉树或类似 BSP 的结构是我盲目追求的东西。

于 2011-08-16T13:46:34.410 回答
0

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

于 2011-08-15T23:55:03.443 回答