0

値側がマップまたはセットである記録マップを実装する最良の方法は何ですか?

特定の ID を持ついくつかのデータの複数のバージョンを保存できる、次のようなデータ構造が必要です。

chronicle-map: String -> Map<String,V>
$id -> {v0-> value-v0, v1-> value-v1, v2 -> value-v2}

または場合によっては 2 つのマップ:

chronicle-map-1: String -> Set<String>
key-$id -> Set{v0,v1,v2}

chronicle-map-2: String -> V
version-$id-v0 -> value-v0
version-$id-v1 -> value-v1
version-$id-v2 -> value-v2

(原子性とシリアライゼーションのパフォーマンスが私の主な関心事です)。acquireUsingLocked/getUsingLockedメソッドは、標準のマップ/セットの実装では機能しないようです。

4

1 に答える 1

1
  1. Chronicle Map 3.x に切り替えることをお勧めします。このバージョンでは、「ネイティブ」をサポートするように進化する新しい堅実なパターンと抽象化のセットが定義されているためMultimapです。

【以下、クロニクルマップ3.xについて】

  1. 原子性 (スレッドセーフ) を確保するには、次のいずれかを実行できます。

    • Java 8 の新しい Map メソッドを使用します: compute()computeIfAbsent()computeIfPresent()またはmerge()次のようなメソッド:

      static <K, V> void multiMapAdd(ChronicleMap<K, Set<V>> map, K key, V value) {
          map.compute(key, (k, v) -> {
              if (v == null)
                  v = new HashSet<>();
              v.add(value);
              return v;
          });
      }
      
    • おそらくシリアライゼーション/デシリアライゼーションのコストを最適化するために、コンテキストを取得し、値のバイトで操作します。例)

      interface LimitedSet {
          public static final int MAX_VALUES_SIZE = 20;
      
          byte getSize();
          void setSize(byte);
      
          MyValue getValue(int index);
          void setValue(@MaxSize(MAX_VALUES_SIZE) int index, MyValue value);
      }
      
      ...
      try (ExternalMapQueryContext<K, LimitedSet, ?> cxt = map.queryContext(key) {
          cxt.writeLock().lock();
          MapEntry<K, LimitedSet> entry = cxt.entry();
          if (entry == null) {
              MapAbsentEntry<K, LimitedSet> absentEntry = cxt.absentEntry();
              cxt.insert(absentEntry, absentEntry.defaultValue());
              entry = cxt.entry();
              assert entry != null;
          }
          LimitedSet values = entry.value().get();
          int size = values.getSize();
          for (int i = 0; i < size; i++) {
              if (same(values.getValue(i), value))
                  return false;
          }
          if (size == MAX_VALUES_SIZE)
              throw new IllegalStateException("values set overflow");
          values.set(size, value);
          values.setSize((byte) (size + 1));
      }
      

      また、Chronicle Map README には、CRDT レプリケーションやマルチエントリ ロックなどの追加機能を明らかにする Chronicle Map の高度な「MultiMap」使用法がいくつか記載されています。

于 2015-08-17T21:01:38.653 に答える