1 package org.shiftone.cache.decorator.miss; 2 3 4 5 import org.shiftone.cache.Cache; 6 import org.shiftone.cache.util.Log; 7 8 import java.util.Hashtable ; 9 import java.util.Map ; 10 11 12 16 public class MissHandlingCache implements Cache 17 { 18 19 private static final Log LOG = new Log(MissHandlingCache.class); 20 private final Cache cache; 21 private final Object fetchLock = new Object (); 22 private final MissHandler missHandler; 23 private Map keyMap = new Hashtable (11); 24 25 public MissHandlingCache(Cache cache, MissHandler missHandler) 26 { 27 28 this.cache = cache; 29 this.missHandler = missHandler; 30 31 LOG.debug("new"); 32 } 33 34 35 synchronized Object getLock(Object key) 36 { 37 38 Lock lock = (Lock) keyMap.get(key); 39 40 if (lock == null) 41 { 42 lock = new Lock(); 43 lock.count = 0; 44 45 keyMap.put(key, lock); 46 } 47 else 48 { 49 lock.count++; 50 } 51 52 return lock; 53 } 54 55 56 synchronized void unlockKey(Object key) 57 { 58 59 Lock lock = (Lock) keyMap.get(key); 60 61 if (lock != null) 62 { 63 lock.count--; 64 65 if (lock.count < 0) 66 { 67 keyMap.remove(key); 68 } 69 } 70 else 71 { 72 throw new IllegalStateException ("unlock error"); 73 } 74 } 75 76 77 public Object getObject(Object key) 78 { 79 80 Object value = null; 81 Object lock = getLock(key); 82 83 synchronized (lock) 84 { 85 try 86 { 87 synchronized (cache) 88 { 89 value = cache.getObject(key); 90 } 91 92 if (value == null) 93 { 94 try 95 { 96 value = missHandler.fetchObject(key); 97 } 98 catch (Exception e) 99 { 100 LOG.error("MissHandler error : " + missHandler, e); 101 } 102 } 103 104 if (value != null) 105 { 106 addObject(key, value); 107 } 108 } 109 finally 110 { 111 unlockKey(key); 112 } 113 114 return value; 115 } 116 } 117 118 119 public void addObject(Object userKey, Object cacheObject) 120 { 121 122 synchronized (cache) 123 { 124 cache.addObject(userKey, cacheObject); 125 } 126 } 127 128 129 public int size() 130 { 131 return cache.size(); 132 } 133 134 135 public void remove(Object key) 136 { 137 138 synchronized (cache) 139 { 140 cache.remove(key); 141 } 142 } 143 144 145 public void clear() 146 { 147 148 synchronized (cache) 149 { 150 cache.clear(); 151 } 152 } 153 154 155 public final String toString() 156 { 157 return "MissHandlingCache->" + cache; 158 } 159 160 161 public static class Lock 162 { 163 int count = 0; 164 } 165 } 166 | Popular Tags |