1 package org.objectweb.celtix.common.util; 2 3 import java.lang.ref.SoftReference ; 4 import java.util.Iterator ; 5 import java.util.LinkedList ; 6 import java.util.Queue ; 7 8 9 26 public abstract class AbstractTwoStageCache<E> { 27 private Object mutex; 28 private int preallocation; 29 private int primaryCacheSize; 30 private int secondaryCacheHighWaterMark; 31 32 private Queue <E> primaryCache; 33 private Queue <SoftReference <E>> secondaryCache; 34 35 43 public AbstractTwoStageCache(int pCacheSize, int highWaterMark, int prealloc) { 44 this(pCacheSize, highWaterMark, prealloc, null); 45 } 46 47 48 57 public AbstractTwoStageCache(int pCacheSize, int highWaterMark, int prealloc, Object mutexParam) { 58 this.primaryCacheSize = Math.min(pCacheSize, highWaterMark); 59 this.secondaryCacheHighWaterMark = highWaterMark - pCacheSize; 60 this.preallocation = prealloc > highWaterMark ? highWaterMark : prealloc; 61 this.mutex = mutexParam != null ? mutexParam : this; 62 } 63 64 public String toString() { 65 return "AbstractTwoStageCache"; 66 } 67 68 69 74 protected abstract E create() throws Exception ; 75 76 77 80 public void populateCache() throws Exception { 81 primaryCache = new LinkedList <E>(); 83 secondaryCache = new LinkedList <SoftReference <E>>(); 84 85 int primaryCachePreallocation = 87 (preallocation > primaryCacheSize) ? primaryCacheSize : preallocation; 88 for (int i = 0; i < primaryCachePreallocation; i++) { 89 primaryCache.offer(create()); 90 } 91 92 int secondaryCachePreallocation = preallocation - primaryCachePreallocation; 94 for (int i = 0; i < secondaryCachePreallocation; i++) { 95 secondaryCache.offer(new SoftReference <E>(create())); 96 } 97 } 98 99 100 105 public E get() throws Exception { 106 E ret = poll(); 107 108 if (ret == null) { 109 ret = create(); 110 } 111 112 return ret; 113 } 114 115 116 121 public E poll() { 122 E ret = null; 123 124 synchronized (mutex) { 125 if (primaryCache != null) { 126 ret = primaryCache.poll(); 127 if (ret == null) { 128 SoftReference <E> sr = secondaryCache.poll(); 129 while (ret == null && sr != null) { 130 if (sr != null) { 131 ret = sr.get(); 132 } 133 if (ret == null) { 134 sr = secondaryCache.poll(); 135 } 136 } 137 } 138 } 139 } 140 141 return ret; 142 } 143 144 145 151 public boolean recycle(E oldObject) { 152 boolean cached = false; 153 154 synchronized (mutex) { 155 if (primaryCache != null) { 156 if (primaryCache.size() < primaryCacheSize) { 157 cached = primaryCache.offer(oldObject); 158 } 159 160 if (!cached && (secondaryCache.size() >= secondaryCacheHighWaterMark)) { 161 Iterator <SoftReference <E>> it = secondaryCache.iterator(); 163 while (it.hasNext()) { 164 SoftReference <E> sr = it.next(); 165 if (sr.get() == null) { 166 it.remove(); 167 } 168 } 169 } 170 171 if (!cached && (secondaryCache.size() < secondaryCacheHighWaterMark)) { 172 cached = secondaryCache.offer(new SoftReference <E>(oldObject)); 173 } 174 } 175 } 176 177 return cached; 178 } 179 } 180 | Popular Tags |