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.lang.ref.SoftReference;
024: import java.nio.ByteBuffer;
025: import java.util.ArrayList;
026: import java.util.List;
027: import java.util.logging.Level;
028: import java.util.logging.Logger;
029:
030: import org.xsocket.DataConverter;
031:
032: /**
033: * a Memory Manager implementation
034: *
035: * @author grro@xsocket.org
036: */
037: final class SynchronizedMemoryManager extends AbstractMemoryManager {
038:
039: private static final Logger LOG = Logger
040: .getLogger(SynchronizedMemoryManager.class.getName());
041:
042: private final List<SoftReference<ByteBuffer>> memoryBuffer = new ArrayList<SoftReference<ByteBuffer>>();
043:
044: /**
045: * constructor
046: *
047: * @param allocationSize the buffer to allocate
048: * @param preallocate true, if buffer should be preallocated
049: * @param minPreallocatedBufferSize the minimal buffer size
050: * @param useDirectMemory true, if direct memory should be used
051: */
052: private SynchronizedMemoryManager(int preallocationSize,
053: boolean preallocate, int minPreallocatedBufferSize,
054: boolean useDirectMemory) {
055: super (preallocationSize, preallocate,
056: minPreallocatedBufferSize, useDirectMemory);
057: }
058:
059: public static SynchronizedMemoryManager createPreallocatedMemoryManager(
060: int preallocationSize, int minBufferSze,
061: boolean useDirectMemory) {
062: return new SynchronizedMemoryManager(preallocationSize, true,
063: minBufferSze, useDirectMemory);
064: }
065:
066: public static SynchronizedMemoryManager createNonPreallocatedMemoryManager(
067: boolean useDirectMemory) {
068: return new SynchronizedMemoryManager(0, false, 1,
069: useDirectMemory);
070: }
071:
072: /**
073: * return the free memory size
074: *
075: * @return the free memory size
076: */
077: public final int getCurrentSizePreallocatedBuffer() {
078: int size = 0;
079:
080: synchronized (memoryBuffer) {
081: for (SoftReference<ByteBuffer> bufferRef : memoryBuffer) {
082: ByteBuffer buffer = bufferRef.get();
083: if (buffer != null) {
084: size += buffer.remaining();
085: }
086: }
087: }
088:
089: return size;
090: }
091:
092: /**
093: * recycle free memory
094: *
095: * @param buffer the buffer to recycle
096: */
097: public void recycleMemory(ByteBuffer buffer) {
098: if (isPreallocationMode()) {
099: int remaining = buffer.remaining();
100: if (remaining >= getPreallocatedMinBufferSize()) {
101: synchronized (memoryBuffer) {
102:
103: if (LOG.isLoggable(Level.FINE)) {
104: LOG.fine("recycling "
105: + DataConverter
106: .toFormatedBytesSize(buffer
107: .remaining()));
108: }
109:
110: memoryBuffer.add(new SoftReference<ByteBuffer>(
111: buffer));
112: }
113: }
114: }
115: }
116:
117: public void preallocate() {
118:
119: }
120:
121: /**
122: * acquire free memory
123: */
124: public ByteBuffer acquireMemoryStandardSizeOrPreallocated(
125: int standardSize) {
126: ByteBuffer buffer = null;
127:
128: if (isPreallocationMode()) {
129:
130: synchronized (memoryBuffer) {
131: if (!memoryBuffer.isEmpty()) {
132: SoftReference<ByteBuffer> freeBuffer = memoryBuffer
133: .remove(0);
134: buffer = freeBuffer.get();
135:
136: if (buffer != null) {
137: // size sufficient?
138: if (buffer.limit() < getPreallocatedMinBufferSize()) {
139: buffer = null;
140: }
141: }
142: }
143: }
144:
145: if (buffer == null) {
146: buffer = newBuffer(standardSize);
147: }
148:
149: return buffer;
150:
151: } else {
152: return newBuffer(standardSize);
153: }
154: }
155: }
|