Как реализовать канонизирующее отображение в Java?

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

Мой текущий подход заключается в использовании HashMap<Object, WeakReference<Object>>, Ключ является первичным ключом сопоставленного объекта базы данных (ArrayList<Object> если это составной ключ), а значения WeakReference<Object>,

Моя главная проблема - как почистить карту? Когда объект больше не используется, слабая ссылка на карте уйдет null, и я обнаружу это только при следующем поиске (или никогда, если я не посмотрю объект снова). Я мог бы сделать регистр слабых ссылок с ReferenceQueue когда они очищаются, а затем проверяют эту очередь каждый раз, когда я что-то ищу. Очищенная ссылка не дала бы мне никакого намека на то, какой объект был очищен, поэтому, я думаю, мне придется подкласс WeakReference сохранить ключ на карте, чтобы я мог удалить его после очистки ссылки.

Это путь, или есть какой-то более простой способ реализовать это?

1 ответ

Решение

Я бы порекомендовал использовать MapMaker от Guava или CacheBuilder в r10.

Они допускают автоматическое * выселение по времени и размеру, а также поддерживают слабые ключи или значения. (Предстоящий CacheBuilder обещает быть специально адаптированным для такого случая использования.)

Таким образом, вы можете инициализировать вашу карту:

ConcurrentMap<Key, Object> cache = new MapMaker()
        .weakValues()
        .makeMap();

И немедленная выгода будет в том, что при сборе значения вся запись будет удалена. Кроме того, вы можете использовать компьютерную карту:

ConcurrentMap<Key, Object> cache = new MapMaker()
        .weakValues()
        .makeComputingMap(loadFunction);

где loadFunction это Function<Key, Object> который загружает объект из базы данных. Преимущество этого состоит в том, что карта будет обрабатывать параллельные запросы для определенного объекта, гарантируя, что запрос вызывается только один раз. Кроме того, запрашивающему коду нужно только позвонить get() и всегда может ожидать возвращения объекта, будь то из кэша или базы данных.

Эти примеры используют MapMaker - Я не имел удовольствия играть с CacheBuilder еще.

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

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