访问按键分组的缓存元素

时间:2019-01-31 11:26:35

标签: java performance caching

我想在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);

现在,使用简单键的缓存中的元素较少,但是值更大且更复杂。在缓存中对成千上万个元素进行测试时,删除的速度很快,放置和获取的速度似乎没有明显降低。

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

1 个答案:

答案 0 :(得分:1)

我建议你使用computeIfAbsent并保存put和get调用如下:

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

此方法确保仅在主映射中尚未映射时才创建辅助映射,并节省了额外的get调用,因为它返回了映射到主键的辅助映射。

参考文献: