编年史地图 - 价值数据类型

时间:2015-04-23 16:52:45

标签: java chronicle chronicle-map

实现编年史地图的最佳方式是什么?价值方面是地图或集合?

我需要类似于以下内容的数据结构,我可以存储具有特定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 个答案:

答案 0 :(得分:1)

  1. 你应该做的事情是切换到Chronicle Map 3.x,因为这个版本定义了一组新的,可靠的模式和抽象,它们将演变为支持&#34; native&#34;有时Multimap
  2. [以下关于Chronicle Map 3.x]

    1. 为确保原子性(线程安全),您可以:

      • 使用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;
            });
        }
        
      • 获取上下文,并使用值字节操作,以优化某些序列化/反序列化成本。 E. g。

        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));
        }
        

        您还可以找到一些这样的高级&#34; MultiMap&#34; Chronicle Map的用法,在Chronicle Map README中显示CRDT复制和多项锁定的其他能力: