View Javadoc

1   //========================================================================
2   //Copyright 2004-2008 Mort Bay Consulting Pty. Ltd.
3   //------------------------------------------------------------------------
4   //Licensed under the Apache License, Version 2.0 (the "License");
5   //you may not use this file except in compliance with the License.
6   //You may obtain a copy of the License at 
7   //http://www.apache.org/licenses/LICENSE-2.0
8   //Unless required by applicable law or agreed to in writing, software
9   //distributed under the License is distributed on an "AS IS" BASIS,
10  //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  //See the License for the specific language governing permissions and
12  //limitations under the License.
13  //========================================================================
14  
15  package org.mortbay.jetty;
16  
17  import java.util.ArrayList;
18  
19  import org.mortbay.component.AbstractLifeCycle;
20  import org.mortbay.io.Buffer;
21  import org.mortbay.io.Buffers;
22  
23  /* ------------------------------------------------------------ */
24  /** Abstract Buffer pool.
25   * simple unbounded pool of buffers.
26   * @author gregw
27   *
28   */
29  public abstract class AbstractBuffers extends AbstractLifeCycle implements Buffers
30  {
31      private int _headerBufferSize=4*1024;
32      private int _requestBufferSize=8*1024;
33      private int _responseBufferSize=24*1024;
34  
35      final static private int __HEADER=0;
36      final static private int __REQUEST=1;
37      final static private int __RESPONSE=2;
38      final static private int __OTHER=3;
39      final private int[] _pool={2,1,1,2};
40  
41      private final ThreadLocal _buffers=new ThreadLocal()
42      {
43          protected Object initialValue()
44          {
45              return new ThreadBuffers(_pool[__HEADER],_pool[__REQUEST],_pool[__RESPONSE],_pool[__OTHER]);
46          }
47      };
48     
49      public AbstractBuffers()
50      {
51          super();
52      }
53  
54  
55  
56      public Buffer getBuffer(final int size )
57      {
58          final int set = (size==_headerBufferSize)?__HEADER
59                  :(size==_responseBufferSize)?__RESPONSE
60                          :(size==_requestBufferSize)?__REQUEST:__OTHER;
61  
62          final ThreadBuffers thread_buffers = (ThreadBuffers)_buffers.get();
63  
64          final Buffer[] buffers=thread_buffers._buffers[set];
65          for (int i=0;i<buffers.length;i++)
66          {
67              final Buffer b=buffers[i];
68              if (b!=null && b.capacity()==size)
69              {
70                  buffers[i]=null;
71                  return b;
72              }
73          }
74  
75          return newBuffer(size);
76      }
77  
78      public void returnBuffer( Buffer buffer )
79      {
80          buffer.clear();
81          if (buffer.isVolatile() || buffer.isImmutable())
82              return;
83  
84          int size=buffer.capacity();
85          final int set = (size==_headerBufferSize)?__HEADER
86                  :(size==_responseBufferSize)?__RESPONSE
87                          :(size==_requestBufferSize)?__REQUEST:__OTHER;
88          
89          final ThreadBuffers thread_buffers = (ThreadBuffers)_buffers.get();
90          final Buffer[] buffers=thread_buffers._buffers[set];
91          for (int i=0;i<buffers.length;i++)
92          {
93              if (buffers[i]==null)
94              {
95                  buffers[i]=buffer;
96                  return;
97              }
98          }
99  
100     }
101 
102     protected void doStart()
103         throws Exception
104     {
105         super.doStart();
106         if (_headerBufferSize==_requestBufferSize && _headerBufferSize==_responseBufferSize)
107         {
108             _pool[__HEADER]+=_pool[__REQUEST]+_pool[__RESPONSE];
109             _pool[__REQUEST]=0;
110             _pool[__RESPONSE]=0;
111         }
112         else if (_headerBufferSize==_requestBufferSize)
113         {
114             _pool[__HEADER]+=_pool[__REQUEST];
115             _pool[__REQUEST]=0;
116         }
117         else if (_headerBufferSize==_responseBufferSize)
118         {
119             _pool[__HEADER]+=_pool[__RESPONSE];
120             _pool[__RESPONSE]=0;
121         }
122         else if (_requestBufferSize==_responseBufferSize)
123         {
124             _pool[__RESPONSE]+=_pool[__REQUEST];
125             _pool[__REQUEST]=0;
126         }
127 
128     }
129 
130     /**
131      * @return Returns the headerBufferSize.
132      */
133     public int getHeaderBufferSize()
134     {
135         return _headerBufferSize;
136     }
137 
138     /**
139      * @param headerBufferSize The headerBufferSize to set.
140      */
141     public void setHeaderBufferSize( int headerBufferSize )
142     {
143         if (isStarted())
144             throw new IllegalStateException();
145         _headerBufferSize = headerBufferSize;
146     }
147 
148     /**
149      * @return Returns the requestBufferSize.
150      */
151     public int getRequestBufferSize()
152     {
153         return _requestBufferSize;
154     }
155 
156     /**
157      * @param requestBufferSize The requestBufferSize to set.
158      */
159     public void setRequestBufferSize( int requestBufferSize )
160     {
161         if (isStarted())
162           throw new IllegalStateException();
163         _requestBufferSize = requestBufferSize;
164     }
165 
166     /**
167      * @return Returns the responseBufferSize.
168      */
169     public int getResponseBufferSize()
170     {
171         return _responseBufferSize;
172     }
173 
174     /**
175      * @param responseBufferSize The responseBufferSize to set.
176      */
177     public void setResponseBufferSize( int responseBufferSize )
178     {
179         if (isStarted())
180             throw new IllegalStateException();
181         _responseBufferSize = responseBufferSize;
182     }
183     
184     protected abstract Buffer newBuffer( int size );
185 
186     protected static class ThreadBuffers
187     {
188         final Buffer[][] _buffers;
189         ThreadBuffers(int headers,int requests,int responses,int others)
190         {
191             _buffers = new Buffer[4][];
192             _buffers[__HEADER]=new Buffer[headers];
193             _buffers[__REQUEST]=new Buffer[requests];
194             _buffers[__RESPONSE]=new Buffer[responses];
195             _buffers[__OTHER]=new Buffer[others];
196 
197         }
198     }
199     
200     public String toString()
201     {
202         return "{{"+_headerBufferSize+","+_requestBufferSize+","+_responseBufferSize+"}}";
203     }
204 }