Caching 在infinispan中删除基于谓词的缓存项的最佳方法?

Caching 在infinispan中删除基于谓词的缓存项的最佳方法?,caching,infinispan,remove-if,infinispan-9,Caching,Infinispan,Remove If,Infinispan 9,如果缓存中的键与某个模式匹配,我想删除几个缓存项 例如,我在缓存中有以下键值对 ("key-1", "value-1"), ("key-2", "value-2"), ("key-3", "value-3"), ("key-4", "value-4") 因为缓存实现了一个映射接口,所以我可以这样做 cache.entrySet().removeIf(entry -> entry.getKey().indexOf("key-") > 0); 在infinispan中是否有更好的方法

如果缓存中的键与某个模式匹配,我想删除几个缓存项

例如,我在缓存中有以下键值对

("key-1", "value-1"), ("key-2", "value-2"), ("key-3", "value-3"), ("key-4", "value-4")
因为缓存实现了一个映射接口,所以我可以这样做

cache.entrySet().removeIf(entry -> entry.getKey().indexOf("key-") > 0);

在infinispan中是否有更好的方法(可能使用函数或缓存流api)?

entrySet上的removeIf方法应该可以正常工作。但对于分布式缓存来说,速度会非常慢,因为它会下拉缓存中的每个条目,在本地计算谓词,然后对匹配的每个条目执行删除。即使在复制缓存中,它仍然必须执行所有的删除调用(至少迭代器是本地的)。由于我们已经在更新Map方法,此方法可能在将来更改[a]

另一种选择是使用函数式API,如您所说[1]。不幸的是,它的实现方式仍然是首先在本地提取所有条目。如果Functional Map API变得更加流行,这一点可能会在以后有所改变

另一个选择是缓存流API,它的使用可能会有点麻烦,但会为您提供所有选项中最好的性能。很高兴您提到了:)我建议您首先应用任何中间操作(幸运的是,您可以使用过滤器,因为您的密钥不会同时更改)。然后使用forEach终端操作传递该节点上的缓存[2](注意这是一个覆盖)。在forEach callable中,您可以根据需要调用remove命令

cache.entrySet().parallelStream() // stream() if you want single thread per node
   .filter(e -> e.getKey().indexOf("key-") > 0)
   .forEach((cache, e) -> cache.remove(e.getKey()));
您也可以使用索引来避免容器的迭代,但我在这里不详细介绍。索引是一个完全不同的野兽

[a]

[1]


[2]

entrySet上的removeIf方法应该可以正常工作。但对于分布式缓存来说,速度会非常慢,因为它会下拉缓存中的每个条目,在本地计算谓词,然后对匹配的每个条目执行删除。即使在复制缓存中,它仍然必须执行所有的删除调用(至少迭代器是本地的)。由于我们已经在更新Map方法,此方法可能在将来更改[a]

另一种选择是使用函数式API,如您所说[1]。不幸的是,它的实现方式仍然是首先在本地提取所有条目。如果Functional Map API变得更加流行,这一点可能会在以后有所改变

另一个选择是缓存流API,它的使用可能会有点麻烦,但会为您提供所有选项中最好的性能。很高兴您提到了:)我建议您首先应用任何中间操作(幸运的是,您可以使用过滤器,因为您的密钥不会同时更改)。然后使用forEach终端操作传递该节点上的缓存[2](注意这是一个覆盖)。在forEach callable中,您可以根据需要调用remove命令

cache.entrySet().parallelStream() // stream() if you want single thread per node
   .filter(e -> e.getKey().indexOf("key-") > 0)
   .forEach((cache, e) -> cache.remove(e.getKey()));
您也可以使用索引来避免容器的迭代,但我在这里不详细介绍。索引是一个完全不同的野兽

[a]

[1]


[2]

感谢您提供了宝贵的答案,我无法使用函数式readwritemap api删除基于evalMany的少量条目。但是您基于缓存流api的解决方案解决了我的问题。感谢您的宝贵回答,我无法使用函数式readwritemap api来删除基于evalMany的少量条目。但基于缓存流api的解决方案解决了我的问题。