package org.maachang.mimdb.core.util ;

/**
 * オブジェクトリンクリスト.
 * 
 * @version 2013/10/26
 * @author masahito suzuki
 * @since MasterInMemDB 1.00
 */
@SuppressWarnings("unchecked")
public class ObjectLinkedList<T> {
    
    /** 格納先オブジェクト. **/
    private static final class _OLEm<T> {
        T n ;
        _OLEm<T> next ;
    }
    
    /** 格納条件. **/
    private _OLEm<T> top = null ;
    private _OLEm<T> now = null ;
    
    /**
     * コンストラクタ.
     */
    public ObjectLinkedList() {
        top = null ;
        now = null ;
    }
    
    /**
     * 情報クリア.
     */
    public final void clear() {
        top = null ;
        now = null ;
    }
    
    /**
     * 情報追加.
     * @param v 対象の情報を設定します.
     */
    public final void offer( final T v ) {
        if( top == null ) {
            now = new _OLEm<T>() ;
            now.n = v ;
            now.next = null ;
            top = now ;
        }
        else {
            _OLEm<T> n = new _OLEm<T>() ;
            now.next = n ;
            now = n ;
            n.n = v ;
            n.next = null ;
        }
    }
    
    /**
     * 情報取得.
     * @return T 情報が返却されます.
     */
    public final T poll() {
        T ret = top.n ;
        top = top.next ;
        return ret ;
    }
    
    /**
     * 情報取得.
     * @parma lst 格納先の配列を設定します.
     * @param off 格納先のオフセット値を設定します.
     * @return int オフセット値+今回追加された長さの合計が返却されます.
     */
    public final int poll( final T[] lst,int off ) {
        for( ; top != null ; lst[ off ++ ] = top.n,top = top.next ) ;
        return off ;
    }
    
    /**
     * 情報が存在するかチェック.
     * @return boolean [true]の場合、存在します.
     */
    public final boolean hasNext() {
        return top != null ;
    }
    
    /**
     * データ長を取得.
     * @return int データ長が返却されます.
     */
    public final int size() {
        _OLEm<T> n = top ;
        int ret = 0 ;
        while( n != null ) {
            ret ++ ;
            n = n.next ;
        }
        return ret ;
    }
}
