访问按键分组的缓存元素

问题描述 投票:1回答:1

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

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

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

java performance caching
1个回答
1
投票

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

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

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

参考文献:

© www.soinside.com 2019 - 2024. All rights reserved.