/
NikolayIvkin
/
tutorials1
Обзор
Документация
Войти
/
NikolayIvkin
/
tutorials1
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
data-structures/src/main/java/com/baeldung/lrucache/LRUCache.java
100 строк
3 KB
Arash Ariani
Bael 4464 (#11041)
20 июл 2021, 08:21
20 июл 2021, 08:21
66b40ed
Код
Авторство
О чём код?
package com.baeldung.lrucache; import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantReadWriteLock; public class LRUCache<K, V> implements Cache<K, V> { private int size; private Map<K, LinkedListNode<CacheElement<K, V>>> linkedListNodeMap; private DoublyLinkedList<CacheElement<K, V>> doublyLinkedList; private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public LRUCache(int size) { this.size = size; this.linkedListNodeMap = new ConcurrentHashMap<>(size); this.doublyLinkedList = new DoublyLinkedList<>(); } @Override public boolean put(K key, V value) { this.lock.writeLock().lock(); try { CacheElement<K, V> item = new CacheElement<K, V>(key, value); LinkedListNode<CacheElement<K, V>> newNode; if (this.linkedListNodeMap.containsKey(key)) { LinkedListNode<CacheElement<K, V>> node = this.linkedListNodeMap.get(key); newNode = doublyLinkedList.updateAndMoveToFront(node, item); } else { if (this.size() >= this.size) { this.evictElement(); } newNode = this.doublyLinkedList.add(item); } if (newNode.isEmpty()) { return false; } this.linkedListNodeMap.put(key, newNode); return true; } finally { this.lock.writeLock().unlock(); } } @Override public Optional<V> get(K key) { this.lock.readLock().lock(); try { LinkedListNode<CacheElement<K, V>> linkedListNode = this.linkedListNodeMap.get(key); if (linkedListNode != null && !linkedListNode.isEmpty()) { linkedListNodeMap.put(key, this.doublyLinkedList.moveToFront(linkedListNode)); return Optional.of(linkedListNode.getElement().getValue()); } return Optional.empty(); } finally { this.lock.readLock().unlock(); } } @Override public int size() { this.lock.readLock().lock(); try { return doublyLinkedList.size(); } finally { this.lock.readLock().unlock(); } } @Override public boolean isEmpty() { return size() == 0; } @Override public void clear() { this.lock.writeLock().lock(); try { linkedListNodeMap.clear(); doublyLinkedList.clear(); } finally { this.lock.writeLock().unlock(); } } private boolean evictElement() { this.lock.writeLock().lock(); try { LinkedListNode<CacheElement<K, V>> linkedListNode = doublyLinkedList.removeTail(); if (linkedListNode.isEmpty()) { return false; } linkedListNodeMap.remove(linkedListNode.getElement().getKey()); return true; } finally { this.lock.writeLock().unlock(); } } }