1 // 2 // ======================================================================== 3 // Copyright (c) 1995-2014 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 /* ------------------------------------------------------------ */ PooledBuffers(Buffers.Type headerType, int headerSize, Buffers.Type bufferType, int bufferSize, Buffers.Type otherType,int maxSize)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 /* ------------------------------------------------------------ */ getHeader()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 /* ------------------------------------------------------------ */ getBuffer()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 /* ------------------------------------------------------------ */ getBuffer(int size)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 /* ------------------------------------------------------------ */ returnBuffer(Buffer buffer)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 toString()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 } 123