001 // Copyright 2007 Waterken Inc. under the terms of the MIT X license
002 // found at http://www.opensource.org/licenses/mit-license.html
003 package org.waterken.serial;
004
005 import static org.ref_send.promise.Eventual.cast;
006
007 import java.io.Serializable;
008 import java.util.Iterator;
009
010 import org.ref_send.promise.Deferred;
011 import org.ref_send.promise.Eventual;
012 import org.ref_send.promise.Promise;
013 import org.ref_send.promise.Resolver;
014
015 /**
016 * A {@link Series} maker.
017 * @see "Section 19.9 'Queues' of 'Systems Programming in Concurrent Prolog';
018 * Concurrent Prolog Collected Papers Volume 2; Ehud Shapiro; 1987."
019 */
020 public final class
021 Serial {
022 private Serial() {}
023
024 /**
025 * Makes a {@link Series}.
026 * @param _ eventual operator
027 */
028 static public <T> Series<T>
029 make(final Eventual _) {
030 /*
031 * The implementation starts with a promise for the initial element,
032 * from which all other promises are derived.
033 */
034 final Deferred<Element<T>> initial = _.defer();
035 class SeriesX implements Series<T>, Serializable {
036 static private final long serialVersionUID = 1L;
037
038 protected Element<T> front_ = cast(Element.class, initial.promise);
039 private Resolver<Element<T>> back = initial.resolver;
040
041 public Iterator<Promise<T>>
042 iterator() {
043 class IteratorX implements Iterator<Promise<T>>, Serializable {
044 static private final long serialVersionUID = 1L;
045
046 private Element<T> current_ = front_;
047
048 public boolean
049 hasNext() { return true; } // The future is unlimited.
050
051 public Promise<T>
052 next() {
053 /*
054 * Produce a promise for what will be the value of the
055 * current element and hold onto an eventual reference
056 * for what will be the next element in the list, which
057 * is now the current element in the iteration order.
058 */
059 final Promise<T> r = current_.getValue();
060 current_ = current_.getNext();
061 return r;
062 }
063
064 public void
065 remove() { throw new UnsupportedOperationException(); }
066 }
067 return new IteratorX();
068 }
069
070 public Element<T>
071 getFront() { return front_; }
072
073 public void
074 produce(final Promise<T> value) {
075 /*
076 * Resolve the promise for the last element in the list with an
077 * actual element containing the provided value, and an eventual
078 * reference for what will be the next element in the list,
079 * which is now the new last element.
080 */
081 final Deferred<Element<T>> x = _.defer();
082 back.apply(Link.link(value, cast(Element.class, x.promise)));
083 back = x.resolver;
084 }
085
086 public Promise<T>
087 consume() {
088 /*
089 * Produce a promise for what will be the value of the first
090 * element and hold onto an eventual reference for what will be
091 * the next element in the list, which is now the first element.
092 */
093 final Promise<T> r = front_.getValue();
094 front_ = front_.getNext();
095 return r;
096 }
097 }
098 return new SeriesX();
099 }
100 }