/*
 * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
 *
 * The Apache Software License, Version 1.1
 *
 * 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 "Burlap", "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 Scott Ferguson
 */

package com.alibaba.com.caucho.hessian.util;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReferenceArray;

/**
 * FreeList provides a simple class to manage free objects.  This is useful
 * for large data structures that otherwise would gobble up huge GC time.
 *
 * <p>The free list is bounded.  Freeing an object when the list is full will
 * do nothing.
 */
public final class HessianFreeList<T> {
    private final AtomicReferenceArray<T> _freeStack;
    private final AtomicInteger _top = new AtomicInteger();

    /**
     * Create a new free list.
     *
     * @param initialSize maximum number of free objects to store.
     */
    public HessianFreeList(int size) {
        _freeStack = new AtomicReferenceArray(size);
    }

    /**
     * Try to get an object from the free list.  Returns null if the free list
     * is empty.
     *
     * @return the new object or null.
     */
    public T allocate() {
        int top = _top.get();

        if (top > 0 && _top.compareAndSet(top, top - 1))
            return _freeStack.getAndSet(top - 1, null);
        else
            return null;
    }

    /**
     * Frees the object.  If the free list is full, the object will be garbage
     * collected.
     *
     * @param obj the object to be freed.
     */
    public boolean free(T obj) {
        int top = _top.get();

        if (top < _freeStack.length()) {
            boolean isFree = _freeStack.compareAndSet(top, null, obj);

            _top.compareAndSet(top, top + 1);

            return isFree;
        } else
            return false;
    }

    public boolean allowFree(T obj) {
        return _top.get() < _freeStack.length();
    }

    /**
     * Frees the object.  If the free list is full, the object will be garbage
     * collected.
     *
     * @param obj the object to be freed.
     */
    public void freeCareful(T obj) {
        if (checkDuplicate(obj))
            throw new IllegalStateException("tried to free object twice");

        free(obj);
    }

    /**
     * Debugging to see if the object has already been freed.
     */
    public boolean checkDuplicate(T obj) {
        int top = _top.get();

        for (int i = top - 1; i >= 0; i--) {
            if (_freeStack.get(i) == obj)
                return true;
        }

        return false;
    }
}
