View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 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.util.Queue;
22  import java.util.concurrent.ConcurrentLinkedQueue;
23  import java.util.concurrent.atomic.AtomicInteger;
24  
25  public class PooledBuffers extends AbstractBuffers
26  {
27      private final Queue<Buffer> _headers;
28      private final Queue<Buffer> _buffers;
29      private final Queue<Buffer> _others;
30      private final AtomicInteger _size = new AtomicInteger();
31      private final int _maxSize;
32      private final boolean _otherHeaders;
33      private final boolean _otherBuffers;
34  
35      /* ------------------------------------------------------------ */
36      public PooledBuffers(Buffers.Type headerType, int headerSize, Buffers.Type bufferType, int bufferSize, Buffers.Type otherType,int maxSize)
37      {
38          super(headerType,headerSize,bufferType,bufferSize,otherType);
39          _headers=new ConcurrentLinkedQueue<Buffer>();
40          _buffers=new ConcurrentLinkedQueue<Buffer>();
41          _others=new ConcurrentLinkedQueue<Buffer>();
42          _otherHeaders=headerType==otherType;
43          _otherBuffers=bufferType==otherType;
44          _maxSize=maxSize;
45      }
46  
47      /* ------------------------------------------------------------ */
48      public Buffer getHeader()
49      {
50          Buffer buffer = _headers.poll();
51          if (buffer==null)
52              buffer=newHeader();
53          else
54              _size.decrementAndGet();
55          return buffer;
56      }
57  
58      /* ------------------------------------------------------------ */
59      public Buffer getBuffer()
60      {
61          Buffer buffer = _buffers.poll();
62          if (buffer==null)
63              buffer=newBuffer();
64          else
65              _size.decrementAndGet();
66          return buffer;
67      }
68  
69      /* ------------------------------------------------------------ */
70      public Buffer getBuffer(int size)
71      {
72          if (_otherHeaders && size==getHeaderSize())
73              return getHeader();
74          if (_otherBuffers && size==getBufferSize())
75              return getBuffer();
76  
77          // Look for an other buffer
78          Buffer buffer = _others.poll();
79  
80          // consume all other buffers until one of the right size is found
81          while (buffer!=null && buffer.capacity()!=size)
82          {
83              _size.decrementAndGet();
84              buffer = _others.poll();
85          }
86  
87          if (buffer==null)
88              buffer=newBuffer(size);
89          else
90              _size.decrementAndGet();
91          return buffer;
92      }
93  
94      /* ------------------------------------------------------------ */
95      public void returnBuffer(Buffer buffer)
96      {
97          buffer.clear();
98          if (buffer.isVolatile() || buffer.isImmutable())
99              return;
100 
101         if (_size.incrementAndGet() > _maxSize)
102             _size.decrementAndGet();
103         else
104         {
105             if (isHeader(buffer))
106                 _headers.add(buffer);
107             else if (isBuffer(buffer))
108                 _buffers.add(buffer);
109             else
110                 _others.add(buffer);
111         }
112     }
113 
114     public String toString()
115     {
116         return String.format("%s [%d/%d@%d,%d/%d@%d,%d/%d@-]",
117                 getClass().getSimpleName(),
118                 _headers.size(),_maxSize,_headerSize,
119                 _buffers.size(),_maxSize,_bufferSize,
120                 _others.size(),_maxSize);
121     }
122 }