diff options
Diffstat (limited to 'jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardByteBufferPool.java')
-rw-r--r-- | jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardByteBufferPool.java | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardByteBufferPool.java b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardByteBufferPool.java new file mode 100644 index 0000000000..60b6190bf2 --- /dev/null +++ b/jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/StandardByteBufferPool.java @@ -0,0 +1,97 @@ +//======================================================================== +//Copyright 2011-2012 Mort Bay Consulting Pty. Ltd. +//------------------------------------------------------------------------ +//All rights reserved. This program and the accompanying materials +//are made available under the terms of the Eclipse Public License v1.0 +//and Apache License v2.0 which accompanies this distribution. +//The Eclipse Public License is available at +//http://www.eclipse.org/legal/epl-v10.html +//The Apache License v2.0 is available at +//http://www.opensource.org/licenses/apache2.0.php +//You may elect to redistribute this code under either of these licenses. +//======================================================================== + +package org.eclipse.jetty.spdy; + +import java.nio.ByteBuffer; +import java.util.Queue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ConcurrentMap; + +public class StandardByteBufferPool implements ByteBufferPool +{ + private final ConcurrentMap<Integer, Queue<ByteBuffer>> directBuffers = new ConcurrentHashMap<>(); + private final ConcurrentMap<Integer, Queue<ByteBuffer>> heapBuffers = new ConcurrentHashMap<>(); + private final int factor; + + public StandardByteBufferPool() + { + this(1024); + } + + public StandardByteBufferPool(int factor) + { + this.factor = factor; + } + + public ByteBuffer acquire(int size, boolean direct) + { + int bucket = bucketFor(size); + ConcurrentMap<Integer, Queue<ByteBuffer>> buffers = buffersFor(direct); + + ByteBuffer result = null; + Queue<ByteBuffer> byteBuffers = buffers.get(bucket); + if (byteBuffers != null) + result = byteBuffers.poll(); + + if (result == null) + { + int capacity = bucket * factor; + result = direct ? ByteBuffer.allocateDirect(capacity) : ByteBuffer.allocate(capacity); + } + + result.clear(); + result.limit(size); + + return result; + } + + public void release(ByteBuffer buffer) + { + int bucket = bucketFor(buffer.capacity()); + ConcurrentMap<Integer, Queue<ByteBuffer>> buffers = buffersFor(buffer.isDirect()); + + // Avoid to create a new queue every time, just to be discarded immediately + Queue<ByteBuffer> byteBuffers = buffers.get(bucket); + if (byteBuffers == null) + { + byteBuffers = new ConcurrentLinkedQueue<>(); + Queue<ByteBuffer> existing = buffers.putIfAbsent(bucket, byteBuffers); + if (existing != null) + byteBuffers = existing; + } + + buffer.clear(); + byteBuffers.offer(buffer); + } + + public void clear() + { + directBuffers.clear(); + heapBuffers.clear(); + } + + private int bucketFor(int size) + { + int bucket = size / factor; + if (size % factor > 0) + ++bucket; + return bucket; + } + + private ConcurrentMap<Integer, Queue<ByteBuffer>> buffersFor(boolean direct) + { + return direct ? directBuffers : heapBuffers; + } +} |