Index: ../../../dev/grizzly2_git/modules/grizzly/src/main/java/org/glassfish/grizzly/memory/HeapBuffer.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP <+>/*\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.\n *\n * Copyright (c) 2010-2012 Oracle and/or its affiliates. All rights reserved.\n *\n * The contents of this file are subject to the terms of either the GNU\n * General Public License Version 2 only (\"GPL\") or the Common Development\n * and Distribution License(\"CDDL\") (collectively, the \"License\"). You\n * may not use this file except in compliance with the License. You can\n * obtain a copy of the License at\n * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html\n * or packager/legal/LICENSE.txt. See the License for the specific\n * language governing permissions and limitations under the License.\n *\n * When distributing the software, include this License Header Notice in each\n * file and include the License file at packager/legal/LICENSE.txt.\n *\n * GPL Classpath Exception:\n * Oracle designates this particular file as subject to the \"Classpath\"\n * exception as provided by Oracle in the GPL Version 2 section of the License\n * file that accompanied this code.\n *\n * Modifications:\n * If applicable, add the following below the License Header, with the fields\n * enclosed by brackets [] replaced by your own identifying information:\n * \"Portions Copyright [year] [name of copyright owner]\"\n *\n * Contributor(s):\n * If you wish your version of this file to be governed by only the CDDL or\n * only the GPL Version 2, indicate your decision by adding \"[Contributor]\n * elects to include this software in this distribution under the [CDDL or GPL\n * Version 2] license.\" If you don't indicate a single choice of license, a\n * recipient has the option to distribute your version of this file under\n * either the CDDL, the GPL Version 2 or to extend the choice of license to\n * its licensees as provided above. However, if you add GPL Version 2 code\n * and therefore, elected the GPL Version 2 license, then the option applies\n * only if the new code is made subject to such option by the copyright\n * holder.\n */\n\npackage org.glassfish.grizzly.memory;\n\nimport java.nio.BufferOverflowException;\nimport java.nio.BufferUnderflowException;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.nio.InvalidMarkException;\nimport java.nio.charset.Charset;\nimport java.util.Arrays;\n\nimport org.glassfish.grizzly.Buffer;\n\n/**\n * {@link Buffer} implementation, which uses the {@link ByteBuffer} underneath.\n *\n * @see Buffer\n * @see MemoryManager\n * @see ByteBuffer\n *\n * @author Ken Cavanaugh\n * @author John Vieten\n * @author Alexey Stashok\n * @author Ryan Lubke\n *\n * @since 2.0\n */\npublic class HeapBuffer implements Buffer {\n public static volatile boolean DEBUG_MODE = false;\n\n // Dispose underlying Buffer flag\n protected boolean allowBufferDispose = false;\n\n protected Exception disposeStackTrace;\n\n protected byte[] heap;\n\n protected int offset;\n\n protected int pos;\n\n protected int cap;\n\n protected int lim;\n\n protected int mark = -1;\n\n protected boolean readOnly;\n\n protected ByteOrder order = ByteOrder.BIG_ENDIAN;\n\n protected boolean bigEndian = true;\n\n protected ByteBuffer byteBuffer;\n\n\n // ------------------------------------------------------------ Constructors\n\n protected HeapBuffer() {\n }\n\n protected HeapBuffer(final byte[] heap,\n final int offset,\n final int cap) {\n this.heap = heap;\n this.offset = offset;\n this.cap = cap;\n this.lim = this.cap;\n }\n\n @Override\n public final boolean isComposite() {\n return false;\n }\n\n @Override\n public HeapBuffer prepend(final Buffer header) {\n checkDispose();\n return this;\n }\n\n @Override\n public void trim() {\n checkDispose() ;\n flip();\n }\n \n @Override\n public void shrink() {\n checkDispose();\n }\n\n @Override\n public final boolean allowBufferDispose() {\n return allowBufferDispose;\n }\n\n @Override\n public final void allowBufferDispose(boolean allowBufferDispose) {\n this.allowBufferDispose = allowBufferDispose;\n }\n\n @Override\n public final boolean tryDispose() {\n if (allowBufferDispose) {\n dispose();\n return true;\n }\n\n return false;\n }\n\n @Override\n public void dispose() {\n prepareDispose();\n \n byteBuffer = null;\n heap = null;\n pos = 0;\n offset = 0;\n lim = 0;\n cap = 0;\n }\n\n protected final void prepareDispose() {\n checkDispose();\n if (DEBUG_MODE) { // if debug is on - clear the buffer content\n // Use static logic class to help JIT optimize the code\n DebugLogic.doDebug(this);\n }\n }\n\n @Override\n public ByteBuffer underlying() {\n checkDispose();\n return toByteBuffer();\n }\n\n @Override\n public final int capacity() {\n checkDispose();\n return cap;\n }\n\n @Override\n public final int position() {\n checkDispose();\n return pos;\n }\n\n @Override\n public final HeapBuffer position(final int newPosition) {\n checkDispose();\n pos = newPosition;\n if (mark > pos) mark = -1;\n return this;\n }\n\n @Override\n public final int limit() {\n checkDispose();\n return lim;\n }\n\n @Override\n public final HeapBuffer limit(final int newLimit) {\n checkDispose();\n lim = newLimit;\n if (mark > lim) mark = -1;\n return this;\n }\n\n @Override\n public final HeapBuffer mark() {\n mark = pos;\n return this;\n }\n\n @Override\n public final HeapBuffer reset() {\n int m = mark;\n if (m < 0)\n throw new InvalidMarkException();\n pos = m;\n return this;\n }\n\n @Override\n public final HeapBuffer clear() {\n pos = 0;\n lim = cap;\n mark = -1;\n return this;\n }\n\n @Override\n public final HeapBuffer flip() {\n lim = pos;\n pos = 0;\n mark = -1;\n return this;\n }\n\n @Override\n public final HeapBuffer rewind() {\n pos = 0;\n mark = -1;\n return this;\n }\n\n @Override\n public final int remaining() {\n return (lim - pos);\n }\n\n @Override\n public final boolean hasRemaining() {\n return (pos < lim);\n }\n\n @Override\n public boolean isReadOnly() {\n return readOnly;\n }\n\n @Override\n public final boolean isDirect() {\n return false;\n }\n\n /**\n * {@inheritDoc}\n */\n @Override\n public Buffer split(int splitPosition) {\n final int oldPosition = pos;\n final int oldLimit = lim;\n\n final HeapBuffer ret = createHeapBuffer(\n heap,\n offset + splitPosition,\n cap - splitPosition);\n\n cap = splitPosition;\n\n if (oldPosition < splitPosition) {\n pos = oldPosition;\n } else {\n pos = cap;\n ret.position(oldPosition - splitPosition);\n }\n\n if (oldLimit < splitPosition) {\n lim = oldLimit;\n ret.limit(0);\n } else {\n lim = cap;\n ret.limit(oldLimit - splitPosition);\n }\n\n return ret;\n }\n\n @Override\n public HeapBuffer slice() {\n return slice(pos, lim);\n }\n\n @Override\n public HeapBuffer slice(int position, int limit) {\n return createHeapBuffer(heap, offset + position, limit - position);\n }\n\n\n @Override\n public HeapBuffer duplicate() {\n\n final HeapBuffer duplicate =\n createHeapBuffer(heap, offset, cap);\n duplicate.position(pos);\n duplicate.limit(lim);\n return duplicate;\n }\n\n @Override\n public HeapBuffer asReadOnlyBuffer() {\n final HeapBuffer b = new ReadOnlyHeapBuffer(heap, offset, cap);\n b.pos = pos;\n b.lim = lim;\n return b;\n }\n\n @Override\n public byte get() {\n if (!hasRemaining()) {\n throw new BufferUnderflowException();\n }\n return heap[offset + pos++];\n }\n\n @Override\n public byte get(int index) {\n if (index < 0 || index >= lim) {\n throw new IndexOutOfBoundsException();\n }\n return heap[offset + index];\n }\n\n @Override\n public HeapBuffer put(byte b) {\n if (!hasRemaining()) {\n throw new BufferOverflowException();\n }\n heap[offset + pos++] = b;\n return this;\n }\n\n @Override\n public HeapBuffer put(int index, byte b) {\n if (index < 0 || index >= lim) {\n throw new IndexOutOfBoundsException();\n }\n heap[offset + index] = b;\n return this;\n }\n\n @Override\n public HeapBuffer get(final byte[] dst) {\n return get(dst, 0, dst.length);\n }\n\n @Override\n public HeapBuffer get(final byte[] dst, final int offset, final int length) {\n if (remaining() < length) {\n throw new BufferUnderflowException();\n }\n System.arraycopy(heap, (this.offset + pos), dst, offset, length);\n pos += length;\n return this;\n }\n\n @Override\n public HeapBuffer put(final Buffer src) {\n put(src, src.position(), src.remaining());\n src.position(src.limit());\n return this;\n }\n\n @Override\n public HeapBuffer put(final Buffer src, final int position, final int length) {\n if (remaining() < length) {\n throw new BufferOverflowException();\n }\n\n final int oldPos = src.position();\n final int oldLim = src.limit();\n\n final int thisPos = pos; // Save the current pos for case, if src == this\n Buffers.setPositionLimit(src, position, position + length);\n\n src.get(heap, offset + thisPos, length);\n Buffers.setPositionLimit(src, oldPos, oldLim);\n pos = thisPos + length;\n\n\n return this;\n }\n\n @Override\n public Buffer get(final ByteBuffer dst) {\n final int length = dst.remaining();\n \n dst.put(heap, offset + pos, length);\n pos += length;\n \n return this;\n }\n\n @Override\n public Buffer get(final ByteBuffer dst, final int position, final int length) {\n final int oldPos = dst.position();\n final int oldLim = dst.limit();\n\n try {\n Buffers.setPositionLimit(dst, position, position + length);\n dst.put(heap, offset + pos, length);\n pos += length;\n } finally {\n Buffers.setPositionLimit(dst, oldPos, oldLim);\n }\n\n return this;\n }\n \n @Override\n public Buffer put(final ByteBuffer src) {\n final int length = src.remaining();\n \n src.get(heap, offset + pos, length);\n pos += length;\n \n return this;\n }\n\n @Override\n public Buffer put(final ByteBuffer src, final int position, final int length) {\n final int oldPos = src.position();\n final int oldLim = src.limit();\n\n try {\n Buffers.setPositionLimit(src, position, position + length);\n src.get(heap, offset + pos, length);\n pos += length;\n } finally {\n Buffers.setPositionLimit(src, oldPos, oldLim);\n }\n\n return this;\n }\n\n public static HeapBuffer wrap(byte[] heap) {\n return wrap(heap, 0, heap.length);\n }\n\n\n public static HeapBuffer wrap(byte[] heap, int off, int len) {\n return new HeapBuffer(heap, off, len);\n }\n\n\n @Override\n public HeapBuffer put(byte[] src) {\n return put(src, 0, src.length);\n }\n\n @Override\n public HeapBuffer put(byte[] src, int offset, int length) {\n if (remaining() < length) {\n throw new BufferOverflowException();\n }\n\n System.arraycopy(src, offset, heap, this.offset + pos, length);\n pos += length;\n\n return this;\n }\n\n @SuppressWarnings(\"deprecation\")\n @Override\n public HeapBuffer put8BitString(final String s) {\n final int len = s.length();\n if (remaining() < len) {\n throw new BufferOverflowException();\n }\n\n s.getBytes(0, len, heap, offset + pos);\n pos += len;\n\n return this;\n }\n\n @Override\n public HeapBuffer compact() {\n final int length = remaining();\n System.arraycopy(heap, offset + pos, heap, offset, length);\n pos = length;\n lim = cap;\n return this;\n }\n\n @Override\n public ByteOrder order() {\n return order;\n }\n\n @Override\n public HeapBuffer order(ByteOrder bo) {\n order = bo;\n bigEndian = (order == ByteOrder.BIG_ENDIAN);\n return this;\n }\n\n @Override\n public char getChar() {\n if (remaining() < 2) {\n throw new BufferUnderflowException();\n }\n final char c = Bits.getChar(heap, offset + pos, bigEndian);\n pos += 2;\n return c;\n }\n\n @Override\n public char getChar(int index) {\n if (index < 0 || index >= (lim - 1)) {\n throw new IndexOutOfBoundsException();\n }\n return Bits.getChar(heap, offset + index, bigEndian);\n }\n\n @Override\n public HeapBuffer putChar(char value) {\n if (remaining() < 2) {\n throw new BufferUnderflowException();\n }\n\n Bits.putChar(heap, offset + pos, value, bigEndian);\n pos += 2;\n return this;\n }\n\n @Override\n public HeapBuffer putChar(int index, char value) {\n if (index < 0 || index >= (lim - 1)) {\n throw new IndexOutOfBoundsException();\n }\n Bits.putChar(heap, offset + index, value, bigEndian);\n return this;\n }\n\n @Override\n public short getShort() {\n if (remaining() < 2) {\n throw new BufferUnderflowException();\n }\n final short s = Bits.getShort(heap, offset + pos, bigEndian);\n pos += 2;\n return s;\n }\n\n @Override\n public short getShort(int index) {\n if (index < 0 || index >= (lim - 1)) {\n throw new IndexOutOfBoundsException();\n }\n return Bits.getShort(heap, offset + index, bigEndian);\n }\n\n @Override\n public HeapBuffer putShort(short value) {\n if (remaining() < 2) {\n throw new BufferUnderflowException();\n }\n Bits.putShort(heap, offset + pos, value, bigEndian);\n pos += 2;\n return this;\n }\n\n @Override\n public HeapBuffer putShort(int index, short value) {\n if (index < 0 || index >= (lim - 1)) {\n throw new IndexOutOfBoundsException();\n }\n Bits.putShort(heap, offset + index, value, bigEndian);\n return this;\n }\n\n @Override\n public int getInt() {\n if (remaining() < 4) {\n throw new BufferUnderflowException();\n }\n final int i = Bits.getInt(heap, offset + pos, bigEndian);\n pos += 4;\n return i;\n }\n\n @Override\n public int getInt(int index) {\n if (index < 0 || index >= (lim - 3)) {\n throw new IndexOutOfBoundsException();\n }\n return Bits.getInt(heap, offset + index, bigEndian);\n }\n\n @Override\n public HeapBuffer putInt(int value) {\n if (remaining() < 4) {\n throw new BufferUnderflowException();\n }\n Bits.putInt(heap, offset + pos, value, bigEndian);\n pos += 4;\n return this;\n }\n\n @Override\n public HeapBuffer putInt(int index, int value) {\n if (index < 0 || index >= (lim - 3)) {\n throw new IndexOutOfBoundsException();\n }\n Bits.putInt(heap, offset + index, value, bigEndian);\n return this;\n }\n\n @Override\n public long getLong() {\n if (remaining() < 8) {\n throw new BufferUnderflowException();\n }\n final long l = Bits.getLong(heap, offset + pos, bigEndian);\n pos += 8;\n return l;\n }\n\n @Override\n public long getLong(int index) {\n if (index < 0 || index >= (lim - 7)) {\n throw new IndexOutOfBoundsException();\n }\n return Bits.getLong(heap, offset + index, bigEndian);\n }\n\n @Override\n public HeapBuffer putLong(long value) {\n if (remaining() < 8) {\n throw new BufferUnderflowException();\n }\n Bits.putLong(heap, offset + pos, value, bigEndian);\n pos += 8;\n return this;\n }\n\n @Override\n public HeapBuffer putLong(int index, long value) {\n if (index < 0 || index >= (lim - 7)) {\n throw new IndexOutOfBoundsException();\n }\n Bits.putLong(heap, offset + index, value, bigEndian);\n return this;\n }\n\n @Override\n public float getFloat() {\n if (remaining() < 4) {\n throw new BufferUnderflowException();\n }\n final float f = Bits.getFloat(heap, offset + pos, bigEndian);\n pos += 4;\n return f;\n }\n\n @Override\n public float getFloat(int index) {\n if (index < 0 || index >= (lim - 3)) {\n throw new IndexOutOfBoundsException();\n }\n return Bits.getFloat(heap, offset + index, bigEndian);\n }\n\n @Override\n public HeapBuffer putFloat(float value) {\n if (remaining() < 4) {\n throw new BufferUnderflowException();\n }\n Bits.putFloat(heap, offset + pos, value, bigEndian);\n pos += 4;\n return this;\n }\n\n @Override\n public HeapBuffer putFloat(int index, float value) {\n if (index < 0 || index >= (lim - 3)) {\n throw new IndexOutOfBoundsException();\n }\n Bits.putFloat(heap, offset + index, value, bigEndian);\n return this;\n }\n\n @Override\n public double getDouble() {\n if (remaining() < 8) {\n throw new BufferUnderflowException();\n }\n final double d = Bits.getDouble(heap, offset + pos, bigEndian);\n pos += 8;\n return d;\n }\n\n @Override\n public double getDouble(int index) {\n if (index < 0 || index >= (lim - 7)) {\n throw new IndexOutOfBoundsException();\n }\n return Bits.getDouble(heap, offset + index, bigEndian);\n }\n\n @Override\n public HeapBuffer putDouble(double value) {\n if (remaining() < 8) {\n throw new BufferUnderflowException();\n }\n Bits.putDouble(heap, offset + pos, value, bigEndian);\n return this;\n }\n\n @Override\n public HeapBuffer putDouble(int index, double value) {\n if (index < 0 || index >= (lim - 7)) {\n throw new IndexOutOfBoundsException();\n }\n Bits.putDouble(heap, offset + index, value, bigEndian);\n return this;\n }\n \n @Override\n public int hashCode() {\n int result = (allowBufferDispose ? 1 : 0);\n result = 31 * result + (disposeStackTrace != null ? disposeStackTrace.hashCode() : 0);\n result = 31 * result + (heap != null ? Arrays.hashCode(heap) : 0);\n result = 31 * result + offset;\n result = 31 * result + pos;\n result = 31 * result + cap;\n result = 31 * result + lim;\n result = 31 * result + mark;\n result = 31 * result + (readOnly ? 1 : 0);\n result = 31 * result + (order != null ? order.hashCode() : 0);\n result = 31 * result + (bigEndian ? 1 : 0);\n return result;\n }\n\n @Override\n public boolean equals(Object obj) {\n if (obj instanceof Buffer) {\n Buffer that = (Buffer) obj;\n if (this.remaining() != that.remaining()) {\n return false;\n }\n int p = this.position();\n for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--) {\n byte v1 = this.get(i);\n byte v2 = that.get(j);\n if (v1 != v2) {\n return false;\n }\n }\n return true;\n }\n\n return false;\n }\n\n @Override\n public int compareTo(Buffer o) {\n // taken from ByteBuffer#compareTo(...)\n int n = position() + Math.min(remaining(), o.remaining());\n for (int i = this.position(), j = o.position(); i < n; i++, j++) {\n byte v1 = this.get(i);\n byte v2 = o.get(j);\n if (v1 == v2)\n continue;\n if (v1 < v2)\n return -1;\n return +1;\n }\n\n return remaining() - o.remaining();\n }\n\n protected final void checkDispose() {\n if (heap == null) {\n throw new IllegalStateException(\n \"HeapBuffer has already been disposed\",\n disposeStackTrace);\n }\n }\n\n @Override\n public String toString() {\n final StringBuilder sb = new StringBuilder(\"HeapBuffer (\" +\n System.identityHashCode(this) + \") \");\n sb.append(\"[pos=\");\n sb.append(pos);\n sb.append(\" lim=\");\n sb.append(lim);\n sb.append(\" cap=\");\n sb.append(cap);\n sb.append(']');\n return sb.toString();\n }\n\n @Override\n public String toStringContent() {\n return toStringContent(Charset.defaultCharset(), pos, lim);\n }\n\n @Override\n public String toStringContent(final Charset charset) {\n return toStringContent(charset, pos, lim);\n }\n\n @Override\n public String toStringContent(Charset charset, final int position,\n final int limit) {\n checkDispose();\n if (charset == null) {\n charset = Charset.defaultCharset();\n }\n\n final boolean isRestoreByteBuffer = byteBuffer != null;\n int oldPosition = 0;\n int oldLimit = 0;\n\n if (isRestoreByteBuffer) {\n // ByteBuffer can be used by outer code - so save its state\n oldPosition = byteBuffer.position();\n oldLimit = byteBuffer.limit();\n }\n \n final ByteBuffer bb = toByteBuffer0(position, limit, false);\n\n try {\n return charset.decode(bb).toString();\n } finally {\n if (isRestoreByteBuffer) {\n Buffers.setPositionLimit(byteBuffer, oldPosition, oldLimit);\n }\n }\n }\n\n @Override\n public ByteBuffer toByteBuffer() {\n return toByteBuffer(pos, lim);\n }\n\n @Override\n public ByteBuffer toByteBuffer(final int position, final int limit) {\n // we have to slice the buffer after setting the proper pos/lim in\n // order to allow the full range of methods offered by ByteBuffer to\n // be useful (rewind() for instance which will always set the pos to 0).\n return toByteBuffer0(position, limit, true);\n }\n\n @Override\n public final ByteBufferArray toByteBufferArray() {\n final ByteBufferArray array = ByteBufferArray.create();\n array.add(toByteBuffer());\n\n return array;\n }\n\n @Override\n public final ByteBufferArray toByteBufferArray(final int position,\n final int limit) {\n return toByteBufferArray(ByteBufferArray.create(), position, limit);\n }\n\n @Override\n public final ByteBufferArray toByteBufferArray(final ByteBufferArray array) {\n array.add(toByteBuffer());\n return array;\n }\n\n @Override\n public final ByteBufferArray toByteBufferArray(final ByteBufferArray array,\n final int position, final int limit) {\n\n array.add(toByteBuffer(position, limit));\n\n return array;\n }\n\n @Override\n public final BufferArray toBufferArray() {\n final BufferArray array = BufferArray.create();\n array.add(this);\n\n return array;\n }\n\n @Override\n public final BufferArray toBufferArray(final int position,\n final int limit) {\n return toBufferArray(BufferArray.create(), position, limit);\n }\n\n @Override\n public final BufferArray toBufferArray(final BufferArray array) {\n array.add(this);\n return array;\n }\n\n @Override\n public final BufferArray toBufferArray(final BufferArray array,\n final int position, final int limit) {\n\n final int oldPos = pos;\n final int oldLim = lim;\n\n pos = position;\n lim = limit;\n\n array.add(this, oldPos, oldLim);\n return array;\n }\n\n @Override\n public boolean release() {\n return tryDispose();\n }\n\n /**\n * {@inheritDoc}\n */\n @Override\n public boolean isExternal() {\n return false;\n }\n\n @Override\n public boolean hasArray() {\n return true;\n }\n\n @Override\n public int arrayOffset() {\n return offset;\n }\n\n public byte[] array() {\n return heap;\n }\n\n // ------------------------------------------------------- Protected Methods\n\n\n\n\n protected HeapBuffer createHeapBuffer(final byte[] heap,\n final int offset, final int capacity) {\n return new HeapBuffer(\n heap,\n offset,\n capacity);\n }\n\n protected ByteBuffer toByteBuffer0(final int pos,\n final int len,\n final boolean slice) {\n if (byteBuffer == null) {\n byteBuffer = ByteBuffer.wrap(heap);\n }\n\n Buffers.setPositionLimit(byteBuffer, offset + pos, offset + len);\n\n return ((slice) ? byteBuffer.slice() : byteBuffer);\n\n }\n\n\n // ---------------------------------------------------------- Nested Classes\n\n private static class DebugLogic {\n static void doDebug(HeapBuffer heapBuffer) {\n heapBuffer.clear();\n while(heapBuffer.hasRemaining()) {\n heapBuffer.put((byte) 0xFF);\n }\n heapBuffer.flip();\n heapBuffer.disposeStackTrace = new Exception(\"HeapBuffer was disposed from: \");\n }\n }\n\n}\n =================================================================== --- ../../../dev/grizzly2_git/modules/grizzly/src/main/java/org/glassfish/grizzly/memory/HeapBuffer.java (revision f240c6e3d8d6eb69e7a34c692bf76e950cbda1f8) +++ ../../../dev/grizzly2_git/modules/grizzly/src/main/java/org/glassfish/grizzly/memory/HeapBuffer.java (revision ) @@ -159,6 +159,8 @@ offset = 0; lim = 0; cap = 0; + order = ByteOrder.BIG_ENDIAN; + bigEndian = true; } protected final void prepareDispose() { Index: ../../../dev/grizzly2_git/modules/grizzly/src/main/java/org/glassfish/grizzly/memory/HeapMemoryManager.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP <+>/*\n * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.\n *\n * Copyright (c) 2010-2012 Oracle and/or its affiliates. All rights reserved.\n *\n * The contents of this file are subject to the terms of either the GNU\n * General Public License Version 2 only (\"GPL\") or the Common Development\n * and Distribution License(\"CDDL\") (collectively, the \"License\"). You\n * may not use this file except in compliance with the License. You can\n * obtain a copy of the License at\n * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html\n * or packager/legal/LICENSE.txt. See the License for the specific\n * language governing permissions and limitations under the License.\n *\n * When distributing the software, include this License Header Notice in each\n * file and include the License file at packager/legal/LICENSE.txt.\n *\n * GPL Classpath Exception:\n * Oracle designates this particular file as subject to the \"Classpath\"\n * exception as provided by Oracle in the GPL Version 2 section of the License\n * file that accompanied this code.\n *\n * Modifications:\n * If applicable, add the following below the License Header, with the fields\n * enclosed by brackets [] replaced by your own identifying information:\n * \"Portions Copyright [year] [name of copyright owner]\"\n *\n * Contributor(s):\n * If you wish your version of this file to be governed by only the CDDL or\n * only the GPL Version 2, indicate your decision by adding \"[Contributor]\n * elects to include this software in this distribution under the [CDDL or GPL\n * Version 2] license.\" If you don't indicate a single choice of license, a\n * recipient has the option to distribute your version of this file under\n * either the CDDL, the GPL Version 2 or to extend the choice of license to\n * its licensees as provided above. However, if you add GPL Version 2 code\n * and therefore, elected the GPL Version 2 license, then the option applies\n * only if the new code is made subject to such option by the copyright\n * holder.\n */\n\npackage org.glassfish.grizzly.memory;\n\nimport org.glassfish.grizzly.ThreadCache;\nimport org.glassfish.grizzly.monitoring.jmx.JmxMonitoringConfig;\nimport org.glassfish.grizzly.monitoring.jmx.JmxObject;\n\nimport java.nio.ByteBuffer;\nimport java.nio.charset.Charset;\nimport java.util.Arrays;\nimport org.glassfish.grizzly.Buffer;\nimport org.glassfish.grizzly.Cacheable;\n\n/**\n * A {@link WrapperAware} {@link MemoryManager} implementation for\n * managing {@link HeapBuffer} instances.\n *\n * @since 2.0\n */\npublic class HeapMemoryManager extends AbstractMemoryManager implements WrapperAware {\n\n private static final ThreadCache.CachedTypeIndex CACHE_IDX =\n ThreadCache.obtainIndex(TrimmableHeapBuffer.class, 8);\n\n private static final ThreadCache.CachedTypeIndex BBW_CACHE_IDX =\n ThreadCache.obtainIndex(RecyclableByteBufferWrapper.class, 2);\n\n public HeapMemoryManager() {\n super();\n }\n\n public HeapMemoryManager(final int maxBufferSize) {\n super(maxBufferSize);\n }\n\n // ---------------------------------------------- Methods from MemoryManager\n\n\n /**\n * {@inheritDoc}\n */\n @Override\n public HeapBuffer allocate(final int size) {\n return allocateHeapBuffer(size);\n }\n \n /**\n * {@inheritDoc}\n */\n @Override\n public HeapBuffer allocateAtLeast(final int size) {\n return allocateHeapBufferAtLeast(size);\n }\n\n /**\n * {@inheritDoc}\n */\n @Override\n public HeapBuffer reallocate(final HeapBuffer oldBuffer, final int newSize) {\n return reallocateHeapBuffer(oldBuffer, newSize);\n }\n \n /**\n * {@inheritDoc}\n */\n @Override\n public void release(final HeapBuffer buffer) {\n releaseHeapBuffer(buffer);\n }\n \n /**\n * {@inheritDoc}\n */\n @Override\n public boolean willAllocateDirect(int size) {\n return false;\n }\n\n /**\n * {@inheritDoc}\n */\n @Override\n public JmxMonitoringConfig getMonitoringConfig() {\n return monitoringConfig;\n }\n\n /**\n * {@inheritDoc}\n */\n @Override\n public ThreadLocalPool createThreadLocalPool() {\n return new HeapBufferThreadLocalPool(this);\n }\n\n /**\n * {@inheritDoc}\n */\n @Override\n protected JmxObject createJmxManagementObject() {\n return new org.glassfish.grizzly.memory.jmx.HeapMemoryManager(this);\n }\n\n\n // ----------------------------------------------- Methods from WrapperAware\n\n\n /**\n * {@inheritDoc}\n */\n @Override\n public HeapBuffer wrap(final byte[] data) {\n return createTrimAwareBuffer(data, 0, data.length);\n }\n\n /**\n * {@inheritDoc}\n */\n @Override\n public HeapBuffer wrap(final byte[] data, final int offset, final int length) {\n return createTrimAwareBuffer(data, offset, length);\n }\n\n /**\n * {@inheritDoc}\n */\n @Override\n public HeapBuffer wrap(final String s) {\n return wrap(s, Charset.defaultCharset());\n }\n\n /**\n * {@inheritDoc}\n */\n @Override\n public HeapBuffer wrap(final String s, final Charset charset) {\n return wrap(s.getBytes(charset));\n }\n\n /**\n * {@inheritDoc}\n */\n @Override\n public Buffer wrap(final ByteBuffer byteBuffer) {\n if (byteBuffer.hasArray()) {\n return wrap(byteBuffer.array(),\n byteBuffer.arrayOffset() + byteBuffer.position(),\n byteBuffer.remaining());\n } else {\n return createByteBufferWrapper(byteBuffer);\n }\n }\n\n // ------------------------------------------------------- Protected Methods\n\n\n protected HeapBuffer allocateHeapBuffer(final int size) {\n if (size > maxBufferSize) {\n // Don't use pool\n return createTrimAwareBuffer(size);\n }\n\n final ThreadLocalPool threadLocalCache = getHeapBufferThreadLocalPool();\n if (threadLocalCache != null) {\n final int remaining = threadLocalCache.remaining();\n\n if (remaining == 0 || remaining < size) {\n reallocatePoolBuffer();\n }\n\n return (HeapBuffer) allocateFromPool(threadLocalCache, size);\n } else {\n return createTrimAwareBuffer(size);\n }\n }\n\n protected HeapBuffer allocateHeapBufferAtLeast(final int size) {\n if (size > maxBufferSize) {\n // Don't use pool\n return createTrimAwareBuffer(size);\n }\n\n final ThreadLocalPool threadLocalCache = getHeapBufferThreadLocalPool();\n if (threadLocalCache != null) {\n int remaining = threadLocalCache.remaining();\n\n if (remaining == 0 || remaining < size) {\n reallocatePoolBuffer();\n remaining = threadLocalCache.remaining();\n }\n\n return (HeapBuffer) allocateFromPool(threadLocalCache, remaining);\n } else {\n return createTrimAwareBuffer(size);\n }\n }\n \n protected HeapBuffer reallocateHeapBuffer(HeapBuffer oldHeapBuffer, int newSize) {\n if (oldHeapBuffer.capacity() >= newSize) return oldHeapBuffer;\n\n final ThreadLocalPool memoryPool = getHeapBufferThreadLocalPool();\n if (memoryPool != null) {\n final HeapBuffer newBuffer =\n memoryPool.reallocate(oldHeapBuffer, newSize);\n\n if (newBuffer != null) {\n ProbeNotifier.notifyBufferAllocatedFromPool(monitoringConfig,\n newSize - oldHeapBuffer.capacity());\n\n return newBuffer;\n }\n }\n \n final HeapBuffer newHeapBuffer = allocateHeapBuffer(newSize);\n oldHeapBuffer.flip();\n return newHeapBuffer.put(oldHeapBuffer);\n }\n\n\n protected final void releaseHeapBuffer(final HeapBuffer heapBuffer) {\n final ThreadLocalPool memoryPool = getHeapBufferThreadLocalPool();\n if (memoryPool != null) {\n\n if (memoryPool.release(heapBuffer.clear())) {\n ProbeNotifier.notifyBufferReleasedToPool(monitoringConfig,\n heapBuffer.capacity());\n }\n }\n\n }\n\n\n // --------------------------------------------------------- Private Methods\n\n\n private void reallocatePoolBuffer() {\n final byte[] heap = new byte[maxBufferSize];\n ProbeNotifier.notifyBufferAllocated(monitoringConfig, maxBufferSize);\n\n final HeapBufferThreadLocalPool threadLocalCache =\n getHeapBufferThreadLocalPool();\n if (threadLocalCache != null) {\n threadLocalCache.reset(heap, 0, maxBufferSize);\n }\n }\n\n TrimmableHeapBuffer createTrimAwareBuffer(final int length) {\n final byte[] heap = new byte[length];\n ProbeNotifier.notifyBufferAllocated(monitoringConfig, length);\n \n return createTrimAwareBuffer(heap, 0, length);\n }\n\n TrimmableHeapBuffer createTrimAwareBuffer(final byte[] heap,\n final int offset, final int length) {\n\n final TrimmableHeapBuffer buffer = ThreadCache.takeFromCache(CACHE_IDX);\n if (buffer != null) {\n buffer.initialize(this, heap, offset, length);\n return buffer;\n }\n\n return new TrimmableHeapBuffer(this, heap, offset, length);\n }\n\n private ByteBufferWrapper createByteBufferWrapper(\n final ByteBuffer underlyingByteBuffer) {\n\n final RecyclableByteBufferWrapper buffer = ThreadCache.takeFromCache(BBW_CACHE_IDX);\n if (buffer != null) {\n buffer.initialize(underlyingByteBuffer);\n return buffer;\n }\n\n return new RecyclableByteBufferWrapper(underlyingByteBuffer);\n }\n\n @SuppressWarnings(\"unchecked\")\n private static HeapBufferThreadLocalPool getHeapBufferThreadLocalPool() {\n final ThreadLocalPool pool = getThreadLocalPool();\n return ((pool instanceof HeapBufferThreadLocalPool)\n ? (HeapBufferThreadLocalPool) pool\n : null);\n }\n\n\n // ---------------------------------------------------------- Nested Classes\n\n\n /**\n * Information about thread associated memory pool.\n */\n private static final class HeapBufferThreadLocalPool implements ThreadLocalPool {\n /**\n * Memory pool\n */\n private byte[] pool;\n\n private int pos;\n private int lim;\n\n private final ByteBuffer[] byteBufferCache;\n private int byteBufferCacheSize = 0;\n private final HeapMemoryManager mm;\n \n public HeapBufferThreadLocalPool(final HeapMemoryManager mm) {\n this(mm, 8);\n }\n\n public HeapBufferThreadLocalPool(final HeapMemoryManager mm,\n final int maxByteBufferCacheSize) {\n byteBufferCache = new ByteBuffer[maxByteBufferCacheSize];\n this.mm = mm;\n }\n\n @Override\n public HeapBuffer allocate(final int size) {\n final HeapBuffer allocated = mm.createTrimAwareBuffer(pool, pos, size);\n if (byteBufferCacheSize > 0) {\n allocated.byteBuffer = byteBufferCache[--byteBufferCacheSize];\n byteBufferCache[byteBufferCacheSize] = null;\n }\n\n pos += size;\n return allocated;\n }\n\n @Override\n public HeapBuffer reallocate(final HeapBuffer heapBuffer, final int newSize) {\n final int diff;\n\n if (isLastAllocated(heapBuffer)\n && remaining() >= (diff = (newSize - heapBuffer.cap))) {\n\n pos += diff;\n heapBuffer.cap = newSize;\n heapBuffer.lim = newSize;\n\n return heapBuffer;\n }\n\n return null;\n }\n\n @Override\n public boolean release(final HeapBuffer heapBuffer) {\n boolean canCacheByteBuffer =\n heapBuffer.byteBuffer != null &&\n byteBufferCacheSize < byteBufferCache.length;\n\n final boolean result;\n\n if (isLastAllocated(heapBuffer)) {\n pos -= heapBuffer.cap;\n\n result = true;\n } else if (wantReset(heapBuffer.cap)) {\n reset(heapBuffer);\n \n result = true;\n } else {\n canCacheByteBuffer = canCacheByteBuffer && (pool == heapBuffer.heap);\n result = false;\n }\n\n if (canCacheByteBuffer) {\n byteBufferCache[byteBufferCacheSize++] = heapBuffer.byteBuffer;\n }\n\n return result;\n }\n\n @Override\n public void reset(final HeapBuffer heapBuffer) {\n final byte[] heap = heapBuffer.array();\n if (pool != heap) {\n clearByteBufferCache();\n pool = heap;\n }\n\n pos = heapBuffer.offset;\n lim = pos + heapBuffer.cap;\n }\n\n public void reset(final byte[] heap, final int offset, final int capacity) {\n if (pool != heap) {\n clearByteBufferCache();\n }\n \n pool = heap;\n pos = offset;\n lim = capacity;\n }\n\n @Override\n public boolean wantReset(final int size) {\n return size - remaining() > 1024;\n }\n\n @Override\n public boolean isLastAllocated(final HeapBuffer oldHeapBuffer) {\n return oldHeapBuffer.heap == pool &&\n (oldHeapBuffer.offset + oldHeapBuffer.cap == pos);\n }\n\n @Override\n public HeapBuffer reduceLastAllocated(final HeapBuffer heapBuffer) {\n pos = heapBuffer.offset + heapBuffer.cap;\n\n return null;\n }\n\n @Override\n public int remaining() {\n return lim - pos;\n }\n\n @Override\n public boolean hasRemaining() {\n return pos < lim;\n }\n\n @Override\n public String toString() {\n return \"(pool=\" + pool.length +\n \" pos=\" + pos +\n \" cap=\" + lim\n + ')';\n }\n\n private void clearByteBufferCache() {\n Arrays.fill(byteBufferCache, 0, byteBufferCacheSize, null);\n byteBufferCacheSize = 0;\n }\n\n\n } // END ByteBufferThreadLocalPool\n\n\n /**\n * {@link HeapBuffer} implementation, which supports trimming. In\n * other words it's possible to return unused {@link org.glassfish.grizzly.Buffer} space to\n * pool.\n */\n private static final class TrimmableHeapBuffer extends HeapBuffer\n implements TrimAware {\n\n private HeapMemoryManager mm;\n \n private TrimmableHeapBuffer(final HeapMemoryManager mm,\n byte[] heap,\n int offset,\n int capacity) {\n super(heap, offset, capacity);\n this.mm = mm;\n }\n\n @Override\n public void trim() {\n checkDispose();\n\n final int sizeToReturn = cap - pos;\n\n\n if (sizeToReturn > 0) {\n final HeapBufferThreadLocalPool threadLocalCache =\n getHeapBufferThreadLocalPool();\n if (threadLocalCache != null) {\n\n if (threadLocalCache.isLastAllocated(this)) {\n flip();\n cap = lim;\n threadLocalCache.reduceLastAllocated(this);\n\n return;\n } else if (threadLocalCache.wantReset(sizeToReturn)) {\n flip();\n\n cap = lim;\n\n threadLocalCache.reset(heap, offset + cap, sizeToReturn);\n return;\n }\n }\n }\n\n super.trim();\n }\n\n @Override\n public void recycle() {\n allowBufferDispose = false;\n\n ThreadCache.putToCache(CACHE_IDX, this);\n }\n\n @Override\n public void dispose() {\n prepareDispose();\n mm.release(this);\n mm = null;\n\n byteBuffer = null;\n heap = null;\n pos = 0;\n offset = 0;\n lim = 0;\n cap = 0;\n recycle();\n }\n\n @Override\n protected HeapBuffer createHeapBuffer(final byte[] heap,\n final int offset,\n final int capacity) {\n return mm.createTrimAwareBuffer(heap, offset, capacity);\n }\n\n void initialize(final HeapMemoryManager mm,\n final byte[] heap,\n final int offset,\n final int length) {\n\n this.mm = mm;\n this.heap = heap;\n this.offset = offset;\n pos = 0;\n cap = length;\n lim = length;\n \n disposeStackTrace = null;\n }\n } // END TrimAwareWrapper\n\n private final static class RecyclableByteBufferWrapper extends ByteBufferWrapper\n implements Cacheable {\n\n private RecyclableByteBufferWrapper(final ByteBuffer underlyingByteBuffer) {\n super(underlyingByteBuffer);\n }\n\n @Override\n public void recycle() {\n allowBufferDispose = false;\n\n ThreadCache.putToCache(BBW_CACHE_IDX, this);\n }\n\n @Override\n public void dispose() {\n super.dispose();\n recycle();\n }\n\n private void initialize(final ByteBuffer underlyingByteBuffer) {\n visible = underlyingByteBuffer;\n disposeStackTrace = null;\n }\n\n }\n}\n =================================================================== --- ../../../dev/grizzly2_git/modules/grizzly/src/main/java/org/glassfish/grizzly/memory/HeapMemoryManager.java (revision f240c6e3d8d6eb69e7a34c692bf76e950cbda1f8) +++ ../../../dev/grizzly2_git/modules/grizzly/src/main/java/org/glassfish/grizzly/memory/HeapMemoryManager.java (revision ) @@ -45,6 +45,7 @@ import org.glassfish.grizzly.monitoring.jmx.JmxObject; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.nio.charset.Charset; import java.util.Arrays; import org.glassfish.grizzly.Buffer; @@ -544,6 +545,8 @@ offset = 0; lim = 0; cap = 0; + order = ByteOrder.BIG_ENDIAN; + bigEndian = true; recycle(); }