Skip to content

Commit 940ba4a

Browse files
authored
Bael 4464 (eugenp#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
1 parent 47e2b74 commit 940ba4a

2 files changed

Lines changed: 34 additions & 44 deletions

File tree

data-structures/src/main/java/com/baeldung/lrucache/DoublyLinkedList.java

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,67 +10,62 @@ public class DoublyLinkedList<T> {
1010
private LinkedListNode<T> head;
1111
private LinkedListNode<T> tail;
1212
private AtomicInteger size;
13-
private ReentrantReadWriteLock.ReadLock readLock;
14-
private ReentrantReadWriteLock.WriteLock writeLock;
15-
16-
13+
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
14+
1715
public DoublyLinkedList() {
1816
this.dummyNode = new DummyNode<T>(this);
19-
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
20-
readLock = lock.readLock();
21-
writeLock = lock.writeLock();
2217
clear();
2318
}
2419

2520
public void clear() {
26-
writeLock.lock();
21+
this.lock.writeLock().lock();
2722
try {
2823
head = dummyNode;
2924
tail = dummyNode;
3025
size = new AtomicInteger(0);
3126
} finally {
32-
writeLock.unlock();
27+
this.lock.writeLock().unlock();
3328
}
3429
}
3530

3631
public int size() {
37-
readLock.lock();
32+
this.lock.readLock().lock();
3833
try {
3934
return size.get();
4035
} finally {
41-
readLock.unlock();
36+
this.lock.readLock().unlock();
4237
}
4338
}
4439

4540
public boolean isEmpty() {
46-
readLock.lock();
41+
this.lock.readLock().lock();
4742
try {
4843
return head.isEmpty();
4944
} finally {
50-
readLock.unlock();
45+
this.lock.readLock().unlock();
5146
}
5247
}
5348

5449
public boolean contains(T value) {
55-
readLock.lock();
50+
this.lock.readLock().lock();
5651
try {
5752
return search(value).hasElement();
5853
} finally {
59-
readLock.unlock();
54+
this.lock.readLock().unlock();
6055
}
6156
}
6257

6358
public LinkedListNode<T> search(T value) {
64-
readLock.lock();
59+
this.lock.readLock().lock();
6560
try {
6661
return head.search(value);
6762
} finally {
68-
readLock.unlock();
63+
this.lock.readLock().unlock();
6964
}
7065
}
7166

7267
public LinkedListNode<T> add(T value) {
73-
writeLock.lock();
68+
this.lock.writeLock().lock();
7469
try {
7570
head = new Node<T>(value, head, this);
7671
if (tail.isEmpty()) {
@@ -79,12 +74,12 @@ public LinkedListNode<T> add(T value) {
7974
size.incrementAndGet();
8075
return head;
8176
} finally {
82-
writeLock.unlock();
77+
this.lock.writeLock().unlock();
8378
}
8479
}
8580

8681
public boolean addAll(Collection<T> values) {
87-
writeLock.lock();
82+
this.lock.writeLock().lock();
8883
try {
8984
for (T value : values) {
9085
if (add(value).isEmpty()) {
@@ -93,12 +88,12 @@ public boolean addAll(Collection<T> values) {
9388
}
9489
return true;
9590
} finally {
96-
writeLock.unlock();
91+
this.lock.writeLock().unlock();
9792
}
9893
}
9994

10095
public LinkedListNode<T> remove(T value) {
101-
writeLock.lock();
96+
this.lock.writeLock().lock();
10297
try {
10398
LinkedListNode<T> linkedListNode = head.search(value);
10499
if (!linkedListNode.isEmpty()) {
@@ -113,12 +108,12 @@ public LinkedListNode<T> remove(T value) {
113108
}
114109
return linkedListNode;
115110
} finally {
116-
writeLock.unlock();
111+
this.lock.writeLock().unlock();
117112
}
118113
}
119114

120115
public LinkedListNode<T> removeTail() {
121-
writeLock.lock();
116+
this.lock.writeLock().lock();
122117
try {
123118
LinkedListNode<T> oldTail = tail;
124119
if (oldTail == head) {
@@ -132,7 +127,7 @@ public LinkedListNode<T> removeTail() {
132127
}
133128
return oldTail;
134129
} finally {
135-
writeLock.unlock();
130+
this.lock.writeLock().unlock();
136131
}
137132
}
138133

@@ -141,7 +136,7 @@ public LinkedListNode<T> moveToFront(LinkedListNode<T> node) {
141136
}
142137

143138
public LinkedListNode<T> updateAndMoveToFront(LinkedListNode<T> node, T newValue) {
144-
writeLock.lock();
139+
this.lock.writeLock().lock();
145140
try {
146141
if (node.isEmpty() || (this != (node.getListReference()))) {
147142
return dummyNode;
@@ -150,7 +145,7 @@ public LinkedListNode<T> updateAndMoveToFront(LinkedListNode<T> node, T newValue
150145
add(newValue);
151146
return head;
152147
} finally {
153-
writeLock.unlock();
148+
this.lock.writeLock().unlock();
154149
}
155150
}
156151

data-structures/src/main/java/com/baeldung/lrucache/LRUCache.java

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.baeldung.lrucache;
22

3-
import java.util.Hashtable;
43
import java.util.Map;
54
import java.util.Optional;
65
import java.util.concurrent.ConcurrentHashMap;
@@ -10,21 +9,17 @@ public class LRUCache<K, V> implements Cache<K, V> {
109
private int size;
1110
private Map<K, LinkedListNode<CacheElement<K, V>>> linkedListNodeMap;
1211
private DoublyLinkedList<CacheElement<K, V>> doublyLinkedList;
13-
private ReentrantReadWriteLock.ReadLock readLock;
14-
private ReentrantReadWriteLock.WriteLock writeLock;
12+
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1513

1614
public LRUCache(int size) {
1715
this.size = size;
18-
this.linkedListNodeMap = new Hashtable<>(size);
16+
this.linkedListNodeMap = new ConcurrentHashMap<>(size);
1917
this.doublyLinkedList = new DoublyLinkedList<>();
20-
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
21-
this.readLock = lock.readLock();
22-
this.writeLock = lock.writeLock();
2318
}
2419

2520
@Override
2621
public boolean put(K key, V value) {
27-
writeLock.lock();
22+
this.lock.writeLock().lock();
2823
try {
2924
CacheElement<K, V> item = new CacheElement<K, V>(key, value);
3025
LinkedListNode<CacheElement<K, V>> newNode;
@@ -43,13 +38,13 @@ public boolean put(K key, V value) {
4338
this.linkedListNodeMap.put(key, newNode);
4439
return true;
4540
} finally {
46-
writeLock.unlock();
41+
this.lock.writeLock().unlock();
4742
}
4843
}
4944

5045
@Override
5146
public Optional<V> get(K key) {
52-
readLock.lock();
47+
this.lock.readLock().lock();
5348
try {
5449
LinkedListNode<CacheElement<K, V>> linkedListNode = this.linkedListNodeMap.get(key);
5550
if (linkedListNode != null && !linkedListNode.isEmpty()) {
@@ -58,17 +53,17 @@ public Optional<V> get(K key) {
5853
}
5954
return Optional.empty();
6055
} finally {
61-
readLock.unlock();
56+
this.lock.readLock().unlock();
6257
}
6358
}
6459

6560
@Override
6661
public int size() {
67-
readLock.lock();
62+
this.lock.readLock().lock();
6863
try {
6964
return doublyLinkedList.size();
7065
} finally {
71-
readLock.unlock();
66+
this.lock.readLock().unlock();
7267
}
7368
}
7469

@@ -79,18 +74,18 @@ public boolean isEmpty() {
7974

8075
@Override
8176
public void clear() {
82-
writeLock.lock();
77+
this.lock.writeLock().lock();
8378
try {
8479
linkedListNodeMap.clear();
8580
doublyLinkedList.clear();
8681
} finally {
87-
writeLock.unlock();
82+
this.lock.writeLock().unlock();
8883
}
8984
}
9085

9186

9287
private boolean evictElement() {
93-
writeLock.lock();
88+
this.lock.writeLock().lock();
9489
try {
9590
LinkedListNode<CacheElement<K, V>> linkedListNode = doublyLinkedList.removeTail();
9691
if (linkedListNode.isEmpty()) {
@@ -99,7 +94,7 @@ private boolean evictElement() {
9994
linkedListNodeMap.remove(linkedListNode.getElement().getKey());
10095
return true;
10196
} finally {
102-
writeLock.unlock();
97+
this.lock.writeLock().unlock();
10398
}
10499
}
105100
}

0 commit comments

Comments
 (0)