[logback-dev] svn commit: r1791 - logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern

noreply.ceki at qos.ch noreply.ceki at qos.ch
Wed Sep 3 17:23:45 CEST 2008


Author: ceki
Date: Wed Sep  3 17:23:45 2008
New Revision: 1791

Modified:
   logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LRUCache.java

Log:
- Using LinkedHashMap as the underlying data structure for the LRUCache.
  
  Unfortunately, this implementations fails the Scenario unit tests. Yes, it looks 
  like a JDK bug (very suprisingly).
  
  Commiting this version for historical (archiving) purposes.

Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LRUCache.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LRUCache.java	(original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/pattern/LRUCache.java	Wed Sep  3 17:23:45 2008
@@ -1,156 +1,45 @@
+/**
+ * Logback: the generic, reliable, fast and flexible logging framework.
+ * 
+ * Copyright (C) 2000-2008, QOS.ch
+ * 
+ * This library is free software, you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation.
+ */
 package ch.qos.logback.classic.pattern;
 
-import java.util.HashMap;
-import java.util.LinkedList;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
-public class LRUCache<K, V> {
-
-  Map<K, Entry> map = new HashMap<K, Entry>();
-  Entry head;
-  Entry tail;
-
-  int limit;
-
-  LRUCache(int limit) {
-    if(limit < 1) {
-       throw new IllegalArgumentException("limit cannnot be smaller than 1");
-    } 
-    
-    this.limit = limit;
- 
-    head = new Entry(null, null);
-    tail = head;
-  }
-
-  public void put(K key, V value) {
-    Entry entry = map.get(key);
-    if (entry == null) {
-      entry = new Entry(key, value);
-      map.put(key, entry);
-    } 
-    moveToTail(entry);
-    while(map.size() > limit) {
-      removeHead();
-    }
-  }
-
-  public V get(K key) {
-    Entry existing = map.get(key);
-    if (existing == null) {
-      return null;
-    } else {
-      moveToTail(existing);
-      return existing.value;
-    }
-  }
-
-  private void removeHead() {
-    //System.out.println("RemoveHead called");
-    map.remove(head.key);
-    head = head.next;
-    head.prev = null;
-  }
-
-  private void moveToTail(Entry e) {
-    rearrangePreexistingLinks(e);
-    rearrangeTailLinks(e);
-  }
-
-  private void rearrangePreexistingLinks(Entry e) {
-    if (e.prev != null) {
-      e.prev.next = e.next;
-    }
-    if (e.next != null) {
-      e.next.prev = e.prev;
-    }
-    if(head == e) {
-      head = e.next;
-    }
+/**
+ * An lru cache based on Java's LinkedHashMap.
+ * 
+ * @author Ceki Gulcu
+ *
+ * @param <K>
+ * @param <V>
+ */
+public class LRUCache<K, V> extends LinkedHashMap<K, V> {
+  private static final long serialVersionUID = -6592964689843698200L;
+
+  final int cacheSize;
+
+  public LRUCache(int cacheSize) {
+    super((int) (cacheSize*(4.0f/3)), 0.75f, true);
+    if(cacheSize < 1) {
+      throw new IllegalArgumentException("Cache size cannnot be smaller than 1");
+   } 
+    this.cacheSize = cacheSize;
   }
   
-  private void rearrangeTailLinks(Entry e) {
-    if(head == tail) {
-      head = e;
-    }
-    Entry preTail = tail.prev;
-    if(preTail != null) {
-      preTail.next = e;
-    }
-    e.prev = preTail;
-    e.next = tail;
-    tail.prev = e;
-  }
-
-
-  public void dump() {
-    Entry e = head;
-    System.out.print("N:");
-    while (e != null) {
-      //System.out.print(e+"->");
-      System.out.print(e.key+", ");
-      e = e.next;
-    }
-    System.out.println();
-  }
-
-  List<K> keyList() {
-    List<K> result = new LinkedList<K>();
-    Entry e = head;
-    while (e != tail) {
-      result.add(e.key);
-      e = e.next;
-    }
-    return result;
+  protected boolean removeEldestEntry(Map.Entry eldest) {
+    return (size() > cacheSize);
   }
   
-  // ================================================================ 
-  private class Entry {
-    Entry next;
-    Entry prev;
-    K key;
-    V value;
-
-    Entry(K k, V v) {
-      this.key = k;
-      this.value = v;
-    }
-
-    @Override
-    public int hashCode() {
-      final int prime = 31;
-      int result = 1;
-      result = prime * result + ((key == null) ? 0 : key.hashCode());
-      return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      if (this == obj)
-        return true;
-      if (obj == null)
-        return false;
-      if (getClass() != obj.getClass())
-        return false;
-      final Entry other = (Entry) obj;
-      if (key == null) {
-        if (other.key != null)
-          return false;
-      } else if (!key.equals(other.key))
-        return false;
-      if (value == null) {
-        if (other.value != null)
-          return false;
-      } else if (!value.equals(other.value))
-        return false;
-      return true;
-    }
-
-    @Override
-    public String toString() {
-      return "(" + key + ", " + value + ")";
-    }
+  List<K> keyList() {
+    return new ArrayList<K>(keySet());
   }
-
 }


More information about the logback-dev mailing list