00001 package gov.nasa.arc.ase.util; 00002 00003 import java.util.*; 00004 00005 public class Cache { 00006 public interface Listener { 00007 public void elementRemoved(Object o); 00008 } 00009 00010 private class EntryComparator implements Comparator { 00011 public int compare(Object o1, Object o2) { 00012 Map.Entry e1 = (Map.Entry)o1; 00013 Index c1 = (Index)e1.getValue(); 00014 Map.Entry e2 = (Map.Entry)o2; 00015 Index c2 = (Index)e2.getValue(); 00016 00017 return c1.cnt - c2.cnt; 00018 } 00019 } 00020 00021 private class Index { 00022 int cnt; 00023 00024 public Index() { 00025 cnt = 0; 00026 } 00027 00028 public Index(int value) { 00029 cnt = value; 00030 } 00031 00032 public Object clone() { 00033 return new Index(cnt); 00034 } 00035 00036 public boolean equals(Object o) { 00037 return ((Index)o).cnt == cnt; 00038 } 00039 00040 public String toString() { 00041 return new Integer(cnt).toString(); 00042 } 00043 } 00044 00045 private Hashtable ht = new Hashtable(); 00046 private Index lowest = new Index(0); 00047 private Index highest = new Index(0); 00048 private int count = 0; 00049 private int size; 00050 private Listener listener; 00051 00052 public Cache(int s) { 00053 size = s; 00054 listener = null; 00055 } 00056 public Cache(int s, Listener l) { 00057 size = s; 00058 listener = l; 00059 } 00060 private Object getKey(Index c) { 00061 Collection entrySet = ht.entrySet(); 00062 for(Iterator i = entrySet.iterator(); i.hasNext();) { 00063 Map.Entry v = (Map.Entry)i.next(); 00064 if(v.getValue().equals(c)) return v.getKey(); 00065 } 00066 00067 return null; 00068 } 00069 private Index getValue(Index c) { 00070 Collection entrySet = ht.entrySet(); 00071 for(Iterator i = entrySet.iterator(); i.hasNext();) { 00072 Map.Entry v = (Map.Entry)i.next(); 00073 if(v.getValue().equals(c)) return (Index)v.getValue(); 00074 } 00075 00076 return null; 00077 } 00078 private int lowestValue() { 00079 int min = 0; 00080 boolean found = false; 00081 Collection values = ht.values(); 00082 00083 for(Iterator i = values.iterator(); i.hasNext();) { 00084 Index v = (Index)i.next(); 00085 00086 if(!found || v.cnt < min) { 00087 found = true; 00088 min = v.cnt; 00089 } 00090 } 00091 00092 return min; 00093 } 00094 private void next() { 00095 highest.cnt++; 00096 if(highest.cnt < 0) { 00097 ArrayList entries = new ArrayList(ht.entrySet()); 00098 int idx = 0; 00099 00100 ht = new Hashtable(); 00101 Collections.sort(entries, new EntryComparator()); 00102 for(Iterator i = entries.iterator(); i.hasNext(); idx++) { 00103 Map.Entry e = (Map.Entry)i.next(); 00104 ht.put(e.getKey(), new Index(idx)); 00105 } 00106 00107 lowest.cnt = 0; 00108 highest.cnt = entries.size(); 00109 } 00110 } 00111 public boolean put(Object o) { 00112 if(ht.containsKey(o)) { 00113 Index c = (Index)ht.get(o); 00114 00115 if(c.cnt != highest.cnt-1) { 00116 int old = c.cnt; 00117 00118 c.cnt = highest.cnt; 00119 if(old == lowest.cnt) 00120 lowest.cnt = lowestValue(); 00121 next(); 00122 } 00123 00124 return false; 00125 } 00126 00127 if(count == size) 00128 removeLowest(); 00129 else 00130 count++; 00131 00132 ht.put(o, new Index(highest.cnt)); 00133 next(); 00134 00135 return true; 00136 } 00137 private void removeLowest() { 00138 Object key = getKey(lowest); 00139 if(key == null) { 00140 System.err.println("key == null"); 00141 System.err.println(highest); 00142 System.err.println(lowest); 00143 System.err.println(ht); 00144 } 00145 00146 ht.remove(key); 00147 lowest.cnt = lowestValue(); 00148 if(count == 1) highest.cnt = 0; 00149 00150 if(listener != null) listener.elementRemoved(key); 00151 } 00152 public void setSize(int s) { 00153 if(s > count) { 00154 size = s; 00155 } else { 00156 while(count > s) { 00157 removeLowest(); 00158 count--; 00159 } 00160 size = s; 00161 } 00162 } 00163 public String toString() { 00164 return ht.toString(); 00165 } 00166 }