1 9 package javolution.realtime; 10 11 import javolution.Configuration; 12 import javolution.JavolutionError; 13 import j2me.lang.UnsupportedOperationException; 14 15 38 public abstract class ObjectFactory{ 39 40 43 static final int MAX = Configuration.factories(); 44 45 48 static ObjectFactory[] INSTANCES = new ObjectFactory[MAX]; 49 50 53 static volatile int Count; 54 55 58 static volatile boolean IsAllocationProfileEnabled; 59 60 63 volatile int _allocatedCount; 64 65 68 volatile int _preallocatedCount; 69 70 73 volatile Class _productClass; 74 75 78 Node_preallocated; 79 80 83 private final int _index; 84 85 88 private final HeapPool _heapPool = new HeapPool(); 89 90 97 protected ObjectFactory() { 98 _index = ObjectFactory.add(this); 99 } 100 101 private static synchronized int add(ObjectFactory factory) { 102 final int count = ObjectFactory.Count; 103 if (count >= MAX) { 104 throw new UnsupportedOperationException( 105 "Maximum number of factories (system property " 106 + "\"javolution.factories\", value " + MAX 107 + ") has been reached"); 108 } 109 Class factoryClass = factory.getClass(); 110 for (int i = 0; i < count; i++) { 111 if (factoryClass == INSTANCES[i].getClass()) { 112 throw new UnsupportedOperationException(factoryClass 113 + " cannot have more than one instance"); 114 } 115 } 116 INSTANCES[count] = factory; 117 return ObjectFactory.Count++; 118 } 119 120 126 protected abstract Objectcreate(); 127 128 133 public final ObjectnewObject() { 134 if (!IsAllocationProfileEnabled) 135 return create(); 136 Nodenode = preallocatedNode(); 137 Objectobj = (node != null) ? node._object : create(); 138 if (_productClass == null) { 139 _productClass = obj.getClass(); 140 } 141 return obj; 142 } 143 144 150 public Objectobject() { 151 PoolContext poolContext = Context.currentContext().poolContext(); 152 return (poolContext != null) ? (Object) poolContext.getLocalPool( 153 _index).next() : newObject(); 154 } 155 156 162 public final ObjectPoolcurrentPool() { 163 PoolContext poolContext = Context.currentContext().poolContext(); 164 return (poolContext != null) ? (ObjectPool) poolContext 165 .getLocalPool(_index) : _heapPool; 166 } 167 168 174 public final ObjectPoolheapPool() { 175 return _heapPool; 176 } 177 178 190 protected void cleanup(Objectobj) { 191 throw new UnsupportedOperationException(); 192 } 193 194 200 protected ObjectPoolnewPool() { 201 return new LocalPool(); 202 } 203 204 207 synchronized void preallocate() { 208 for (int i = 0; i < _allocatedCount; i++) { 209 Node node = new Node(); 210 node._object = this.create(); 211 node._next = _preallocated; 212 _preallocated = node; 213 } 214 if (_allocatedCount > _preallocatedCount) { 215 _preallocatedCount = _allocatedCount; 216 } 217 _allocatedCount = 0; 218 } 219 220 223 final synchronized void reset() { 224 _allocatedCount = 0; 225 _preallocatedCount = 0; 226 _preallocated = null; 227 } 228 229 233 private synchronized Node preallocatedNode() { 234 if ((_allocatedCount++ == _preallocatedCount) 235 && AllocationProfile.OverflowHandler != null) { AllocationProfile.OverflowHandler.run(); 237 } 238 if (_preallocated != null) { 239 Node node = _preallocated; 240 _preallocated = _preallocated._next; 241 return node; 242 } else { 243 return null; 244 } 245 } 246 247 250 private final class HeapPool extends ObjectPool{ 251 252 public Objectnext() { 254 return newObject(); 255 } 256 257 public void recycle(Objectobj) { 259 } 261 262 protected void recycleAll() { 264 } 266 267 protected void clearAll() { 269 } 271 } 272 273 276 private final class LocalPool extends ObjectPool{ 277 278 282 private boolean _doCleanup = true; 283 284 287 private Node_usedNodes; 288 289 292 private Node_availNodes; 293 294 297 private Node_usedNodesTail; 298 299 public Objectnext() { 301 Nodenode; 302 if (_availNodes != null) { node = _availNodes; 304 _availNodes = node._next; 305 } else { if (IsAllocationProfileEnabled) { 307 node = preallocatedNode(); 308 if (node == null) { 309 node = new Node(); 310 node._object = create(); 311 } 312 } else { 313 node = new Node(); 314 node._object = create(); 315 } 316 } 317 if (_usedNodes == null) { _usedNodesTail = node; 319 } 320 node._next = _usedNodes; 321 _usedNodes = node; 322 return node._object; 323 } 324 325 public void recycle(Objectobj) { 327 if (_doCleanup) { 329 try { 330 cleanup(obj); 331 } catch (UnsupportedOperationException ex) { 332 _doCleanup = false; 333 } 334 } 335 if (_usedNodes._object == obj) { Nodenode = _usedNodes; 338 if (node == _usedNodesTail) { _usedNodesTail = null; 340 if (node._next != null) throw new JavolutionError("Pool Corrupted"); 342 } 343 _usedNodes = node._next; 344 node._next = _availNodes; 345 _availNodes = node; 346 } else { Nodeprevious = _usedNodes; 348 for (Nodenode = previous._next; node != null;) { 349 if (node._object == obj) { if (node == _usedNodesTail) { _usedNodesTail = previous; 352 } 353 previous._next = node._next; 354 node._next = _availNodes; 355 _availNodes = node; 356 return; 357 } 358 previous = node; 359 node = node._next; 360 } 361 throw new JavolutionError("Object not in the pool"); 362 } 363 } 364 365 protected void recycleAll() { 367 if (_doCleanup) { 369 try { 370 for (Nodenode = _usedNodes; node != null;) { 371 cleanup(node._object); 372 node = node._next; 373 } 374 } catch (UnsupportedOperationException ex) { 375 _doCleanup = false; 376 } 377 } 378 379 if (_usedNodes != null) { 380 _usedNodesTail._next = _availNodes; 381 _availNodes = _usedNodes; 382 _usedNodes = null; 383 _usedNodesTail = null; 384 } 385 } 386 387 protected void clearAll() { 389 _availNodes = null; 390 _usedNodes = null; 391 _usedNodesTail = null; 392 } 393 394 } 395 396 399 static final class Node{ 400 401 Object_object; 402 403 Node_next; 404 } 405 } 406 | Popular Tags |