1 // ========================================================================
2 // Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
3 // ------------------------------------------------------------------------
4 // All rights reserved. This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v1.0
6 // and Apache License v2.0 which accompanies this distribution.
7 // The Eclipse Public License is available at
8 // http://www.eclipse.org/legal/epl-v10.html
9 // The Apache License v2.0 is available at
10 // http://www.opensource.org/licenses/apache2.0.php
11 // You may elect to redistribute this code under either of these licenses.
12 // ========================================================================
13
14 package org.eclipse.jetty.io;
15
16
17 /* ------------------------------------------------------------ */
18 /** Abstract Buffer pool.
19 * simple unbounded pool of buffers for header, request and response sizes.
20 *
21 */
22 public abstract class ThreadLocalBuffers implements Buffers
23 {
24 private int _bufferSize=12*1024;
25 private int _headerSize=6*1024;
26
27 /* ------------------------------------------------------------ */
28 private final ThreadLocal<ThreadBuffers> _buffers=new ThreadLocal<ThreadBuffers>()
29 {
30 @Override
31 protected ThreadBuffers initialValue()
32 {
33 return new ThreadBuffers();
34 }
35 };
36
37 /* ------------------------------------------------------------ */
38 public ThreadLocalBuffers()
39 {
40 }
41
42 /* ------------------------------------------------------------ */
43 public Buffer getBuffer()
44 {
45 ThreadBuffers buffers = _buffers.get();
46 if (buffers._buffer!=null)
47 {
48 Buffer b=buffers._buffer;
49 buffers._buffer=null;
50 return b;
51 }
52
53 if (buffers._other!=null && buffers._other.capacity()==_bufferSize)
54 {
55 Buffer b=buffers._other;
56 buffers._other=null;
57 return b;
58 }
59
60 return newBuffer(_bufferSize);
61 }
62
63 /* ------------------------------------------------------------ */
64 public Buffer getHeader()
65 {
66 ThreadBuffers buffers = _buffers.get();
67 if (buffers._header!=null)
68 {
69 Buffer b=buffers._header;
70 buffers._header=null;
71 return b;
72 }
73
74 if (buffers._other!=null && buffers._other.capacity()==_headerSize && isHeader(buffers._other))
75 {
76 Buffer b=buffers._other;
77 buffers._other=null;
78 return b;
79 }
80
81 return newHeader(_headerSize);
82 }
83
84 /* ------------------------------------------------------------ */
85 public Buffer getBuffer(int size)
86 {
87 ThreadBuffers buffers = _buffers.get();
88 if (buffers._other!=null && buffers._other.capacity()==size)
89 {
90 Buffer b=buffers._other;
91 buffers._other=null;
92 return b;
93 }
94
95 return newBuffer(size);
96 }
97
98 /* ------------------------------------------------------------ */
99 public void returnBuffer(Buffer buffer)
100 {
101 buffer.clear();
102 if (buffer.isVolatile() || buffer.isImmutable())
103 return;
104
105 int size=buffer.capacity();
106
107 ThreadBuffers buffers = _buffers.get();
108
109 if (buffers._header==null && size==_headerSize && isHeader(buffer))
110 buffers._header=buffer;
111 else if (size==_bufferSize && buffers._buffer==null)
112 buffers._buffer=buffer;
113 else
114 buffers._other=buffer;
115 }
116
117
118
119 /* ------------------------------------------------------------ */
120 /**
121 * @return Returns the buffer size in bytes.
122 */
123 public int getBufferSize()
124 {
125 return _bufferSize;
126 }
127
128 /* ------------------------------------------------------------ */
129 /**
130 * @return Returns the header size in bytes.
131 */
132 public int getHeaderSize()
133 {
134 return _headerSize;
135 }
136
137 /* ------------------------------------------------------------ */
138 /**
139 * Create a new content Buffer
140 * @param size
141 * @return new Buffer
142 */
143 protected abstract Buffer newBuffer(int size);
144
145 /* ------------------------------------------------------------ */
146 /**
147 * Create a new header Buffer
148 * @param size
149 * @return new Buffer
150 */
151 protected abstract Buffer newHeader(int size);
152
153 /* ------------------------------------------------------------ */
154 /**
155 * @param buffer
156 * @return True if the buffer is the correct type to be a Header buffer
157 */
158 protected abstract boolean isHeader(Buffer buffer);
159
160 /* ------------------------------------------------------------ */
161 /**
162 * @param size The buffer size in bytes
163 */
164 public void setBufferSize( int size )
165 {
166 _bufferSize = size;
167 }
168
169 /* ------------------------------------------------------------ */
170 /**
171 * @param size The header size in bytes
172 */
173 public void setHeaderSize( int size )
174 {
175 _headerSize = size;
176 }
177
178 /* ------------------------------------------------------------ */
179 @Override
180 public String toString()
181 {
182 return "{{"+getHeaderSize()+","+getBufferSize()+"}}";
183 }
184
185 /* ------------------------------------------------------------ */
186 /* ------------------------------------------------------------ */
187 protected static class ThreadBuffers
188 {
189 Buffer _buffer;
190 Buffer _header;
191 Buffer _other;
192 }
193 }