【问题标题】:Access to cache elements grouped by key访问按键分组的缓存元素
【发布时间】:2019-06-24 20:29:14
【问题描述】:

我想在 JCS 或 Infinispan 等缓存中使用复合键 (String, int) 缓存大量 Java 对象 (String, byte[])。

键可以通过它的字符串部分(我们称之为ID)进行分组:

KEY = VALUE
-------------
A 1 = valueA1
A 4 = valueA4
A 5 = valueA5
B 9 = valueB9
C 3 = valueC3
C 7 = valueC7

我需要删除按键的 ID 部分分组的元素,例如 A 应该删除 A 1、A 4 和 A 5。

首先我尝试了这样的事情:

   final List<String> keys = cache.keySet()
            .stream().filter(k -> k.getId().equals(id)).collect(Collectors.toList());
    keys.forEach(cache::remove);

虽然这行得通,但它 - 不足为奇 - 非常昂贵,因此速度很慢。

所以我尝试了另一种方法,仅使用 ID 作为键并将值分组到地图中:

KEY = VALUE
---------------------------------------------
  A = {1 = valueA1, 4 = valueA4, 5 = valueA5}
  B = {9 = valueB9}
  C = {3 = valueC3, 7 = valueC7}

然后删除一个组非常有效:

cache.remove(id);

但推杆需要得到:

    Map<Integer, Value> map = cache.get(key.getId());
    if (map == null) {
        map = new HashMap<>();
    }
    map.put(key.getInt(), value);

    cache.put(key.getId(), map);

现在缓存中的元素更少,键更简单,但值更大更复杂。使用缓存中的数十万个元素进行测试,删除速度很快,而 put 和 get 似乎并没有明显变慢。

这是一个有效的解决方案还是有更好的方法?

【问题讨论】:

    标签: java performance caching


    【解决方案1】:

    我建议你使用 computeIfAbsent 并保存一个 put 和 get 调用,如下所示:

    cache.computeIfAbsent(key.getId(), k -> new HashMap<Integer,Value>()).put(key.getInt(),value);
    

    此方法确保仅当辅助映射尚未映射到主映射时才创建辅助映射,并且无需额外的 get 调用,因为它返回映射到主键的辅助映射。

    参考资料:

    【讨论】:

      猜你喜欢
      • 2020-05-03
      • 2017-10-25
      • 2019-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多