1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.eclipse.jetty.spdy;
18
19 import java.nio.ByteBuffer;
20 import java.util.Queue;
21 import java.util.concurrent.ConcurrentHashMap;
22 import java.util.concurrent.ConcurrentLinkedQueue;
23 import java.util.concurrent.ConcurrentMap;
24
25 public class StandardByteBufferPool implements ByteBufferPool
26 {
27 private final ConcurrentMap<Integer, Queue<ByteBuffer>> directBuffers = new ConcurrentHashMap<>();
28 private final ConcurrentMap<Integer, Queue<ByteBuffer>> heapBuffers = new ConcurrentHashMap<>();
29 private final int factor;
30
31 public StandardByteBufferPool()
32 {
33 this(1024);
34 }
35
36 public StandardByteBufferPool(int factor)
37 {
38 this.factor = factor;
39 }
40
41 public ByteBuffer acquire(int size, boolean direct)
42 {
43 int bucket = bucketFor(size);
44 ConcurrentMap<Integer, Queue<ByteBuffer>> buffers = buffersFor(direct);
45
46 ByteBuffer result = null;
47 Queue<ByteBuffer> byteBuffers = buffers.get(bucket);
48 if (byteBuffers != null)
49 result = byteBuffers.poll();
50
51 if (result == null)
52 {
53 int capacity = bucket * factor;
54 result = direct ? ByteBuffer.allocateDirect(capacity) : ByteBuffer.allocate(capacity);
55 }
56
57 result.clear();
58 result.limit(size);
59
60 return result;
61 }
62
63 public void release(ByteBuffer buffer)
64 {
65 int bucket = bucketFor(buffer.capacity());
66 ConcurrentMap<Integer, Queue<ByteBuffer>> buffers = buffersFor(buffer.isDirect());
67
68
69 Queue<ByteBuffer> byteBuffers = buffers.get(bucket);
70 if (byteBuffers == null)
71 {
72 byteBuffers = new ConcurrentLinkedQueue<>();
73 Queue<ByteBuffer> existing = buffers.putIfAbsent(bucket, byteBuffers);
74 if (existing != null)
75 byteBuffers = existing;
76 }
77
78 buffer.clear();
79 byteBuffers.offer(buffer);
80 }
81
82 public void clear()
83 {
84 directBuffers.clear();
85 heapBuffers.clear();
86 }
87
88 private int bucketFor(int size)
89 {
90 int bucket = size / factor;
91 if (size % factor > 0)
92 ++bucket;
93 return bucket;
94 }
95
96 private ConcurrentMap<Integer, Queue<ByteBuffer>> buffersFor(boolean direct)
97 {
98 return direct ? directBuffers : heapBuffers;
99 }
100 }