Package org.xtreemfs.babudb

Source Code of org.xtreemfs.babudb.BabuDBRequestResultImpl

/*
* Copyright (c) 2009 - 2011, Jan Stender, Bjoern Kolbeck, Mikael Hoegqvist,
*                     Felix Hupfeld, Felix Langner, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
/*
* AUTHORS: Felix Langner (ZIB)
*/
package org.xtreemfs.babudb;

import java.util.concurrent.atomic.AtomicBoolean;

import org.xtreemfs.babudb.api.database.DatabaseRequestListener;
import org.xtreemfs.babudb.api.database.DatabaseRequestResult;
import org.xtreemfs.babudb.api.dev.ResponseManagerInternal;
import org.xtreemfs.babudb.api.exception.BabuDBException;
import org.xtreemfs.babudb.api.exception.BabuDBException.ErrorCode;
import org.xtreemfs.babudb.lsmdb.LSN;
import org.xtreemfs.foundation.logging.Logging;

/**
* Default return value for BabuDB requests.
*
* @author flangner
* @since 11/11/2009
* @param <T>
*/
public class BabuDBRequestResultImpl<T> implements DatabaseRequestResult<T> {
   
    private final ResponseManagerInternal       respMan;
   
    private DatabaseRequestListener<T>          listener;

    private T                                   result;
   
    private BabuDBException                     error;
   
    private final AtomicBoolean                 finished = new AtomicBoolean(false);
   
    protected final Object                      context;
   
    private LSN                                 assignedLSN = null;
   
/*
* constructors
*/
   
    /**
     * Creates a new future-object for a BabuDB request.
     *
     * @param respMan - thread to handle request listener.
     */
    public BabuDBRequestResultImpl(ResponseManagerInternal respMan) {
        this(null, respMan);
    }
   
    /**
     * Creates a new future-object for a BabuDB request.
     *
     * @param context - can be null.
     * @param respMan - thread to handle request listener.
     */
    public BabuDBRequestResultImpl(Object context, ResponseManagerInternal respMan) {
        this.context = context;
        this.respMan = respMan;
    }
   
/*
* getter/setter
*/
   
    public LSN getAssignedLSN() {
        return assignedLSN;
    }
   
/*
* state changing methods   
*/
   
    /**
     * Internal operation to run if the request was finished without
     * a return value.
     * Has to be invoked exactly one time!
     *
     * @param lsn
     */
    public void finished(LSN lsn) {
        finished(null, null, lsn);
    }
   
    /**
     * Internal operation to run if the request was finished.
     * Has to be invoked exactly one time!
     *
     * @param result
     * @param lsn
     */
    public void finished(T result) {
        finished(result, null, null);
    }
   
    /**
     * Internal operation to run if the request was finished.
     * Has to be invoked exactly one time!
     *
     * @param result
     * @param lsn
     */
    public void finished(T result, LSN lsn) {
        finished(result, null, lsn);
    }
   
    /**
     * Internal operation to run if the request failed.
     * Has to be invoked exactly one time!
     *
     * @param error - has to be not null, if an error occurs.
     */
    public void failed(BabuDBException error) {
        finished(null, error, null);
    }
   
/*
* private methods   
*/
   
    /**
     * Internal operation to run if the request was finished.
     * Has to be invoked exactly one time!
     *
     * @param result
     * @param error - has to be not null, if an error occurs.
     * @param lsn
     * @throws InterruptedException
     */
    private void finished(T result, BabuDBException error, LSN lsn) {
        assert (result == null || error == null) : "Results are not permitted on error!";
        this.error = error;
        this.result = result;
        this.assignedLSN = lsn;
       
        // notify the synchronously waiting instances
        synchronized (finished) {
            boolean check = finished.compareAndSet(false, true);
            assert (check) : "The request was already finished!";
           
            finished.notifyAll();
        }
       
        // notify the asynchronous-listener
        if (listener != null) {
            try {
                respMan.enqueueResponse(listener, error, result, context);
            } catch (InterruptedException e) {
                Logging.logError(Logging.LEVEL_ERROR, this, e);
            }
        }
    }

/*
* DatabaseRequestResult interface
*/
   
    /* (non-Javadoc)
     * @see org.xtreemfs.babudb.api.database.DatabaseRequestResult#registerListener(org.xtreemfs.babudb.api.database.DatabaseRequestListener)
     */
    public void registerListener(DatabaseRequestListener<T> listener) {
        synchronized (finished) {
            assert (this.listener == null) : "There is already a listener registered!";
            if (finished.get()) {
                if (error == null) {
                    listener.finished(result,context);
                } else {
                    listener.failed(error,context);
                }
            } else {
                this.listener = listener;
            }
        }
    }
   
    /* (non-Javadoc)
     * @see org.xtreemfs.babudb.api.database.DatabaseRequestResult#get()
     */
    public T get() throws BabuDBException {
        try {
            synchronized (finished) {
                if (!finished.get()) {
                    finished.wait();
                }
            }
        } catch (InterruptedException e) {
            throw new BabuDBException(ErrorCode.INTERRUPTED,
                    "Thread was interrupted while waiting for the response.");
        }
        if (error != null) throw error;
        return result;
    }
}
TOP

Related Classes of org.xtreemfs.babudb.BabuDBRequestResultImpl

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.