2 // ========================================================================
3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
19 package org.eclipse.jetty.io;
21 import java.nio.ByteBuffer;
22 import java.util.Queue;
23 import java.util.concurrent.ConcurrentLinkedQueue;
25 import org.eclipse.jetty.util.BufferUtil;
27 public class ArrayByteBufferPool implements ByteBufferPool
29 private final int _min;
30 private final Bucket[] _direct;
31 private final Bucket[] _indirect;
32 private final int _inc;
34 public ArrayByteBufferPool()
39 public ArrayByteBufferPool(int minSize, int increment, int maxSize)
41 if (minSize>=increment)
42 throw new IllegalArgumentException("minSize >= increment");
43 if ((maxSize%increment)!=0 || increment>=maxSize)
44 throw new IllegalArgumentException("increment must be a divisor of maxSize");
48 _direct=new Bucket[maxSize/increment];
49 _indirect=new Bucket[maxSize/increment];
52 for (int i=0;i<_direct.length;i++)
55 _direct[i]=new Bucket(size);
56 _indirect[i]=new Bucket(size);
61 public ByteBuffer acquire(int size, boolean direct)
63 Bucket bucket = bucketFor(size,direct);
64 ByteBuffer buffer = bucket==null?null:bucket._queue.poll();
68 int capacity = bucket==null?size:bucket._size;
69 buffer = direct ? BufferUtil.allocateDirect(capacity) : BufferUtil.allocate(capacity);
76 public void release(ByteBuffer buffer)
80 Bucket bucket = bucketFor(buffer.capacity(),buffer.isDirect());
83 BufferUtil.clear(buffer);
84 bucket._queue.offer(buffer);
91 for (int i=0;i<_direct.length;i++)
93 _direct[i]._queue.clear();
94 _indirect[i]._queue.clear();
98 private Bucket bucketFor(int size,boolean direct)
103 if (b>=_direct.length)
105 Bucket bucket = direct?_direct[b]:_indirect[b];
110 public static class Bucket
112 public final int _size;
113 public final Queue<ByteBuffer> _queue= new ConcurrentLinkedQueue<>();
121 public String toString()
123 return String.format("Bucket@%x{%d,%d}",hashCode(),_size,_queue.size());
128 // Package local for testing
129 Bucket[] bucketsFor(boolean direct)
131 return direct ? _direct : _indirect;