さまざまなアクターが同時に同じグラフの一部を作成するソフトを書いています。
グラフのノードはクラス階層によってモデル化され、階層の各具象クラスにはコンパニオン オブジェクトがあります。
abstract class Node
class Node1(k1:Node, k2:Node) extends Node
object Node1 {
def apply(k1:Node, k2:Node) = ...
}
class Node2(k1:Node, k2:Node) extends Node
object Node2 {
def apply(k1:Node, k2:Node) = ...
}
...
ここまでは順調ですね。
作成時にノードで構造ハッシュを実行します。つまり、各コンパニオン オブジェクトには、コンストラクター引数でキー設定されたノード インスタンスを格納する HashTable があります。これは、同じサブノードを持つ特定のノード クラスのインスタンスが既に存在することを検出し、新しいインスタンスを作成する代わりにそのインスタンスを返すために使用されます。これにより、メモリの爆発を回避し、一定の時間を要するノードの等価性テスト (グラフ比較ではなく参照比較) を行うことができます。このマップへのアクセスは、scala.concurrent.Lock を使用して保護されています。
しかし問題は、ロックが jvm スレッド レベルで動作し、アクターがどのようにコーディングされているかによって、アクターが独自の jvm スレッドに割り当てられるか、代わりに同じ JVM スレッド内のいくつかの他のアクターとインターリーブされる可能性があることです。構造ハッシュが機能しなくなります (つまり、構造的に同一のノードがいくつか作成され、そのうちの 1 つだけがキャッシュに格納され、構造的等価性が機能しなくなります)。
まず、この構造的ハッシュ アーキテクチャがアクターの共有なしの哲学に反することはわかっていますが、パフォーマンス上の理由から、このハッシュが機能することが本当に必要です (一定時間の等価性により桁違いの改善が得られます)。 jvmスレッドレベルではなくアクターレベルで動作するアクターとの共有リソースの除外?
ノード コンパニオンをアクターにカプセル化して、ファクトリへのアクセスを完全にシーケンシャル化することを考えましたが、これはすべての既存のコードを完全に書き直すことを意味しますが、他のアイデアはありますか?
ありがとう、