001: /*
002: * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
003: * Copyright (C) 2006 - Javolution (http://javolution.org/)
004: * All rights reserved.
005: *
006: * Permission to use, copy, modify, and distribute this software is
007: * freely granted, provided that this notice is preserved.
008: */
009: package javolution.context;
010:
011: import j2me.lang.ThreadLocal;
012: import javolution.util.FastMap;
013: import javolution.util.FastTable;
014:
015: /**
016: * <p> This class represents the default allocator context. Allocations are
017: * performed using the <code>new</code> keyword and explicit object
018: * {@link ObjectFactory#recycle(Object) recycling} is supported:[code]
019: * char[] buffer = ArrayFactory.CHARS_FACTORY.array(4098); // Possibly recycled.
020: * while (reader.read(buffer) > 0) { ... }
021: * ArrayFactory.CHARS_FACTORY.recycle(buffer); // Explicit recycling.
022: * [/code]</p>
023: *
024: * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
025: * @version 5.2, August 19, 2007
026: */
027: public class HeapContext extends AllocatorContext {
028:
029: /**
030: * Holds the factory to allocator mapping (per thread).
031: */
032: private static final ThreadLocal FACTORY_TO_ALLOCATOR = new ThreadLocal() {
033: protected Object initialValue() {
034: return new FastMap();
035: }
036: };
037:
038: /**
039: * Holds the allocators which have been activated (per thread).
040: */
041: private static final ThreadLocal ACTIVE_ALLOCATORS = new ThreadLocal() {
042: protected Object initialValue() {
043: return new FastTable();
044: }
045: };
046:
047: /**
048: * Enters a heap context.
049: *
050: * @return the heap context entered.
051: */
052: public static HeapContext enter() {
053: return (HeapContext) Context.enter(CLASS);
054: }
055:
056: private static final Class CLASS = new HeapContext().getClass();
057:
058: /**
059: * Exits the current heap context.
060: *
061: * @return the heap context being exited.
062: * @throws ClassCastException if the context is not a heap context.
063: */
064: public static/*HeapContext*/Context exit() {
065: return (HeapContext) Context.exit();
066: }
067:
068: /**
069: * Default constructor.
070: */
071: public HeapContext() {
072: }
073:
074: // Overrides.
075: protected void deactivate() {
076: FastTable allocators = (FastTable) ACTIVE_ALLOCATORS.get();
077: for (int i = 0, n = allocators.size(); i < n;) {
078: ((Allocator) allocators.get(i++)).user = null;
079: }
080: allocators.clear();
081: }
082:
083: // Overrides.
084: protected Allocator getAllocator(ObjectFactory factory) {
085: final FastMap factoryToAllocator = (FastMap) FACTORY_TO_ALLOCATOR
086: .get();
087: HeapAllocator allocator = (HeapAllocator) factoryToAllocator
088: .get(factory);
089: if (allocator == null) {
090: allocator = new HeapAllocator(factory);
091: factoryToAllocator.put(factory, allocator);
092: }
093: if (allocator.user == null) { // Activate.
094: allocator.user = Thread.currentThread();
095: FastTable activeAllocators = (FastTable) ACTIVE_ALLOCATORS
096: .get();
097: activeAllocators.add(allocator);
098: }
099: return allocator;
100: }
101:
102: // Overrides.
103: protected void enterAction() {
104: getOuter().getAllocatorContext().deactivate();
105: }
106:
107: // Overrides.
108: protected void exitAction() {
109: this .deactivate();
110: }
111:
112: // Holds heap allocator implementation.
113: private static final class HeapAllocator extends Allocator {
114:
115: private final ObjectFactory _factory;
116:
117: public HeapAllocator(ObjectFactory factory) {
118: _factory = factory;
119: }
120:
121: protected Object allocate() {
122: return _factory.create();
123: }
124:
125: protected void recycle(Object object) {
126: if (_factory.doCleanup()) {
127: _factory.cleanup(object);
128: }
129: if (queueSize >= queue.length) {
130: resize();
131: }
132: queue[queueSize++] = object;
133: }
134:
135: public String toString() {
136: return "Heap allocator for " + _factory.getClass();
137: }
138: }
139:
140: }
|