demand
With the company's business more complex, the need to provide a user system, for various business systems to query the user's basic information. And the business side of the user information query frequency is high, the design performance of users the system needs attention.
- Initial design : taking into account performance, you can create a hash table in memory as a cache whenever a user to find, will now query the hash table, the query can not query the database again.
- The initial design problems :With the increasing volume of users, because the hash table may gradually lead to increased memory will one day be explode.
- Optimize the initial design : using the LRU algorithm (memory management algorithms, Least Recently Used), I thought the least recently used. Algorithms based on the assumption: long-term data is not used in the future chance of being used is not large. Therefore, when the data reaches a certain threshold percentage of memory, we want to be the least recently used data is removed away.
LRU algorithm
In the LRU algorithm, the "hash chain" uses a data structure called. Hash table consists of several key-value composed of the key-value does not matter logically ordered. However, in the hash chain, the key-value be strung together in a chain, the longer is disordered, but with a fixed arrangement order. Each has a key-value precursor key-value, the successor key-value. So we can put the last key-value in accordance with the time used to sort. End of the list is being used recently, the head is the least recently used was not even used key-value. So, when the cache capacity limit is reached, it will delete the leftmost value chain, then the new value into the far right of the list.
LRU algorithm
Hash chain structure:
Precautions: delete nodes at the same time, remember that the key nodes should be removed from the hashMap
1 package blogSrc; 2 3 import java.util.HashMap; 4 5 public class LRUCache { 6 private Node head; 7 private Node end; 8 9 private HashMap<String,Node> hashMap; 10 private int limit; //缓存上限 11 12 public LRUCache(int limit){ 13 this.limit = limit; 14 this.hashMap = newThe HashMap <String, the Node> (); 15 } 16 . 17 // adding a node to the list 18 is public void the addNode (the Node Node) { . 19 IF (head == null ) { // empty strand 20 is head = Node; 21 is } 22 is 23 is IF (! End = null ) { // node is added to the end 24 end.next = node; 25 node.pre = End; 26 is node.next = null ; 27 } 28 End = Node; 29 } 30 31 is // node is removed from the list 32 public String the removeNode (the Node Node) { 33 is IF (&& End Node == == head head) { // list only one node 34 is head = null ; 35 End = null ; 36 } the else IF (End node ==) { // node is the last node 37 [ end.pre.next = null ; 38 is End = end.pre; 39 } The else IF (Node == head) { // Node to the first node 40 head.next.pre = null ; 41 is head = head.next; 42 is } the else { // Node intermediate node 43 is node.pre.next = node.next; 44 is node.next.pre = node.pre; 45 } 46 is return node.key; 47 } 48 49 // refresh list, the node is placed at the end of the most recently used list 50 public voidrefreshNode (the Node Node) { 51 is IF (Node == End) { 52 is return ; 53 is } 54 is the removeNode (Node); // delete the node 55 the addNode (Node); // add the node 56 is } 57 is 58 // Key according node value, the value of the acquired value of the node in the linked list 59 public String GET (String Key) { 60 the node node = HashMap.get (Key); 61 is IF (node == null ) { 62 is return null ; 63 is } 64 refreshNode (Node); 65 return node.value; 66 } 67 68 // added to the key-value list 69 public void PUT (String Key, String value) { 70 the Node Node = HashMap.get (Key); 71 is IF ( == node null ) { 72 IF (hashMap.size ()> = limit) { 73 is String = oldkey the removeNode (head); // delete the node 74 hashMap.remove (oldkey); // also need to be from a node key To remove hashmap 75 } 76 = node new new Node (key, value); 77 addNode (node); 78 HashMap.Put (key, node); 79 } the else { 80 Node.Value = value; 81 RefreshNode (node); 82 } 83 } 84 85 / / 从链table on删除specified key specific number据 86 public void the remove (String key) { 87 Node node = HashMap.get (key); 88 an if (node == null ) { 89 return ; 90 } 91 removeNode(node); 92 hashMap.remove(key); 93 } 94 95 class Node { 96 public Node next; 97 public Node pre; 98 public String key; 99 public String value; 100 Node(String key, String value){ 101 this.key = key; 102 this.value = value; 103 } 104 105 public String getNextKey() { 106 return next.getKey(); 107 } 108 109 public String getPreKey() { 110 return pre.getKey(); 111 } 112 113 public String getKey() { 114 return key; 115 } 116 117 public String getValue() { 118 return value; 119 } 120 } 121 122 123 public static void main(String[] args){ 124 = LRUCache the LRUCache new new the LRUCache (10 ); 125 lruCache.put ( "001", "User information 1" ); 126 lruCache.put ( "002", "user information 2" ); 127 lruCache.put ( "003", "user information 3" ); 128 lruCache.put ( "004", "4 user information" ); 129 lruCache.get ( "003" ); 130. System.out.println ( "End Now the Node Key IS:" + LRUCache .end.getKey () + ", the Value IS:" + lruCache.end.getValue ()); 131 is lruCache.put ( "002", "user information update 2" ); 132 System.out.println("Now End Node Key is: " + lruCache.end.getKey() + ",Value is: " +lruCache.end.getValue() ); 133 lruCache.put("006","用户6信息"); 134 System.out.println("Now End Node Key is: " + lruCache.end.getKey()+ ",Value is: " +lruCache.end.getValue()); 135 } 136 }
result:
End the Node Key IS now: 003 , the Value IS: 3 User Information Now the Node Key IS End: 002 , the Value IS: user information update 2 now the Node Key IS End: 006, the Value IS: user information 6