blob: 245dbb6218b6236e47fe588ce6e80cc6d4ddb114 [file] [log] [blame]
/*
* 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;
}
}