2011-01-18 2 views
3

У меня есть хэш-таблица, которая находится под интенсивным движением. Я хочу добавить механизм тайм-аута в hashtable, удалить слишком старые записи. Мои проблемы: - Он должен быть легким - Устранение операции не имеет критического момента. Я имею в виду (значение тайм-аута составляет 1 час) операция удаления может быть выполнена через 1 час или 1 час 15 минут. Нет проблем.Механизм ожидания для Hashtable

Мое мнение, создать большой массив (как кольцевой буфер), которые хранят поместить время и хеш ключа, При добавлении в хэш-таблицу, используя индекс массива найти следующий слот на массиве поместить время, если слот массива пусты , введите время вставки и клавишу HT, , если слот массива не пуст, сравните время вставки для таймаута.
Если тайм-аут произошел, удалите из Hashtable (если не удалили еще) Не задержите время ожидания, инкрементируйте индекс, чтобы найти пустой слот или слот массива с таймаутом. При удалении из хеш-таблицы на большом массиве нет операции.

Вскоре для каждой операции добавления в Hashtable может удаляться 1 элемент с тайм-аутом из хеш-таблицы или ничего не делать.

Какое у вас более элегантное и легкое решение?

Спасибо за помогает,

ответ

5

Вы должны скорее рассмотреть вопрос об использовании LinkedHashMap или может быть, WeakHashMap.

Первый имеет a constructor, чтобы установить порядок итераций его элементов в порядке последнего доступа; это делает тривиальным удаление слишком старых элементов. И его метод removeEldestEntry можно переопределить, чтобы определить свою собственную политику, когда автоматически удалять старшую запись после вставки новой.

Последний использует слабые ссылки на ключи, поэтому любой ключ, который не имеет к нему никакой ссылки, может автоматически собираться с мусором.

+0

Я планирую добавить временную метку к значению Hashmap и проверить тайм-аут в функции removeEldestEntry.Контроль тайм-аута также просто для проверки% 10 вставки (не для всех). Это дает мне лучшую производительность. Думаю, это лучше для меня :) Спасибо за помощь. –

0

Я думаю, что гораздо проще использовать LRUMap от Apache Commons Collections. Конечно, вы можете писать свои собственные структуры данных, если вам это нравится или вы хотите учиться, но эта проблема настолько распространена, что существует множество готовых решений. (Я уверен, что другие будут указывать вам на другие реализации тоже через некоторое время ваша проблема будет правильно выбрать один из них :))

+0

Есть много операций по удалению и удалению. Как установить емкость LRUMAP? Если я устанавливаю слишком большой элемент с тайм-аутом, он остается навсегда или слишком мал, как бы уверен, что элемент по крайней мере хранится в течение 1 часа на хэш-таблице. –

+0

Я не был уверен, что вам действительно нужно. LRUMap полезен, если вы просто хотите ограничить размер своей карты. Не существует времени истечения срока действия, последняя введенная запись просто удаляется, когда вы пытаетесь вставить новую запись в уже заполненную карту. Емкость может быть задана в конструкторе. Но если вам нужно явно указать время на выход, решение Guava, вероятно, вам нужно. – biziclop

+0

LRUMap ограничен, по-видимому, только по размеру, поэтому это не очень удобно использовать для ограничений по времени. –

8

Мой подход будет использовать GuavaMapMaker:

ConcurrentMap<String, MyValue> graphs = new MapMaker() 
    .maximumSize(100) 
    .expireAfterWrite(1, TimeUnit.HOURS) 
    .makeComputingMap(
     new Function<String, MyValue>() { 
     public MyValue apply(String string) { 
      return calculateMyValue(string); 
     } 
     }); 

Это может быть не точно то, что вы описываете, но, скорее всего, это достаточно близко. И это намного проще в производстве (плюс использование хорошо протестированной базы кода).

Обратите внимание, что вы можете настроить поведение получаемого Map, вызвав различные методы перед вызовом make*().

+0

MapMaker также доступен в Коллекциях Google. –

+0

@Suresh - google collections теперь находится в guava –

+0

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

0

В предположении, что в настоящее время наиболее сильно доступные элементы в структуре вашего кэша находятся в значительном меньшинстве, вы можете обойтись случайным выбором элементов для удаления (у вас есть низкая вероятность удаления чего-то очень полезного). Я использовал этот метод, и в этом конкретном приложении он работал очень хорошо и не выполнял никаких усилий по внедрению.

Смежные вопросы