001: /*
002: * Copyright (c) xsocket.org, 2006 - 2008. All rights reserved.
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * Please refer to the LGPL license at: http://www.gnu.org/copyleft/lesser.txt
019: * The latest copy of this software may be found on http://www.xsocket.org/
020: */
021: package org.xsocket.connection.spi;
022:
023: import java.nio.ByteBuffer;
024: import java.util.logging.Level;
025: import java.util.logging.Logger;
026:
027: import org.xsocket.DataConverter;
028:
029: /**
030: * implementation base for a Memory Manager implementation
031: *
032: * @author grro@xsocket.org
033: */
034: abstract class AbstractMemoryManager implements IMemoryManager {
035:
036: private static final Logger LOG = Logger
037: .getLogger(AbstractMemoryManager.class.getName());
038:
039: // direct or non-direct buffer
040: private boolean useDirectMemory = false;
041:
042: // preallocation support
043: private int preallocationSize = 65536;
044: private int minPreallocatedBufferSize = 1;
045: private boolean preallocate = false;
046:
047: /**
048: * constructor
049: *
050: * @param allocationSize the buffer to allocate
051: * @param preallocate true, if buffer should be preallocated
052: * @param minPreallocatedBufferSize the minimal buffer size
053: * @param useDirectMemory true, if direct memory should be used
054: */
055: protected AbstractMemoryManager(int preallocationSize,
056: boolean preallocate, int minPreallocatedBufferSize,
057: boolean useDirectMemory) {
058: this .preallocationSize = preallocationSize;
059: this .preallocate = preallocate;
060: this .minPreallocatedBufferSize = minPreallocatedBufferSize;
061: this .useDirectMemory = useDirectMemory;
062: }
063:
064: /**
065: * {@inheritDoc}
066: */
067: public final boolean isPreallocationMode() {
068: return preallocate;
069: }
070:
071: /**
072: * {@inheritDoc}
073: */
074: public final void setPreallocationMode(boolean mode) {
075: this .preallocate = mode;
076: }
077:
078: /**
079: * {@inheritDoc}
080: */
081: public final void setPreallocatedMinBufferSize(Integer minSize) {
082: this .minPreallocatedBufferSize = minSize;
083: }
084:
085: /**
086: * {@inheritDoc}
087: */
088: public final Integer getPreallocatedMinBufferSize() {
089: return minPreallocatedBufferSize;
090: }
091:
092: /**
093: * {@inheritDoc}
094: */
095: public final Integer gettPreallocationBufferSize() {
096: return preallocationSize;
097: }
098:
099: /**
100: * {@inheritDoc}
101: */
102: public final void setPreallocationBufferSize(Integer minSize) {
103: this .preallocationSize = minSize;
104: }
105:
106: /**
107: * {@inheritDoc}
108: */
109: public final boolean isDirect() {
110: return useDirectMemory;
111: }
112:
113: /**
114: * {@inheritDoc}
115: */
116: public final void setDirect(boolean isDirect) {
117: this .useDirectMemory = isDirect;
118: }
119:
120: /**
121: * {@inheritDoc}
122: */
123: public final ByteBuffer extractAndRecycleMemory(ByteBuffer buffer,
124: int read) {
125:
126: ByteBuffer readData = null;
127:
128: if (read > 0) {
129: buffer.limit(buffer.position());
130: buffer.position(buffer.position() - read);
131:
132: // slice the read data
133: readData = buffer.slice();
134:
135: // preallocate mode?
136: if (preallocate) {
137: // does buffer contain remaining free data? -> recycle these
138: if (buffer.limit() < buffer.capacity()) {
139: buffer.position(buffer.limit());
140: buffer.limit(buffer.capacity());
141:
142: recycleMemory(buffer);
143: }
144: }
145:
146: } else {
147: readData = ByteBuffer.allocate(0);
148:
149: if (preallocate) {
150: recycleMemory(buffer);
151: }
152: }
153:
154: return readData;
155: }
156:
157: /**
158: * {@inheritDoc}
159: */
160: public final ByteBuffer acquireMemoryMinSize(int minSize) {
161:
162: // preallocation mode?
163: if (preallocate) {
164:
165: // ... yes, but is required size larger than preallocation size?
166: if (preallocationSize < minSize) {
167: // ... yes. create a new buffer
168: return newBuffer(minSize);
169:
170: // ... no, call method to get preallocated buffer first
171: } else {
172: ByteBuffer buffer = acquireMemoryStandardSizeOrPreallocated(minSize);
173:
174: // buffer to small?
175: if (buffer.remaining() < minSize) {
176: // yes, create a new one
177: return newBuffer(minSize);
178: }
179: return buffer;
180: }
181:
182: // .. no
183: } else {
184: return newBuffer(minSize);
185: }
186: }
187:
188: /**
189: * creates a new buffer
190: * @param size the size of the new buffer
191: * @return the new buffer
192: */
193: protected final ByteBuffer newBuffer(int size) {
194: if (useDirectMemory) {
195: if (LOG.isLoggable(Level.FINE)) {
196: LOG.fine("allocating "
197: + DataConverter.toFormatedBytesSize(size)
198: + " direct memory");
199: }
200:
201: return ByteBuffer.allocateDirect(size);
202:
203: } else {
204: if (LOG.isLoggable(Level.FINE)) {
205: LOG.fine("allocating "
206: + DataConverter.toFormatedBytesSize(size)
207: + " heap memory");
208: }
209:
210: return ByteBuffer.allocate(size);
211: }
212: }
213:
214: /**
215: * {@inheritDoc}
216: */
217: @Override
218: public String toString() {
219: StringBuilder sb = new StringBuilder();
220: sb
221: .append("useDirect="
222: + useDirectMemory
223: + " preallocationOn="
224: + preallocate
225: + " preallcoationSize="
226: + DataConverter
227: .toFormatedBytesSize(preallocationSize)
228: + " preallocatedMinSize="
229: + DataConverter
230: .toFormatedBytesSize(minPreallocatedBufferSize));
231: return sb.toString();
232: }
233: }
|