1 23 24 29 42 43 48 49 package com.sun.enterprise.util.pool; 50 51 import java.util.List ; 52 import java.util.Iterator ; 53 import java.util.ArrayList ; 54 import java.util.Collection ; 55 56 import java.lang.ref.Reference ; 57 import java.lang.ref.SoftReference ; 58 59 import com.sun.enterprise.util.collection.DList; 60 import com.sun.enterprise.util.collection.DListNode; 61 62 import com.sun.enterprise.util.scheduler.PeriodicallyServicable; 63 import com.sun.enterprise.util.scheduler.PeriodicEventScheduler; 64 65 import com.sun.enterprise.util.ApproximateClock; 66 import com.sun.enterprise.util.collection.DListNode; 67 import com.sun.enterprise.util.collection.DListNodeFactory; 68 69 import com.sun.enterprise.util.collection.FastStack; 70 import java.util.logging.Logger ; 72 import java.util.logging.Level ; 73 import com.sun.logging.LogDomains; 74 76 77 public class SoftObjectPool 78 extends com.sun.enterprise.util.pool.AbstractPool 79 implements PeriodicallyServicable 80 { 81 static Logger _logger=LogDomains.getLogger(LogDomains.UTIL_LOGGER); 83 protected DList list; 85 protected int minSize; 86 protected int initialSize; 87 protected int maxLimit; 88 protected long maxIdleTime; 89 protected int maxStrongRefs; 90 91 protected Boolean isBounded; 92 93 101 public SoftObjectPool(ObjectFactory factory, int minSize, int initialSize, 102 long maxIdleTime, int maxStrongRefs) { 103 super(); 104 super.factory = factory; 105 this.minSize = minSize; 106 this.initialSize = initialSize; 107 this.maxIdleTime = maxIdleTime; 108 this.maxStrongRefs = maxStrongRefs; 109 110 setMaxLimit(-1); 111 112 initPool(); 113 } 114 115 123 public SoftObjectPool(ObjectFactory factory, int minSize, int initialSize, int maxLimit, 124 long maxIdleTime, int maxStrongRefs) 125 { 126 super(); 127 super.factory = factory; 128 this.minSize = minSize; 129 this.maxIdleTime = maxIdleTime; 130 this.initialSize = initialSize; 131 this.maxStrongRefs = maxStrongRefs; 132 133 setMaxLimit(maxLimit); 134 135 initPool(); 136 } 137 138 public int getMaxLimit() { 139 return this.maxLimit; 140 } 141 142 public void setMaxLimit(int limit) { 143 if ((limit <= 0) || (limit >= Integer.MAX_VALUE-1)) { 144 this.isBounded = null; 145 } else { 146 this.isBounded = new Boolean (true); 147 this.maxLimit = limit; 148 } 149 } 150 151 152 private void initPool() { 153 list = new DList(); 154 155 super.collection = list; 156 super.preload((minSize < initialSize) ? initialSize : minSize); 157 158 scheduler.addTimeRepeatableTask(this, (int) maxIdleTime); 159 } 160 161 164 protected boolean canCreate() { 165 return (isBounded == null) ? true : (createdCount < maxLimit); 166 } 167 168 176 protected Object checkin(Object object) { 177 int size = list.size(); 178 long now = _clock.getTime(); 179 180 if (size < maxStrongRefs) { 181 list.addAsLastNode(new TimeStampedSoftDListNode(object, now, object)); 182 } else { 183 list.addAsLastNode(new TimeStampedSoftDListNode(new SoftReference (object), now, null)); 184 } 185 186 return this; 187 } 188 189 private Object obtainObject(Object param) { 190 SoftReference ref; 191 Object object = null; 192 int notifyCount = 0; 193 194 for (int size = list.size(); size > 0; size--) { 195 TimeStampedSoftDListNode tsNode = (TimeStampedSoftDListNode) list.getDListNodeAt(0); 196 list.delink(tsNode); 197 198 if (tsNode.isSoftRef == null) { 199 ref = (SoftReference ) tsNode.object; 200 if ((object = ref.get()) != null) { 201 break; 202 } else { 203 notifyCount++; 204 } 205 } else { 206 object = tsNode.object; 207 break; 208 } 209 } 210 211 if (object == null) { 212 try { 213 object = factory.create(param); 214 afterCreate(object); 215 } catch (PoolException poolEx) { 216 217 } 218 } 219 220 super.createdCount -= notifyCount; 221 222 if (notifyCount == 1) { 223 super.collection.notify(); 224 } else if (notifyCount > 1) { 225 super.collection.notifyAll(); 226 } 227 228 return object; 229 } 230 231 238 protected Object checkout(Object param) { 239 return obtainObject(param); 240 } 241 242 243 244 246 public void prolog() { 247 } 248 249 public void service() { 250 int killedCount = 0; 251 252 long now = _clock.getTime(); 253 long allowed = now - maxIdleTime; 254 255 TimeStampedSoftDListNode tsNode = null; 256 FastStack stack = new FastStack(); 257 258 synchronized (super.collection) { 259 260 Object done = null; 261 while (done == null) { 262 tsNode = (TimeStampedSoftDListNode) list.getFirstDListNode(); 263 264 if (tsNode == null) { done = new Object (); 266 } else if (tsNode.timeStamp <= allowed) { 267 list.delink(tsNode); 269 stack.push(tsNode.object); 270 killedCount++; 271 } else { 272 done = new Object (); 274 } 275 } 277 super.createdCount -= killedCount; 278 279 int deficit = list.size() - minSize; 280 super.preload(0 - deficit); 281 282 if (killedCount == 0) { 283 } else if (killedCount == 1) { 284 collection.notify(); 285 } else { 286 collection.notifyAll(); 287 } 288 289 } 291 292 while (! stack.isEmpty()) { 294 Object object = stack.pop(); 295 beforeDestroy(object); 296 factory.destroy(object); 297 } 298 299 _logger.log(Level.FINE,"Leaving service after killing " + killedCount + " (idle) objects. Now size: " + list.size()); 302 } 304 305 public void epilog() { 306 } 307 308 312 public long getFrequency() { 313 return this.maxIdleTime; 314 } 315 316 320 public boolean getExecuteIfMissed() { 321 return true; 322 } 323 324 328 public boolean getExecutionTolerance(long missedByMillis) { 329 return true; 330 } 331 332 335 public String toString() { 336 return ""; 337 } 338 339 341 class TimeStampedSoftDListNode 342 extends DListNode 343 { 344 long timeStamp; 345 Object isSoftRef; 346 347 public TimeStampedSoftDListNode(Object object, long ts, Object isSoftRef) { 348 super(object); 349 this.timeStamp = ts; 350 this.isSoftRef = isSoftRef; 351 352 _logger.log(Level.FINE,this + ": created DListNode at: " + ts); 355 } 357 358 public String toString() { 359 return "TSDListNode: " + object + "; isSoftRef: " + isSoftRef; 360 } 361 362 363 } 364 365 366 } 367 | Popular Tags |