Package de.netseeker.ejoe.cache

Source Code of de.netseeker.ejoe.cache.ByteBufferCache

/*********************************************************************
* ByteBufferCache.java
* created on 17.03.2007 by netseeker
* $Id: ByteBufferCache.java,v 1.2 2007/03/25 15:03:22 netseeker Exp $
* $Log: ByteBufferCache.java,v $
* Revision 1.2  2007/03/25 15:03:22  netseeker
* *** empty log message ***
*
* Revision 1.1  2007/03/22 21:01:33  netseeker
* *** empty log message ***
*
*
* ====================================================================
*
*  Copyright 2005-2006 netseeker aka Michael Manske
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
* ====================================================================
*
* This file is part of the EJOE framework.
* For more information on the author, please see
* <http://www.manskes.de/>.
*
*********************************************************************/
package de.netseeker.ejoe.cache;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* A pool for direct ByteBuffers which is able to borrow ByteBuffers according to a requested capacity.
*
* @author netseeker
* @since 0.3.9.2
*/
class ByteBufferCache
{
    /**
     * default max. pool size in bytes
     */
    public static final int     DEFAULT_MAX_POOL_SIZE = 1048576;

    private static final Logger LOG                   = Logger.getLogger( ByteBufferCache.class.getName() );

    final ReferenceQueue        _refQueue             = new ReferenceQueue();

    final List                  _pool                 = Collections.synchronizedList( new LinkedList() );

    int                         _sizeB                = DEFAULT_MAX_POOL_SIZE;

    int                         _currentSize          = 0;

    /**
     *
     */
    public ByteBufferCache()
    {
    }

    /**
     * @param size
     */
    public ByteBufferCache(int size)
    {
        _sizeB = size;
    }

    /**
     * @param capacity
     * @return
     */
    public ByteBuffer borrow( int capacity )
    {
        ByteBuffer buffer = null;
        clean();
        int size = _pool.size();
        int i = 0;
        while ( i < size )
        {
            try
            {
                SoftReference ref = (SoftReference) _pool.get( i );
                buffer = (ByteBuffer) ref.get();
                if ( buffer != null && buffer.capacity() >= capacity )
                {
                    ref.clear();
                    _pool.remove( i );
                    _currentSize -= buffer.capacity();
                    buffer.limit( capacity );
                    LOG.log( Level.FINEST, "Borrowed buffer with capacity of " + buffer.capacity() + "(limit="
                            + capacity + "). Pool max size: " + _sizeB + " Current pool size: " + _currentSize );
                    return buffer;
                }
               
                i++;
                size = _pool.size();
            }
            catch ( IndexOutOfBoundsException e )
            {
                // just one or more concurrent borrow processes modified the pool
                break;
            }
        }
        return ByteBuffer.allocateDirect( capacity );
    }

    /**
     * @param buffer
     */
    public void pushBack( ByteBuffer buffer )
    {
        clean();
        if ( _currentSize <= _sizeB )
        {
            buffer.clear();
            SoftReference ref = new SoftReference( buffer, this._refQueue );
            _pool.add( ref );
            _currentSize += buffer.capacity();
            LOG.log( Level.FINEST, "Pushed back buffer with capacity of " + buffer.capacity() + ". Pool max size: "
                    + _sizeB + " Current pool size: " + _currentSize );
        }
        else
        {
            LOG.log( Level.FINEST, "Not pushing back buffer with capacity of " + buffer.capacity()
                    + " because max pool size of " + _sizeB + "bytes is reached." );
        }
    }

    /**
     * garbage collects all dereferenced objects in this cache
     */
    private synchronized void clean()
    {
        Reference ref;

        while ( (ref = this._refQueue.poll()) != null )
        {
            ByteBuffer buffer = (ByteBuffer) ref.get();
            _pool.remove( ref );

            if ( buffer != null )
            {
                LOG.log( Level.FINEST, "Collecting Buffer with capacity of " + buffer.capacity() );
                _currentSize -= buffer.capacity();
            }
            else
            {
                LOG.log( Level.FINEST, "Clearing cache..." );
                _pool.clear();
                _currentSize = 0;
                break;
            }
        }
    }
}
TOP

Related Classes of de.netseeker.ejoe.cache.ByteBufferCache

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.