package org.maachang.leveldb ;

/**
 * バッチ書き込み.
 * 
 * @version 2014/09/16
 * @author  masahito suzuki
 * @since   leveldb-1.01
 */
public final class WriteBatch {
    protected long addr = 0L ;
    protected int count = 0 ;
    
    /**
     * コンストラクタ.
     */
    public WriteBatch() {
        addr = jni.leveldb_wb_create() ;
    }
    
    /**
     * デストラクタ.
     */
    public final void finalize() throws Exception {
        close() ;
    }
    
    /**
     * バッチ書き込み情報のクローズ.
     */
    public final void close() {
        if( addr != 0L ) {
            jni.leveldb_wb_destroy( addr ) ;
            addr = 0L ;
        }
    }
    
    /**
     * クローズしているかチェック.
     * @return boolean [true]の場合、クローズしています.
     */
    public final boolean isClose() {
        return addr == 0L ;
    }
    
    /** check. **/
    protected final void check() {
        if( addr == 0L ) {
            throw new LeveldbException( "既にクローズされています" ) ;
        }
    }
    
    /**
     * 情報セット.
     * @param key 対象のキーを設定します.
     * @param value 対象の要素を設定します.
     */
    public final void put( final JniBuffer key,final JniBuffer value ) {
        check() ;
        if( key == null || value == null || key.position() == 0 || value.position() == 0 ) {
            throw new LeveldbException( "引数は不正です" ) ;
        }
        jni.leveldb_wb_put( addr,key.address(),key.position(),
            value.address(),value.position() ) ;
        count ++ ;
    }
    
    /**
     * 情報削除.
     * @param key 対象のキーを設定します.
     */
    public final void remove( final JniBuffer key ) {
        check() ;
        if( key == null || key.position() == 0 ) {
            throw new LeveldbException( "キー情報が設定されていません" ) ;
        }
        jni.leveldb_wb_remove( addr,key.address(),key.position() ) ;
        count ++ ;
    }
    
    /**
     * WriteBatchを書き込み.
     * @param db 書き込み先のLeveldbオブジェクトを設定します.
     */
    public final void write( Leveldb db ) {
        check() ;
        if( db == null || db.isClose() ) {
            throw new LeveldbException( "書き込み先のLeveldbオブジェクトはクローズされているか無効です" ) ;
        }
        if( count == 0 ) {
            return ;
        }
        if( jni.leveldb_wb_flush( db.addr,addr ) == -1 ) {
            throw new LeveldbException( "Leveldbに対して、WriteBatch書き込みに失敗しました" ) ;
        }
    }
}

