bufferfactoryimpl.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 428 行

JAVA
428
字号
/* * The Apache Software License, Version 1.1 * * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. The end-user documentation included with the redistribution, if *    any, must include the following acknowlegement: *       "This product includes software developed by the *        Caucho Technology (http://www.caucho.com/)." *    Alternately, this acknowlegement may appear in the software itself, *    if and wherever such third-party acknowlegements normally appear. * * 4. The names "Hessian", "Resin", and "Caucho" must not be used to *    endorse or promote products derived from this software without prior *    written permission. For written permission, please contact *    info@caucho.com. * * 5. Products derived from this software may not be called "Resin" *    nor may "Resin" appear in their names without prior written *    permission of Caucho Technology. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * @author Sam */package com.caucho.portal.generic;import java.io.IOException;import java.io.OutputStream;import java.io.Writer;import java.util.ArrayList;import java.util.logging.Level;import java.util.logging.Logger;public class BufferFactoryImpl implements BufferFactory{  static protected final Logger log =     Logger.getLogger(BufferFactoryImpl.class.getName());  private static int _bufferCount = 10;  private int _bufferSize = 8192;  private int _poolSize = 32;  FreeList<CharBufferImpl> _charBufferFreeList    = new FreeList<CharBufferImpl>(_poolSize);  FreeList<ByteBufferImpl> _byteBufferFreeList    = new FreeList<ByteBufferImpl>(_poolSize);  public void setBufferSize(int bufferSize)  {    synchronized (_byteBufferFreeList) {      synchronized (_charBufferFreeList) {        _byteBufferFreeList.clear();        _charBufferFreeList.clear();        _bufferSize = bufferSize;      }    }  }  public void setPoolSize(int poolSize)  {    synchronized (_byteBufferFreeList) {      synchronized (_charBufferFreeList) {        _poolSize = poolSize;        _byteBufferFreeList.ensureCapacity(poolSize);        _charBufferFreeList.ensureCapacity(poolSize);      }    }  }  public int getDefaultBufferSize()  {    return _bufferSize;  }  public PortletCharBuffer allocateCharBuffer(int capacity)  {    CharBufferImpl b = null;    if (capacity == Integer.MAX_VALUE)      capacity = _bufferSize;    else if (capacity < _bufferSize)      capacity = _bufferSize;    if (capacity == _bufferSize)      b = _charBufferFreeList.allocate();    if (b == null) {      b = new CharBufferImpl(capacity);      if (log.isLoggable(Level.FINEST))        b.log("allocated new with capacity " + capacity);    }    else {      if (log.isLoggable(Level.FINEST))        b.log("allocated reused with capacity " + b.getCapacity());    }    return b;  }  public PortletByteBuffer allocateByteBuffer(int capacity)  {    ByteBufferImpl b = null;    if (capacity == Integer.MAX_VALUE)      capacity = _bufferSize;    else if (capacity <= _bufferSize)      capacity = _bufferSize;    b = _byteBufferFreeList.allocate();    if (b == null) {      b = new ByteBufferImpl(capacity);      if (log.isLoggable(Level.FINEST))        b.log("allocated new with capacity " + capacity);    }    else {      if (log.isLoggable(Level.FINEST))        b.log("allocated reused with capacity " + b.getCapacity());    }    return b;  }    private class CharBufferImpl implements PortletCharBuffer  {    private String _bufferId;    private int _bufferSize;    private char[] _buf;    private int _bufferPos = 0;    public CharBufferImpl(int size)    {      int id = _bufferCount++;      _bufferId = Integer.toString(id, Character.MAX_RADIX);      _bufferSize = size;      _buf = new char[size];    }    void log(String message)    {      if (log.isLoggable(Level.FINEST)) {        message = new StringBuffer(256).append("char buffer ")                                       .append(_bufferId)                                       .append(' ')                                       .append(message)                                       .toString();        log.log(Level.FINEST, message);      }    }    public boolean print(char buf[], int off, int len)    {      if (len > _bufferSize - _bufferPos)        return overrun();      else {        System.arraycopy(buf, off, _buf, _bufferPos, len);        _bufferPos += len;        return true;      }    }    public boolean print(String str, int off, int len)    {      if (len > _bufferSize - _bufferPos)        return overrun();      else {        str.getChars(off, off + len,  _buf, _bufferPos);        _bufferPos += len;        return true;      }    }    public boolean print(int c)    {      if (_bufferPos == _bufferSize)        return overrun();      else {        _buf[_bufferPos++] = (char) c;        return true;      }    }    private boolean overrun()    {      log("overrun");      return false;    }    public void flush(Writer out)      throws IOException    {      if (_bufferPos != 0)  {        log("flush");        out.write(_buf, 0, _bufferPos);        _bufferPos = 0;      }    }    public int size()    {      return _bufferPos;    }    public int getCapacity()    {      return _bufferSize;    }    public void reset()    {      log("reset");      _bufferPos = 0;    }    public void finish()    {      _bufferPos = 0;      log("finish");      if (_bufferSize <= BufferFactoryImpl.this._bufferSize) {        if (!_charBufferFreeList.free(this))          _buf = null;      }      else        _buf = null;    }  }  private class ByteBufferImpl implements PortletByteBuffer  {    private String _bufferId;    private int _bufferSize;    private byte[] _buf;    private int _bufferPos = 0;    public ByteBufferImpl(int size)    {      int id = _bufferCount++;      _bufferId = Integer.toString(id, Character.MAX_RADIX);      _bufferSize = size;      _buf = new byte[size];    }    void log(String message)    {      if (log.isLoggable(Level.FINEST)) {        message = new StringBuffer(256).append("byte buffer ")                                       .append(_bufferId)                                       .append(' ')                                       .append(message)                                       .toString();        log.log(Level.FINEST, message);      }    }    public boolean write(byte[] buf, int off, int len)     {      if (len > _bufferSize - _bufferPos)        return overrun();      else {        System.arraycopy(buf, off, _buf, _bufferPos, len);        _bufferPos += len;        return true;      }    }    /**     * @return false if the buffer is full and the byte could not be written     */    public boolean write(int b)     {      if (_bufferPos == _bufferSize)        return overrun();      else {        _buf[_bufferPos++] = (byte) b;        return true;      }    }    public int size()    {      return _bufferPos;    }    public int getCapacity()    {      return _bufferSize;    }    private boolean overrun()    {      log("overrun");      return false;    }    public void flush(OutputStream out)      throws IOException    {      if (_bufferPos != 0)  {        log("flush");        out.write(_buf, 0, _bufferPos);        _bufferPos = 0;      }    }    public void reset()    {      log("reset");      _bufferPos = 0;    }    public void finish()    {      _bufferPos = 0;      log("finish");      if (_bufferSize <= BufferFactoryImpl.this._bufferSize) {        if (!_byteBufferFreeList.free(this))          _buf = null;      }      else        _buf = null;    }  }  private class FreeList<E>  {    private int _freeListSize;    private ArrayList<E> _freeList;    private long _lastAllocateFail;    public FreeList(int initialCapacity)    {      _freeListSize = initialCapacity;      _freeList = new ArrayList<E>(_freeListSize);    }    public E allocate()    {      synchronized (_freeList) {        int size = _freeList.size();        if (size > 0)          return _freeList.remove(--size);      }      return null;    }    public boolean free(E obj)    {      synchronized (_freeList) {        int size = _freeList.size();        if (size < _freeListSize) {          _freeList.add(obj);          return true;        }        else {          if (log.isLoggable(Level.CONFIG))            log.config("buffer pool overrun, consider increasing buffer-factory pool-size");          return false;        }      }    }    public void clear()    {      synchronized (_freeList) {        _freeList.clear();      }    }    public void ensureCapacity(int capacity)    {      synchronized (_freeList) {        _freeList.ensureCapacity(capacity);      }    }  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?