2015-04-23 68 views
0

實現編年圖的最佳方式是價值面是地圖還是集合?編年史圖 - 價值數據類型

我需要下,我可以存儲一些數據的多個版本與特定的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
  1. 你當然應該做的事情是切換到紀事地圖3.x的,因爲這個版本定義了新的,堅實的一套模式和抽象,將發展以支持「本土」 Multimap有時。

[下列問候紀事地圖3.X]

  • 爲了確保原子(線程安全),則既可以:

    • 使用Java 8的新地圖的方法: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)); 
      } 
      

      你也可以找到紀事地圖README一對夫婦紀事地圖,揭示額外的能力作爲CRDT複製和多進入鎖定,這種先進的「多重映射」用法:

  • +0

    感謝您的詳細解答。 – fitifiti