Лучший способ удалить запись кэша на основе предиката в Infispan?

Я хочу удалить несколько записей кэша, если ключ в кэше соответствует некоторому шаблону.

Например, у меня есть следующая пара ключ-значение в кеше,

("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);

Есть ли лучший способ сделать это в Infispan (может быть, используя API или кеш-поток потока)?

1 ответ

Решение

Метод removeIf для entrySet должен работать просто отлично. Это будет довольно медленно, хотя для распределенного кэша, так как он будет опускать каждую запись в кэше и оценивать предикат локально, а затем выполнять удаление для каждой соответствующей записи. Даже в реплицированном кеше он все равно должен выполнять все вызовы удаления (хотя бы итератор будет локальным). Этот метод может быть изменен в будущем, так как мы уже обновляем методы Map [a].

Другой вариант - вместо этого использовать функциональный API, как вы сказали [1]. К сожалению, способ, которым это реализовано, заключается в том, что он все равно сначала извлекает все записи локально. Это может быть изменено позже, если API функциональной карты станут более популярными.

Еще одним вариантом является API потока кеша, который может быть немного более громоздким в использовании, но обеспечит вам наилучшую производительность из всех вариантов. Рад, что вы упомянули об этом:) Я бы порекомендовал сначала применить любые промежуточные операции (к счастью, в вашем случае вы можете использовать фильтр, поскольку ваши ключи не будут меняться одновременно). Затем используйте операцию терминала forEach, которая передает Cache на этом узле [2] (обратите внимание, что это переопределение). Внутри вызова forEach вы можете вызывать команду удаления так, как вам нужно.

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] https://issues.jboss.org/browse/ISPN-5728

[1] https://docs.jboss.org/infinispan/9.0/apidocs/org/infinispan/commons/api/functional/FunctionalMap.ReadWriteMap.html

[2] https://docs.jboss.org/infinispan/9.0/apidocs/org/infinispan/CacheStream.html

Другие вопросы по тегам