Skip to content

Commit 4182f2c

Browse files
author
freemanzhang
committed
refactor code
1 parent 09483ce commit 4182f2c

File tree

1 file changed

+65
-63
lines changed

1 file changed

+65
-63
lines changed
Lines changed: 65 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,113 @@
11
package hashtable.design;
22

3+
import static org.junit.Assert.assertEquals;
4+
35
import java.util.HashMap;
46
import java.util.Map;
57

6-
class ListNode
8+
import org.junit.Test;
9+
10+
class DLLNode
711
{
8-
public int key;
12+
public int key;
913
public int value;
10-
public ListNode prev;
11-
public ListNode next;
12-
public ListNode( int key, int value )
14+
public DLLNode prev;
15+
public DLLNode next;
16+
public DLLNode( int key, int value )
1317
{
14-
this.key = key;
18+
this.key = key;
1519
this.value = value;
16-
this.prev = prev;
17-
this.next = next;
1820
}
1921
}
2022

2123
public class LRUCacheHashTableDDL
2224
{
23-
private Map<Integer, ListNode> keyToNodeMap;
25+
26+
private Map<Integer, DLLNode> cache;
2427
// list ordered from oldest to latest
25-
private ListNode listHeadSentinel;
26-
private ListNode listTailSentinel;
28+
private DLLNode dummyOldest;
29+
private DLLNode dummyLatest;
2730
private int capacity;
28-
private final static int SENTINEL = 0;
2931

30-
public LRUCacheHashTableDDL(int capacity)
32+
public LRUCacheHashTableDDL( int capacity )
3133
{
3234
this.capacity = capacity;
33-
this.keyToNodeMap = new HashMap<>( capacity );
34-
listHeadSentinel = new ListNode( SENTINEL, SENTINEL );
35-
listTailSentinel = new ListNode( SENTINEL, SENTINEL );
36-
listHeadSentinel.next = listTailSentinel;
37-
listTailSentinel.prev = listHeadSentinel;
35+
this.cache = new HashMap<>( capacity );
36+
dummyOldest = new DLLNode( 0, 0 );
37+
dummyLatest = new DLLNode( 0, 0 );
38+
dummyLatest.prev = dummyOldest;
39+
dummyOldest.next = dummyLatest;
3840
}
3941

40-
public int get(int key)
42+
public int get( int key )
4143
{
42-
if ( keyToNodeMap.containsKey( key ) )
44+
if ( !cache.containsKey( key ) )
4345
{
44-
ListNode node = keyToNodeMap.get( key );
46+
return -1;
47+
}
48+
49+
DLLNode node = cache.get( key );
4550

46-
// move node to list tail
47-
removeNodeFromList( node );
48-
addNodeToListTail( node );
51+
// move node to list tail
52+
deleteNode( node );
53+
addAsLatest( node );
4954

50-
if ( node != null )
51-
{
52-
return node.value;
53-
}
54-
else
55-
{
56-
throw new IllegalStateException("");
57-
}
58-
}
59-
else
60-
{
61-
return -1;
62-
}
55+
return node.value;
6356
}
6457

65-
public void set(int key, int value)
58+
public void put( int key, int value )
6659
{
6760
// judge and pop up oldest entry when necessary
68-
if ( !keyToNodeMap.containsKey( key ) )
61+
if ( !cache.containsKey( key )
62+
&& cache.size() == capacity )
6963
{
70-
if ( keyToNodeMap.size() == capacity )
71-
{
72-
ListNode cacheToBeRemoved = listHeadSentinel.next;
73-
removeNodeFromList( cacheToBeRemoved );
74-
keyToNodeMap.remove( cacheToBeRemoved.key );
75-
}
64+
DLLNode oldest = dummyOldest.next;
65+
deleteNode( oldest );
66+
cache.remove( oldest.key );
7667
}
7768

78-
if ( keyToNodeMap.containsKey( key ) )
69+
if ( cache.containsKey( key ) )
7970
{
80-
ListNode existingNode = keyToNodeMap.get( key );
81-
removeNodeFromList( existingNode );
71+
DLLNode existingNode = cache.get( key );
8272
existingNode.value = value;
83-
addNodeToListTail( existingNode );
73+
74+
deleteNode( existingNode );
75+
addAsLatest( existingNode );
8476
}
8577
else
8678
{
87-
ListNode node = new ListNode( key, value );
88-
addNodeToListTail( node );
89-
keyToNodeMap.put( key, node );
79+
DLLNode node = new DLLNode( key, value );
80+
cache.put( key, node );
81+
addAsLatest( node );
9082
}
9183
}
9284

93-
private void addNodeToListTail( ListNode nodeToBeAdded )
85+
private void addAsLatest( DLLNode node )
9486
{
95-
ListNode nodeBeforeTail = listTailSentinel.prev;
87+
DLLNode beforeTail = dummyLatest.prev;
9688

97-
nodeBeforeTail.next = nodeToBeAdded;
98-
nodeToBeAdded.prev = nodeBeforeTail;
89+
beforeTail.next = node;
90+
node.prev = beforeTail;
9991

100-
nodeToBeAdded.next = listTailSentinel;
101-
listTailSentinel.prev = nodeToBeAdded;
92+
node.next = dummyLatest;
93+
dummyLatest.prev = node;
94+
}
95+
96+
private void deleteNode( DLLNode node )
97+
{
98+
DLLNode beforeNode = node.prev;
99+
DLLNode afterNode = node.next;
100+
beforeNode.next = afterNode;
101+
afterNode.prev = beforeNode;
102102
}
103103

104-
private void removeNodeFromList( ListNode nodeToBeRemoved )
104+
public static void main( String[] args )
105105
{
106-
ListNode nodeBeforeCurr = nodeToBeRemoved.prev;
107-
ListNode nodeAfterCurr = nodeToBeRemoved.next;
108-
nodeBeforeCurr.next = nodeAfterCurr;
109-
nodeAfterCurr.prev = nodeBeforeCurr;
106+
LRUCacheHashTableDDL table = new LRUCacheHashTableDDL( 2 );
107+
table.put( 1, 1 );
108+
table.put( 2, 2 );
109+
assertEquals( 1, table.get( 1 ) );
110+
table.put( 3, 3 );
111+
assertEquals( -1, table.get( 2 ));
110112
}
111113
}

0 commit comments

Comments
 (0)