/* * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
// The number of temp buffers in our pool privatestaticfinalint TEMP_BUF_POOL_SIZE = IOUtil.IOV_MAX;
// The max size allowed for a cached temp buffer, in bytes privatestaticfinallong MAX_CACHED_BUFFER_SIZE = getMaxCachedBufferSize();
// Per-carrier-thread cache of temporary direct buffers privatestatic TerminatingThreadLocal<BufferCache> bufferCache = new TerminatingThreadLocal<>() {
@Override protected BufferCache initialValue() { returnnew BufferCache();
}
@Override protectedvoid threadTerminated(BufferCache cache) { // will never be null while (!cache.isEmpty()) {
ByteBuffer bb = cache.removeFirst();
free(bb);
}
}
};
/** * Returns the max size allowed for a cached temp buffers, in * bytes. It defaults to Long.MAX_VALUE. It can be set with the * jdk.nio.maxCachedBufferSize property. Even though * ByteBuffer.capacity() returns an int, we're using a long here * for potential future-proofing.
*/ privatestaticlong getMaxCachedBufferSize() {
String s = GetPropertyAction.privilegedGetProperty("jdk.nio.maxCachedBufferSize"); if (s != null) { try { long m = Long.parseLong(s); if (m >= 0) { return m;
} else { // if it's negative, ignore the system property
}
} catch (NumberFormatException e) { // if the string is not well formed, ignore the system property
}
} returnLong.MAX_VALUE;
}
/** * Returns true if a buffer of this size is too large to be * added to the buffer cache, false otherwise.
*/ privatestaticboolean isBufferTooLarge(int size) { return size > MAX_CACHED_BUFFER_SIZE;
}
/** * Returns true if the buffer is too large to be added to the * buffer cache, false otherwise.
*/ privatestaticboolean isBufferTooLarge(ByteBuffer buf) { return isBufferTooLarge(buf.capacity());
}
/** * A simple cache of direct buffers.
*/ privatestaticclass BufferCache { // the array of buffers private ByteBuffer[] buffers;
// the number of buffers in the cache privateint count;
// the index of the first valid buffer (undefined if count == 0) privateint start;
BufferCache() {
buffers = new ByteBuffer[TEMP_BUF_POOL_SIZE];
}
/** * Removes and returns a buffer from the cache of at least the given * size (or null if no suitable buffer is found).
*/
ByteBuffer get(int size) { // Don't call this if the buffer would be too large. assert !isBufferTooLarge(size);
if (count == 0) returnnull; // cache is empty
ByteBuffer[] buffers = this.buffers;
// search for suitable buffer (often the first buffer will do)
ByteBuffer buf = buffers[start]; if (buf.capacity() < size) {
buf = null; int i = start; while ((i = next(i)) != start) {
ByteBuffer bb = buffers[i]; if (bb == null) break; if (bb.capacity() >= size) {
buf = bb; break;
}
} if (buf == null) returnnull; // move first element to here to avoid re-packing
buffers[i] = buffers[start];
}
// remove first element
buffers[start] = null;
start = next(start);
count--;
// prepare the buffer and return it
buf.rewind();
buf.limit(size); return buf;
}
boolean offerFirst(ByteBuffer buf) { // Don't call this if the buffer is too large. assert !isBufferTooLarge(buf);
/** * Returns a temporary buffer of at least the given size
*/ publicstatic ByteBuffer getTemporaryDirectBuffer(int size) { // If a buffer of this size is too large for the cache, there // should not be a buffer in the cache that is at least as // large. So we'll just create a new one. Also, we don't have // to remove the buffer from the cache (as this method does // below) given that we won't put the new buffer in the cache. if (isBufferTooLarge(size)) { return ByteBuffer.allocateDirect(size);
}
BufferCache cache = bufferCache.get();
ByteBuffer buf = cache.get(size); if (buf != null) { return buf;
} else { // No suitable buffer in the cache so we need to allocate a new // one. To avoid the cache growing then we remove the first // buffer from the cache and free it. if (!cache.isEmpty()) {
buf = cache.removeFirst();
free(buf);
} return ByteBuffer.allocateDirect(size);
}
}
/** * Returns a temporary buffer of at least the given size and * aligned to the alignment
*/ publicstatic ByteBuffer getTemporaryAlignedDirectBuffer(int size, int alignment) { if (isBufferTooLarge(size)) { return ByteBuffer.allocateDirect(size + alignment - 1)
.alignedSlice(alignment);
}
/** * Releases a temporary buffer by returning to the cache or freeing it.
*/ publicstaticvoid releaseTemporaryDirectBuffer(ByteBuffer buf) {
offerFirstTemporaryDirectBuffer(buf);
}
/** * Releases a temporary buffer by returning to the cache or freeing it. If * returning to the cache then insert it at the start so that it is * likely to be returned by a subsequent call to getTemporaryDirectBuffer.
*/ staticvoid offerFirstTemporaryDirectBuffer(ByteBuffer buf) { // If the buffer is too large for the cache we don't have to // check the cache. We'll just free it. if (isBufferTooLarge(buf)) {
free(buf); return;
}
assert buf != null;
BufferCache cache = bufferCache.get(); if (!cache.offerFirst(buf)) { // cache is full
free(buf);
}
}
/** * Releases a temporary buffer by returning to the cache or freeing it. If * returning to the cache then insert it at the end. This makes it * suitable for scatter/gather operations where the buffers are returned to * cache in same order that they were obtained.
*/ staticvoid offerLastTemporaryDirectBuffer(ByteBuffer buf) { // If the buffer is too large for the cache we don't have to // check the cache. We'll just free it. if (isBufferTooLarge(buf)) {
free(buf); return;
}
assert buf != null;
BufferCache cache = bufferCache.get(); if (!cache.offerLast(buf)) { // cache is full
free(buf);
}
}
/** * Frees the memory for the given direct buffer
*/ privatestaticvoid free(ByteBuffer buf) {
((DirectBuffer)buf).cleaner().clean();
}
// -- Random stuff --
static ByteBuffer[] subsequence(ByteBuffer[] bs, int offset, int length) { if ((offset == 0) && (length == bs.length)) return bs; int n = length;
ByteBuffer[] bs2 = new ByteBuffer[n]; for (int i = 0; i < n; i++)
bs2[i] = bs[offset + i]; return bs2;
}
staticvoid checkBufferPositionAligned(ByteBuffer bb, int pos, int alignment) throws IOException
{ finalint alignmentOffset = bb.alignmentOffset(pos, alignment); if (alignmentOffset != 0) { thrownew IOException("Current position of the bytebuffer ("
+ pos + ") is not a multiple of the block size ("
+ alignment + "): alignment offset = " + alignmentOffset);
}
}
staticvoid checkRemainingBufferSizeAligned(int rem, int alignment) throws IOException
{ if (rem % alignment != 0) { thrownew IOException("Number of remaining bytes ("
+ rem + ") is not a multiple of the block size ("
+ alignment + ")");
}
}
staticvoid checkChannelPositionAligned(long position, int alignment) throws IOException
{ if (position % alignment != 0) { thrownew IOException("Channel position (" + position
+ ") is not a multiple of the block size ("
+ alignment + ")");
}
}
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.31 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.