编年史地图 - 值数据类型



实现一个历史地图的最佳方法是什么,其中值方是映射或集合?

我需要类似于以下内容的数据结构,我可以在其中存储具有特定 id 的某些数据的多个版本:

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

或者可能是两张地图:

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方法似乎不适用于标准映射/集实现。

  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的高级"MultiMap"用法,它揭示了CRDT复制和多条目锁定等附加功能:

      • 复制的编年史映射的 CRDT 值 -- 仅增长集
      • 无向图

最新更新