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 }