需要
同社の事業は、より複雑では、利用者の基本的な情報を照会するためのさまざまな業務システムのためのユーザシステムを、提供する必要があります。そして、ユーザ情報照会頻度のビジネス面では、システムが注意を必要とするユーザの設計性能高いです。
- 初期設計:アカウントのパフォーマンスを考慮して、あなたは今、ハッシュテーブルを照会します、ユーザーが検索するときは常にキャッシュとしてメモリにハッシュテーブルを作成することができ、クエリが再びデータベースを照会することはできません。
- 初期設計の問題:ユーザーの増加量で、ハッシュテーブルが徐々に増加し、メモリにつながる可能性があるため、1日に爆発します。
- 初期設計の最適化: LRUアルゴリズムを使用して(最低使用メモリ管理アルゴリズム、)、私は最低使用と思いました。仮定に基づくアルゴリズム:長期データが使用されている将来の機会に使用されていないが、大ではありません。データがメモリの特定のしきい値の割合に達したときにそのため、我々は最低使用データが離れて削除されるようにしたいです。
LRUアルゴリズム
LRUアルゴリズムでは、「ハッシュ鎖」と呼ばれるデータ構造を使用しています。ハッシュテーブルには、論理的に注文した問題ではない、キーと値で構成されるいくつかのキーと値で構成されています。しかしながら、ハッシュ・チェーンに、キー値をチェーンにつなぎ合わせても、長くは不規則であるが、一定の配列順序を有します。各キーと値の前駆キー値、後継キー値を有しています。だから我々は、並べ替えに使用時間に応じて、最後のキーと値を置くことができます。リストの最後は、最近使用されている、ヘッドは、最低使用しても、キーと値を使用していなかったです。キャッシュ容量の上限に達したときに、それは左端のバリューチェーン、リストの右端に、新しい値を削除します。
LRUアルゴリズム
ハッシュチェーン構造:
使用上の注意:キーのノードがハッシュマップから削除する必要があることを覚えて、同時にノードを削除します
1つの パッケージblogSrc。 2 3 インポートたjava.util.HashMap。 4 5 パブリック クラスLRUCache { 6 プライベートノードヘッド。 7 プライベートノード終了。 8 9 プライベートのHashMap <文字列、ノード> ハッシュマップ。 10 プライベート int型の制限; // 缓存上限 11 12 公衆 LRUCache(INTの限界){ 13 この .limit = 限界; 14 この .hashMap = 新しいですHashMapの<文字列、ノード> (); 15 } 16 。17 // リストにノードを追加する 18である 公共 ボイドにaddNode(ノードノード){ 19 IF(ヘッド== nullが){ // 空のストランド 20は、 ヘッド= ノードと、 21である } 22れます 23で IF(エンド!= NULL){ // ノードが最後に追加された 24 end.next = ノード; 25 node.pre = END; 26である node.next = NULL ; 27 } 28 エンド= ノード; 29 } 30 31れる // ノードはリストから削除されている 32 公衆がremoveNode(ノードノード){文字列 33が IF(&&エンドノード== ==ヘッドヘッド){ // リストだけのノード 34が ヘッド= NULL ; 35 エンド= NULL ; 36 } そう IF(エンドノード==){ // ノードが最後のノードである [37 end.pre.next = NULL ; 38は、 エンド= end.pre; 39 } 他 IF(ノード==ヘッド){ // 最初のノードへのノード 40 head.next.pre = NULL ; 41である ヘッド= head.next; 42である } 他 { // ノードの中間ノード 43である node.pre.next = node.next; 44である node.next.pre = node.pre; 45 } 46が リターンnode.key; 47 } 48 49 // リフレッシュリスト、ノードは、最も最近使用されたリストの末尾に配置されている 50 の公共 ボイドrefreshNode(ノードノード){ 51は、 IF(ノード== エンド)は{ 52が 戻り、 53である } 54である がremoveNode(ノード); // ノード削除 55 ;てaddNode(ノード)// ノードを追加 56である } 57が 58 // キーによるノード値は、リンクされたリスト内のノードの取得値の値 59 パブリック文字列GET(文字列キー){ 60 ノードnode = HashMap.get(キー) 61が IF(ノード== NULL ){ 62は リターン NULL ; 63である } 64 refreshNode(ノード) 65 リターンnode.value; 66 } 67 68 // キーと値のリストに追加 69 公共 ボイドPUT(文字キー、文字列値){ 70 ノードノード= (KEY)HashMap.getを、 71である IF( ==ノードNULL ){ 72 IF(hashMap.size()> = 限界){ 73である がremoveNode(ヘッド)oldkeyストリング=; // ノード削除し 74 hashMap.remove(oldkeyを); //は、ノードのキーからであることが必要ハッシュマップ除去するために 75 } 76 node = new Node(key,value); 77 addNode(node); 78 hashMap.put(key,node); 79 }else { 80 node.value = value; 81 refreshNode(node); 82 } 83 } 84 85 //从链表上删除指定key的数据 86 public void remove(String key){ 87 Node node = hashMap.get(key); 88 if (node == null){ 89 return ; 90 } 91 がremoveNode(ノード)。 92 hashMap.remove(キー)。 93 } 94 95 クラスノード{ 96 公共の次のノード。 97 パブリックノード前。 98 公共の文字列のキー。 99 公共の文字列値。 100 ノード(文字列キー、文字列値){ 101 この .KEY = キー。 102 この .VALUE = 値。 103 } 104 105 公共ストリングgetNextKey(){ 106 返すnext.getKeyを(); 107 } 108 109 公共ストリングgetPreKey(){ 110 リターンpre.getKey()。 111 } 112 113 公共の文字列のgetKey(){ 114 リターンキー。 115 } 116 117 公共の文字列のgetValue(){ 118 戻り値; 119 } 120 } 121 122 123 公共 静的 ボイドメイン(文字列[]引数){ 124 = LRUCache LRUCache 新しい新しい LRUCache(10 ); 125 lruCache.put( "001"、 "ユーザ情報1" ); 126 lruCache.put( "002"、 "ユーザ情報2" ); 127 lruCache.put( "003"、 "ユーザ情報3" ); 128 lruCache.put( "004"、 "4ユーザ情報" ); 129 lruCache.get( "003" ); 130 のSystem.out.println( "今、エンドノードキーである:" + LRUCache .end.getKey()+ "は、値は" + lruCache.end.getValue()); 131である lruCache.put( "002"、 "ユーザ情報更新2" )。 132 のSystem.out.println( "エンドノードのキーがある今:" + lruCache.end.getKey()+ "価値があります:" +lruCache.end.getValue())。 133 lruCache.put( "006"、 "用户6信息" )。 134 のSystem.out.println( "今、エンドノードのキーがある:" + lruCache.end.getKey()+ "値は次のとおりです。" + lruCache.end.getValue()); 135 } 136 }
結果:
ノードのキーが今いるエンド:003 、値は:3ユーザー情報 今ノードのキーは終わりです: 002 、値は:ユーザ情報更新2 今、ノードのキーは終わりです: 006、値は次のとおりです。ユーザー情報6