1 17 18 package SOFA.SOFAnode.Util.DFSRChecker.DFSR; 19 20 import java.util.HashMap ; 21 import java.util.ArrayList ; 22 import java.util.Iterator ; 23 import java.util.NoSuchElementException ; 24 25 26 import SOFA.SOFAnode.Util.DFSRChecker.parser.Debug; 27 import SOFA.SOFAnode.Util.DFSRChecker.state.Signature; 28 29 38 public class StateCache { 39 40 47 public StateCache(int maximalcapacity) { 48 49 int initialcapacity = 1000; 50 cache = new HashMap (initialcapacity, load); 51 if (maximalcapacity != 0) 52 this.maximalCapacity = maximalcapacity; 53 else 54 this.maximalCapacity = Integer.MAX_VALUE; 55 56 Debug.println(2, "Cache created with capacity of " + this.maximalCapacity + " items."); 57 58 } 59 60 66 public void insert(Signature item) throws ItemAlreadyPresentException { 67 68 if (cache.size() >= maximalCapacity) { 69 Iterator it = cache.keySet().iterator(); 70 int size = cache.size() / cachePurgeRatio; 71 Debug.print(2, "Purging the cache....."); 72 73 ArrayList keys = new ArrayList (); 74 75 try { 76 for (int i = 0; i < size; ++i) { 77 for (int j = 0; j < currentPurgeIndex; ++j) 78 it.next(); 79 80 keys.add(it.next()); 81 82 for (int j = 0; j < cachePurgeRatio - currentPurgeIndex - 1; ++j) 83 it.next(); 84 } 85 } catch (NoSuchElementException e) { 86 } 87 88 Iterator it2 = keys.iterator(); 89 size = keys.size(); 90 for (int i = 0; i < size; ++i) { 91 cache.remove(it2.next()); 92 } 93 94 currentPurgeIndex = (currentPurgeIndex + 1) % cachePurgeRatio; 95 96 Debug.println(size + " keys purged."); 97 } 98 if (cache.put(item, item) != null) 100 throw new ItemAlreadyPresentException(); 101 } 102 103 106 public boolean isPresent(Signature item) { 107 115 return cache.containsKey(item); 116 } 117 118 124 public void remove(Signature item) throws ItemNotPresentException { 125 132 if (cache.remove(item) == null) { 133 throw new ItemNotPresentException(); 134 } 135 } 136 137 144 public boolean acceptingReach(Signature signature) { 145 153 try { 154 return ((((Signature) cache.get(signature)).acceptingCycleId) >>> 63) != 0; 155 } catch (NullPointerException e) { 156 return false; 157 } 158 } 159 160 166 public void setAcceptingReach(Signature signature) { 167 try { 168 this.remove(signature); 169 } catch (ItemNotPresentException e) { return; 172 } 173 174 signature.setAcceptingReachable(true); 175 176 178 if (cache.put(signature, signature) != null) 179 throw new RuntimeException ("Inconsistent state cache"); 180 181 } 182 183 190 public long getCycleId(Signature signature) { 191 Signature sig = (Signature) cache.get(signature); 192 return (sig.acceptingCycleId & (~((long) 1 << 63))); 193 } 194 195 203 public void setCycleId(Signature signature, long id) { 204 Signature sig = (Signature) cache.get(signature); 205 if (((sig.acceptingCycleId >> 63) & 1) != 0) 206 sig.acceptingCycleId = id | ((long) 1 << 63); 207 else 208 sig.acceptingCycleId = id & (~((long) 1 << 63)); 209 210 } 211 212 216 public void updateItem(Signature signature) { 217 try { 218 this.remove(signature); 219 } catch (ItemNotPresentException e) { return; 222 } 223 224 if (cache.put(signature, signature) != null) 226 throw new RuntimeException ("Inconsistent state cache"); 227 228 } 229 230 233 public void clear() { 234 cache.clear(); 235 } 236 237 241 private HashMap cache; 242 243 248 private final float load = 0.75f; 249 250 253 private final int maximalCapacity; 254 255 258 private final int cachePurgeRatio = 8; 259 260 263 private int currentPurgeIndex = 0; 264 } | Popular Tags |