| 1 package com.quadcap.util.collections; 2 3 40 41 import java.io.IOException ; 42 import java.io.PrintWriter ; 43 44 import java.util.Enumeration ; 45 import java.util.Hashtable ; 46 47 import com.quadcap.util.Debug; 48 import com.quadcap.util.DList; 49 import com.quadcap.util.DListItem; 50 import com.quadcap.util.ListException; 51 52 60 public abstract class Cache { 61 Object store; 62 Object lock; 63 int size; 64 65 Hashtable t; 66 DList lru = new DList(); 67 68 74 public void init(Object store, int size) { 75 this.store = store; 76 this.size = size; 77 this.lock = this; 78 lru.resize(size); 79 t = new Hashtable (); 80 } 81 82 89 public void setLock(Object lock) { 90 this.lock = lock; 91 } 92 93 101 public Cacheable getCacheable(Object key) throws IOException { 102 synchronized (lock) { 104 Cacheable c = (Cacheable)t.get(key); 106 if (c == null) { 107 c = getCacheable(); 110 c.init(store, key); 111 t.put(key, c); 112 } 113 114 try { 116 lru.moveFront(c.getDListItem()); 117 } catch (ListException e) { 118 Debug.print(e); 119 } 120 c.incrRefCount(); 121 return c; 123 } 124 } 125 126 void checkCache() { 127 synchronized (lock) { 128 Hashtable s = new Hashtable (); 129 try { 131 boolean started = false; 132 for (DListItem d = lru.head(); !started || d != lru.head(); 133 d = d.next) { 134 started = true; 135 Cacheable c = (Cacheable)d.obj; 136 if (c == null) continue; 137 Object key = c.getKey(); 138 Cacheable c1 = (Cacheable)t.get(key); 139 if (c1 != c) { 140 System.out.println("lru item not in hashtable: " + 141 key); 142 } 143 s.put(key, c); 144 } 145 } catch (ListException e) { 146 Debug.print(e); 147 } 148 149 for (Enumeration e = t.keys(); e.hasMoreElements(); ) { 151 Object key = e.nextElement(); 152 if (s.get(key) == null) { 153 System.out.println("hashtable item not in lru: " + key); 154 } 155 } 156 } 157 } 158 159 173 public Object get(Object key) throws IOException { 174 Object data = null; 175 synchronized (lock) { 176 Cacheable c = getCacheable(key); 177 try { 178 data = c.getData(); 179 } finally { 180 c.decrRefCount(); 181 } 182 } 183 return data; 184 } 185 186 190 public void put(Object key, Object val) throws IOException { 191 synchronized (lock) { 192 Cacheable c = getCacheable(key); 193 try { 194 c.setData(val); 195 } finally { 196 c.decrRefCount(); 197 } 198 } 199 } 200 201 206 abstract public Cacheable makeCacheable(); 207 208 214 Cacheable getCacheable() throws IOException { 215 Cacheable c = null; 216 DListItem d = lru.tail(); 217 218 while (d != null) { 219 c = (Cacheable)d.obj; 220 if (c != null && c.getRefCount() > 0) { 221 if (d == lru.head()) { 222 show(new PrintWriter (Debug.debugStream)); 223 throw new RuntimeException ("no free cache item"); 224 } 225 d = d.prev; 226 } else { 227 break; } 229 } 230 231 if (c == null) { 232 d.obj = c = makeCacheable(); 233 c.setDListItem(d); 234 } else { 235 Object key = c.getKey(); 236 if (key != null) { 237 t.remove(key); 239 } 240 if (c.isDirty()) c.flush(); 241 } 242 return c; 243 } 244 245 248 public void flush() throws IOException { 249 synchronized (lock) { 250 boolean started = false; 251 for (DListItem d = lru.head(); !started || d != lru.head(); 252 d = d.next) { 253 started = true; 254 Cacheable c = (Cacheable)d.obj; 255 if (c != null) { 256 c.flush(); 261 } 262 } 263 } 264 } 265 266 public void show(PrintWriter os) { 267 synchronized (lock) { 268 lru.show(os, "\n"); 269 } 270 } 271 } 272 | Popular Tags |