From 66b40ed662f87fc8ddf68ee1cb0c2585c9ae1a3c Mon Sep 17 00:00:00 2001 From: Arash Ariani Date: Tue, 20 Jul 2021 09:51:36 +0430 Subject: [PATCH] Bael 4464 (#11041) * BAEL-4464 : how to implement LRU-Cache in java codes added * BAEL-4464 : how to implement LRU-Cache in java codes added - package named fixed * BAEL-4464 : how to implement LRU-Cache in java codes added - package named changed * BAEL-4464 : how to implement LRU-Cache in java codes added - unitTest fixed * BAEL-4464 : issues 4,5 fixed. * fixed some issues in BAEL-4464 --- .../baeldung/lrucache/DoublyLinkedList.java | 49 +++++++++---------- .../java/com/baeldung/lrucache/LRUCache.java | 29 +++++------ 2 files changed, 34 insertions(+), 44 deletions(-) diff --git a/data-structures/src/main/java/com/baeldung/lrucache/DoublyLinkedList.java b/data-structures/src/main/java/com/baeldung/lrucache/DoublyLinkedList.java index a2b56741a2..5850d6c13d 100644 --- a/data-structures/src/main/java/com/baeldung/lrucache/DoublyLinkedList.java +++ b/data-structures/src/main/java/com/baeldung/lrucache/DoublyLinkedList.java @@ -10,67 +10,62 @@ public class DoublyLinkedList { private LinkedListNode head; private LinkedListNode tail; private AtomicInteger size; - private ReentrantReadWriteLock.ReadLock readLock; - private ReentrantReadWriteLock.WriteLock writeLock; - - + private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + public DoublyLinkedList() { this.dummyNode = new DummyNode(this); - ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); - readLock = lock.readLock(); - writeLock = lock.writeLock(); clear(); } public void clear() { - writeLock.lock(); + this.lock.writeLock().lock(); try { head = dummyNode; tail = dummyNode; size = new AtomicInteger(0); } finally { - writeLock.unlock(); + this.lock.writeLock().unlock(); } } public int size() { - readLock.lock(); + this.lock.readLock().lock(); try { return size.get(); } finally { - readLock.unlock(); + this.lock.readLock().unlock(); } } public boolean isEmpty() { - readLock.lock(); + this.lock.readLock().lock(); try { return head.isEmpty(); } finally { - readLock.unlock(); + this.lock.readLock().unlock(); } } public boolean contains(T value) { - readLock.lock(); + this.lock.readLock().lock(); try { return search(value).hasElement(); } finally { - readLock.unlock(); + this.lock.readLock().unlock(); } } public LinkedListNode search(T value) { - readLock.lock(); + this.lock.readLock().lock(); try { return head.search(value); } finally { - readLock.unlock(); + this.lock.readLock().unlock(); } } public LinkedListNode add(T value) { - writeLock.lock(); + this.lock.writeLock().lock(); try { head = new Node(value, head, this); if (tail.isEmpty()) { @@ -79,12 +74,12 @@ public class DoublyLinkedList { size.incrementAndGet(); return head; } finally { - writeLock.unlock(); + this.lock.writeLock().unlock(); } } public boolean addAll(Collection values) { - writeLock.lock(); + this.lock.writeLock().lock(); try { for (T value : values) { if (add(value).isEmpty()) { @@ -93,12 +88,12 @@ public class DoublyLinkedList { } return true; } finally { - writeLock.unlock(); + this.lock.writeLock().unlock(); } } public LinkedListNode remove(T value) { - writeLock.lock(); + this.lock.writeLock().lock(); try { LinkedListNode linkedListNode = head.search(value); if (!linkedListNode.isEmpty()) { @@ -113,12 +108,12 @@ public class DoublyLinkedList { } return linkedListNode; } finally { - writeLock.unlock(); + this.lock.writeLock().unlock(); } } public LinkedListNode removeTail() { - writeLock.lock(); + this.lock.writeLock().lock(); try { LinkedListNode oldTail = tail; if (oldTail == head) { @@ -132,7 +127,7 @@ public class DoublyLinkedList { } return oldTail; } finally { - writeLock.unlock(); + this.lock.writeLock().unlock(); } } @@ -141,7 +136,7 @@ public class DoublyLinkedList { } public LinkedListNode updateAndMoveToFront(LinkedListNode node, T newValue) { - writeLock.lock(); + this.lock.writeLock().lock(); try { if (node.isEmpty() || (this != (node.getListReference()))) { return dummyNode; @@ -150,7 +145,7 @@ public class DoublyLinkedList { add(newValue); return head; } finally { - writeLock.unlock(); + this.lock.writeLock().unlock(); } } diff --git a/data-structures/src/main/java/com/baeldung/lrucache/LRUCache.java b/data-structures/src/main/java/com/baeldung/lrucache/LRUCache.java index 0128cadf78..3032a90d8e 100644 --- a/data-structures/src/main/java/com/baeldung/lrucache/LRUCache.java +++ b/data-structures/src/main/java/com/baeldung/lrucache/LRUCache.java @@ -1,6 +1,5 @@ package com.baeldung.lrucache; -import java.util.Hashtable; import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; @@ -10,21 +9,17 @@ public class LRUCache implements Cache { private int size; private Map>> linkedListNodeMap; private DoublyLinkedList> doublyLinkedList; - private ReentrantReadWriteLock.ReadLock readLock; - private ReentrantReadWriteLock.WriteLock writeLock; + private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public LRUCache(int size) { this.size = size; - this.linkedListNodeMap = new Hashtable<>(size); + this.linkedListNodeMap = new ConcurrentHashMap<>(size); this.doublyLinkedList = new DoublyLinkedList<>(); - ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); - this.readLock = lock.readLock(); - this.writeLock = lock.writeLock(); } @Override public boolean put(K key, V value) { - writeLock.lock(); + this.lock.writeLock().lock(); try { CacheElement item = new CacheElement(key, value); LinkedListNode> newNode; @@ -43,13 +38,13 @@ public class LRUCache implements Cache { this.linkedListNodeMap.put(key, newNode); return true; } finally { - writeLock.unlock(); + this.lock.writeLock().unlock(); } } @Override public Optional get(K key) { - readLock.lock(); + this.lock.readLock().lock(); try { LinkedListNode> linkedListNode = this.linkedListNodeMap.get(key); if (linkedListNode != null && !linkedListNode.isEmpty()) { @@ -58,17 +53,17 @@ public class LRUCache implements Cache { } return Optional.empty(); } finally { - readLock.unlock(); + this.lock.readLock().unlock(); } } @Override public int size() { - readLock.lock(); + this.lock.readLock().lock(); try { return doublyLinkedList.size(); } finally { - readLock.unlock(); + this.lock.readLock().unlock(); } } @@ -79,18 +74,18 @@ public class LRUCache implements Cache { @Override public void clear() { - writeLock.lock(); + this.lock.writeLock().lock(); try { linkedListNodeMap.clear(); doublyLinkedList.clear(); } finally { - writeLock.unlock(); + this.lock.writeLock().unlock(); } } private boolean evictElement() { - writeLock.lock(); + this.lock.writeLock().lock(); try { LinkedListNode> linkedListNode = doublyLinkedList.removeTail(); if (linkedListNode.isEmpty()) { @@ -99,7 +94,7 @@ public class LRUCache implements Cache { linkedListNodeMap.remove(linkedListNode.getElement().getKey()); return true; } finally { - writeLock.unlock(); + this.lock.writeLock().unlock(); } } }