9

Erlang で単純な Minecraft サーバー アプリケーションを作成しているので、チャンク データを効率的に保存および変更する方法について考えています。Minecraft の内部構造を知らない人のために: 最大 32kB のサイズの大量のバイナリ (100-1000) をメモリに格納する必要があります。ここまでは、Erlang の組み込みバイナリで十分です。しかし、サーバーはこれらのバイナリのいくつかのバイトを (ID によって) かなり頻繁に読み取って変更する必要があり、常にそれらをコピーしたくありません。
あると便利な機能は、Erlang の標準バイナリからのインポートとエクスポートです。

Erlang 拡張機能やデータベース、またはこれに使用できるものはありますか?

4

3 に答える 3

10

バイナリは読み取り専用であるため、次のアプローチを考えることができます (変更率が高いことが予想される場合)。

  1. リーフ内の比較的小さな不変のバイナリで、ツリーのような構造を使用します。その場合、データを変更するときは、小さなリーフ バイナリ + ルートまでのすべてのノードを再作成するだけで済みます。変更が特定の位置に対して「ローカル」であると仮定すると、octo-tree から始めることができると思います。
  2. 「大きな」バイナリ + 変更のリスト (関数の単純なリストなど) を使用します。世界を変更する必要がある場合は、リストに新しい機能を追加するだけです。誰かが世界の状態を尋ねたら、ベース バイナリを取得し、リストからすべての変更を適用します。時々、すべての変更を「押しつぶし」、新しいベースライン状態のバイナリを準備します。これは、以前のアプローチ (リーフのバイナリ/変更のペアを持つツリー) と組み合わせることができます。
  3. 可変ワールド管理を外部コードに移動します。NIFまたはポートを使用できます。それが最速の方法だと思います。また、実装も比較的容易だと思います。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 を変更可能な配列として使用することです。その種のものはかなり速いです。

3 番目のオプションは、空間ツリー構造を使用して世界を表現することです。オクトリーまたは BSP のような構造は、やみくもに手に入れたいものです。

于 2011-08-16T13:46:34.410 に答える
0

1000 の 32kb バイナリは大したことではありません。あなたはいくつかのバイトを変更すると言いますか?バイナリに含めることができる、または頻繁に変更されるさまざまな部分の記録を作成した方がよいかもしれません。そうすれば、他の部分をコピーせずにバイナリの一部を変更できます。ets を使用すると、gc されるのを待っている大量のバイナリ コピーについて心配する必要はありません。それはまだコピーを作成し、まだ gc されていますが、プロセスと同じ方法ではありません。fullsweep_after オプションを使用して、プロセスのクリーンアップをより頻繁に行うこともできます。

于 2011-08-15T23:55:03.443 に答える