Лень выселения на картах Гуавы - PullRequest
4 голосов
/ 05 мая 2011

Текущий алгоритм выселения для карт довольно ленив. Похоже, объекты с истекшим сроком действия удаляются только при обращении к структуре данных.

Например, сопоставление адресов с индексаторами, определенное как:

ConcurrentMap<Address, Indexer> indexers = new MapMaker()
  .expireAfterAccess( EXPIRATION, TimeUnit.SECONDS)
  .evictionListener( new IndexEvicted())
  .makeMap();

приводит к довольно удивительной закономерности: в то время как containsKey() для данного адреса возвращает false, сразу после того, как этот индексатор для этого адреса выселен.

Каков будет рекомендуемый подход, чтобы сделать процесс очистки более оперативным? То есть удалить объекты, близкие к фактическому времени истечения.

Обновление: Я бы хотел уточнить, что я имею в виду в режиме реального времени. Для приведенного выше примера, EXPIRATION составляет 10 секунд, я бы хотел, чтобы вставленный объект выселился через 10 секунд после последнего доступа. Этого сейчас не происходит - карту нужно использовать как-то, чтобы начать выселение. Если карта полностью не используется, объект может оставаться там годами.

Ответы [ 3 ]

4 голосов
/ 05 мая 2011

Для своевременного выселения в Гуаве необходимо реализовать какой-либо фоновый поток или выполнить повторяющуюся по времени задачу.Это сделало бы карту более тяжелой и трудной для использования в таких средах, как J2EE или в средах, где политика безопасности предотвращает порождение потоков по воле случая.

Если вы заботитесь о своевременном выселении, настройте свое время.поток, который касается карты.

С другой стороны, я согласен, что было бы неплохо иметь выселение, запускаемое сборщиком мусора ... например, с помощью SoftReference и финализатора.(Да, я знаю, что финализаторы в основном злые, я просто предлагаю дополнительную стратегию последней инстанции.)

2 голосов
/ 05 мая 2011

В дополнение к expireAfterAccess существует метод expireAfterWrite.Это, вероятно, соответствует требованиям.

С javadoc :

Указывает, что каждая запись должна автоматически удаляться с карты, как только по истечении фиксированной продолжительности с момента записисоздание или замена.Обратите внимание, что при изменении значения записи будет сброшено время ее истечения.

Примечание: и expireAfterAccess, и expireAfterWrite - это "в реальном времени", просто один из элементов истекает на основе их последнеговремя записи, другое основано на времени последнего доступа.

1 голос
/ 28 мая 2011

Хотя ответ Дилума имеет больше смысла, также обратите внимание, что касание структуры данных с автоматическим удалением , а не обязательно изгонит все просроченные записи.Срок действия истекает в сравнительно небольших пакетах, и поэтому, если у вас есть большое количество одновременных истечений, вам может потребоваться коснуться структуры данных несколько раз.К сожалению, я не думаю, что есть простой программный способ сделать это надежно.

...