1 //
2 // ========================================================================
3 // Copyright (c) 1995-2015 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.ArrayList;
23 import java.util.List;
24
25 import org.eclipse.jetty.util.BufferUtil;
26
27 /**
28 * <p>A {@link ByteBuffer} pool.</p>
29 * <p>Acquired buffers may be {@link #release(ByteBuffer) released} but they do not need to;
30 * if they are released, they may be recycled and reused, otherwise they will be garbage
31 * collected as usual.</p>
32 */
33 public interface ByteBufferPool
34 {
35 /**
36 * <p>Requests a {@link ByteBuffer} of the given size.</p>
37 * <p>The returned buffer may have a bigger capacity than the size being
38 * requested but it will have the limit set to the given size.</p>
39 *
40 * @param size the size of the buffer
41 * @param direct whether the buffer must be direct or not
42 * @return the requested buffer
43 * @see #release(ByteBuffer)
44 */
45 public ByteBuffer acquire(int size, boolean direct);
46
47 /**
48 * <p>Returns a {@link ByteBuffer}, usually obtained with {@link #acquire(int, boolean)}
49 * (but not necessarily), making it available for recycling and reuse.</p>
50 *
51 * @param buffer the buffer to return
52 * @see #acquire(int, boolean)
53 */
54 public void release(ByteBuffer buffer);
55
56 public static class Lease
57 {
58 private final ByteBufferPool byteBufferPool;
59 private final List<ByteBuffer> buffers;
60 private final List<Boolean> recycles;
61
62 public Lease(ByteBufferPool byteBufferPool)
63 {
64 this.byteBufferPool = byteBufferPool;
65 this.buffers = new ArrayList<>();
66 this.recycles = new ArrayList<>();
67 }
68
69 public ByteBuffer acquire(int capacity, boolean direct)
70 {
71 ByteBuffer buffer = byteBufferPool.acquire(capacity, direct);
72 BufferUtil.clearToFill(buffer);
73 return buffer;
74 }
75
76 public void append(ByteBuffer buffer, boolean recycle)
77 {
78 buffers.add(buffer);
79 recycles.add(recycle);
80 }
81
82 public void insert(int index, ByteBuffer buffer, boolean recycle)
83 {
84 buffers.add(index, buffer);
85 recycles.add(index, recycle);
86 }
87
88 public List<ByteBuffer> getByteBuffers()
89 {
90 return buffers;
91 }
92
93 public long getTotalLength()
94 {
95 long length = 0;
96 for (int i = 0; i < buffers.size(); ++i)
97 length += buffers.get(i).remaining();
98 return length;
99 }
100
101 public int getSize()
102 {
103 return buffers.size();
104 }
105
106 public void recycle()
107 {
108 for (int i = 0; i < buffers.size(); ++i)
109 {
110 ByteBuffer buffer = buffers.get(i);
111 if (recycles.get(i))
112 byteBufferPool.release(buffer);
113 }
114 buffers.clear();
115 recycles.clear();
116 }
117 }
118 }