]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/io/ArrayByteBufferPool.java
Merge "Update notes about password security"
[gigi.git] / lib / jetty / org / eclipse / jetty / io / ArrayByteBufferPool.java
1 //
2 //  ========================================================================
3 //  Copyright (c) 1995-2016 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.
8 //
9 //      The Eclipse Public License is available at
10 //      http://www.eclipse.org/legal/epl-v10.html
11 //
12 //      The Apache License v2.0 is available at
13 //      http://www.opensource.org/licenses/apache2.0.php
14 //
15 //  You may elect to redistribute this code under either of these licenses.
16 //  ========================================================================
17 //
18
19 package org.eclipse.jetty.io;
20
21 import java.nio.ByteBuffer;
22 import java.util.Queue;
23 import java.util.concurrent.ConcurrentLinkedQueue;
24
25 import org.eclipse.jetty.util.BufferUtil;
26
27 public class ArrayByteBufferPool implements ByteBufferPool
28 {
29     private final int _min;
30     private final Bucket[] _direct;
31     private final Bucket[] _indirect;
32     private final int _inc;
33
34     public ArrayByteBufferPool()
35     {
36         this(0,1024,64*1024);
37     }
38
39     public ArrayByteBufferPool(int minSize, int increment, int maxSize)
40     {
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");
45         _min=minSize;
46         _inc=increment;
47
48         _direct=new Bucket[maxSize/increment];
49         _indirect=new Bucket[maxSize/increment];
50
51         int size=0;
52         for (int i=0;i<_direct.length;i++)
53         {
54             size+=_inc;
55             _direct[i]=new Bucket(size);
56             _indirect[i]=new Bucket(size);
57         }
58     }
59
60     @Override
61     public ByteBuffer acquire(int size, boolean direct)
62     {
63         Bucket bucket = bucketFor(size,direct);
64         ByteBuffer buffer = bucket==null?null:bucket._queue.poll();
65
66         if (buffer == null)
67         {
68             int capacity = bucket==null?size:bucket._size;
69             buffer = direct ? BufferUtil.allocateDirect(capacity) : BufferUtil.allocate(capacity);
70         }
71
72         return buffer;
73     }
74
75     @Override
76     public void release(ByteBuffer buffer)
77     {
78         if (buffer!=null)
79         {    
80             Bucket bucket = bucketFor(buffer.capacity(),buffer.isDirect());
81             if (bucket!=null)
82             {
83                 BufferUtil.clear(buffer);
84                 bucket._queue.offer(buffer);
85             }
86         }
87     }
88
89     public void clear()
90     {
91         for (int i=0;i<_direct.length;i++)
92         {
93             _direct[i]._queue.clear();
94             _indirect[i]._queue.clear();
95         }
96     }
97
98     private Bucket bucketFor(int size,boolean direct)
99     {
100         if (size<=_min)
101             return null;
102         int b=(size-1)/_inc;
103         if (b>=_direct.length)
104             return null;
105         Bucket bucket = direct?_direct[b]:_indirect[b];
106                 
107         return bucket;
108     }
109
110     public static class Bucket
111     {
112         public final int _size;
113         public final Queue<ByteBuffer> _queue= new ConcurrentLinkedQueue<>();
114
115         Bucket(int size)
116         {
117             _size=size;
118         }
119         
120         @Override
121         public String toString()
122         {
123             return String.format("Bucket@%x{%d,%d}",hashCode(),_size,_queue.size());
124         }
125     }
126     
127
128     // Package local for testing
129     Bucket[] bucketsFor(boolean direct)
130     {
131         return direct ? _direct : _indirect;
132     }
133 }