/*
 * Copyright (c) 2009 Stanford University, unless otherwise specified.
 * All rights reserved.
 *
 * This software was developed by the Pervasive Parallelism Laboratory of
 * Stanford University, California, USA.
 *
 * Permission to use, copy, modify, and distribute this software in source
 * or binary form for any purpose with or without fee is hereby granted,
 * 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. Neither the name of Stanford University nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS 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 THE REGENTS OR 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.
 */

package org.apache.ignite.internal.util.snaptree;

/** A <code>Epoch</code> has a lifecycle consisting of three phases: active,
 *  closing, and closed.  During the active phase partipants may arrive and
 *  leave the epoch.  Once a close has been requested, new participants are not
 *  allowed, only leaving is possible.  Once close has been requested and all
 *  participants have left, the epoch is transitioned to the closed state.
 *  <p>
 *  Entry is performed with {@link #attemptArrive}, which returns a non-null
 *  ticket on success or null if {@link #beginClose} has already been called.
 *  Each successful call to <code>attemptArrive</code> must be paired by a call
 *  to {@link Ticket#leave} on the returned ticket.
 *  <p>
 *  The abstract method {@link #onClosed} will be invoked exactly once after
 *  the epoch becomes closed.  It will be passed the sum of the values passed
 *  to {@link Ticket#leave}.  There is no way to query the current participant
 *  count or state of the epoch without changing it.
 *  <p>
 *  Internally the epoch responds to contention by increasing its size,
 *  striping the participant count across multiple objects (and hopefully
 *  multiple cache lines).  Once close has begun, the epoch converts itself to
 *  a single-shot hierarchical barrier, that also performs a hierarchical
 *  reduction of the leave parameters.
 */
@SuppressWarnings("ALL")
abstract public class Epoch {

    /** Represents a single successful arrival to an {@link Epoch}. */
    public interface Ticket {
        /** Informs the epoch that returned this ticket that the participant
         *  has left.  This method should be called exactly once per ticket.
         *  The sum of the <code>data</code> values for all tickets will be
         *  computed and passed to {@link Epoch#onClosed}.
         */
        void leave(int data);
    }

    private final Root _root = new Root();

    /** Returns a {@link Ticket} indicating a successful arrival, if no call to
     *  {@link #beginClose} has been made for this epoch, or returns null if
     *  close has already begun.  {@link Ticket#leave} must be called exactly
     *  once on any returned ticket.
     */
    public Ticket attemptArrive() {
        return _root.attemptArrive();
    }

    /** Prevents new arrivals from succeeding, then returns immediately.
     *  {@link #onClosed} will be called after all outstanding tickets have
     *  been returned.  To block until close is complete, add some sort of
     *  synchronization logic to the user-defined implementation of {@link
     *  #onClosed}.
     */
    public void beginClose() {
        _root.beginClose();
    }

    /** Override this method to provide user-defined behavior.
     *  <code>dataSum</code> will be the sum of the <code>data</code> values
     *  passed to {@link Ticket#leave} for all tickets in this epoch.
     *  <p>
     *  As a simple example, a blocking close operation may be defined by:<pre>
     *    class BlockingEpoch extends Epoch {
     *        private final CountDownLatch _closed = new CountDownLatch(1);
     *
     *        public void blockingClose() throws InterruptedException {
     *            beginClose();
     *            _closed.await();
     *        }
     *
     *        protected void onClosed(int dataSum) {
     *            _closed.countDown(1);
     *        }
     *    }
     *  </pre>
     */
    abstract protected void onClosed(int dataSum);

    //////////////// debugging stuff

    int computeSpread() {
        return _root.computeSpread();
    }

    //////////////// internal implementation

    private class Root extends EpochNode {
        /** */
        private static final long serialVersionUID = 0L;

        protected void onClosed(final int dataSum) {
            Epoch.this.onClosed(dataSum);
        }
    }
}
