This operator does not support backpressure because multicasting means the stream is "hot" with
- * multiple subscribers. Each child will need to manage backpressure independently using operators such
- * as {@link #onBackpressureDrop} and {@link #onBackpressureBuffer}.
+ *
This operator supports backpressure. Note that the upstream requests are determined by the child
+ * Subscriber which requests the largest amount: i.e., two child Subscribers with requests of 10 and 100 will
+ * request 100 elements from the underlying Observable sequence.
*
Scheduler:
*
This version of {@code replay} does not operate by default on a particular {@link Scheduler}.
*
@@ -5895,14 +5894,7 @@ public Void call(Notification> notification) {
* @see ReactiveX operators documentation: Replay
*/
public final ConnectableObservable replay() {
- return new OperatorMulticast(this, new Func0>() {
-
- @Override
- public Subject super T, ? extends T> call() {
- return ReplaySubject. create();
- }
-
- });
+ return OperatorReplay.create(this);
}
/**
@@ -5912,9 +5904,9 @@ public final ConnectableObservable replay() {
*
*
*
Backpressure Support:
- *
This operator does not support backpressure because multicasting means the stream is "hot" with
- * multiple subscribers. Each child will need to manage backpressure independently using operators such
- * as {@link #onBackpressureDrop} and {@link #onBackpressureBuffer}.
+ *
This operator supports backpressure. Note that the upstream requests are determined by the child
+ * Subscriber which requests the largest amount: i.e., two child Subscribers with requests of 10 and 100 will
+ * request 100 elements from the underlying Observable sequence.
*
Scheduler:
*
This version of {@code replay} does not operate by default on a particular {@link Scheduler}.
*
@@ -5929,12 +5921,12 @@ public final ConnectableObservable replay() {
* @see ReactiveX operators documentation: Replay
*/
public final Observable replay(Func1 super Observable, ? extends Observable> selector) {
- return create(new OnSubscribeMulticastSelector(this, new Func0>() {
+ return OperatorReplay.multicastSelector(new Func0>() {
@Override
- public final Subject call() {
- return ReplaySubject.create();
+ public ConnectableObservable call() {
+ return Observable.this.replay();
}
- }, selector));
+ }, selector);
}
/**
@@ -5945,9 +5937,9 @@ public final Subject call() {
*
*
*
Backpressure Support:
- *
This operator does not support backpressure because multicasting means the stream is "hot" with
- * multiple subscribers. Each child will need to manage backpressure independently using operators such
- * as {@link #onBackpressureDrop} and {@link #onBackpressureBuffer}.
+ *
This operator supports backpressure. Note that the upstream requests are determined by the child
+ * Subscriber which requests the largest amount: i.e., two child Subscribers with requests of 10 and 100 will
+ * request 100 elements from the underlying Observable sequence.
*
Scheduler:
*
This version of {@code replay} does not operate by default on a particular {@link Scheduler}.
*
@@ -5965,12 +5957,12 @@ public final Subject call() {
* @see ReactiveX operators documentation: Replay
*/
public final Observable replay(Func1 super Observable, ? extends Observable> selector, final int bufferSize) {
- return create(new OnSubscribeMulticastSelector(this, new Func0>() {
+ return OperatorReplay.multicastSelector(new Func0>() {
@Override
- public final Subject call() {
- return ReplaySubject.createWithSize(bufferSize);
+ public ConnectableObservable call() {
+ return Observable.this.replay(bufferSize);
}
- }, selector));
+ }, selector);
}
/**
@@ -5981,9 +5973,9 @@ public final Subject call() {
*
*
*
Backpressure Support:
- *
This operator does not support backpressure because multicasting means the stream is "hot" with
- * multiple subscribers. Each child will need to manage backpressure independently using operators such
- * as {@link #onBackpressureDrop} and {@link #onBackpressureBuffer}.
+ *
This operator supports backpressure. Note that the upstream requests are determined by the child
+ * Subscriber which requests the largest amount: i.e., two child Subscribers with requests of 10 and 100 will
+ * request 100 elements from the underlying Observable sequence.
*
Scheduler:
*
This version of {@code replay} operates by default on the {@code computation} {@link Scheduler}.
*
@@ -6017,9 +6009,9 @@ public final Observable replay(Func1 super Observable, ? extends Obs
*
*
*
Backpressure Support:
- *
This operator does not support backpressure because multicasting means the stream is "hot" with
- * multiple subscribers. Each child will need to manage backpressure independently using operators such
- * as {@link #onBackpressureDrop} and {@link #onBackpressureBuffer}.
+ *
This operator supports backpressure. Note that the upstream requests are determined by the child
+ * Subscriber which requests the largest amount: i.e., two child Subscribers with requests of 10 and 100 will
+ * request 100 elements from the underlying Observable sequence.
*
Scheduler:
*
you specify which {@link Scheduler} this operator will use
*
@@ -6049,12 +6041,12 @@ public final Observable replay(Func1 super Observable, ? extends Obs
if (bufferSize < 0) {
throw new IllegalArgumentException("bufferSize < 0");
}
- return create(new OnSubscribeMulticastSelector(this, new Func0>() {
+ return OperatorReplay.multicastSelector(new Func0>() {
@Override
- public final Subject call() {
- return ReplaySubject.createWithTimeAndSize(time, unit, bufferSize, scheduler);
+ public ConnectableObservable call() {
+ return Observable.this.replay(bufferSize, time, unit, scheduler);
}
- }, selector));
+ }, selector);
}
/**
@@ -6065,9 +6057,9 @@ public final Subject call() {
*
*
*
Backpressure Support:
- *
This operator does not support backpressure because multicasting means the stream is "hot" with
- * multiple subscribers. Each child will need to manage backpressure independently using operators such
- * as {@link #onBackpressureDrop} and {@link #onBackpressureBuffer}.
+ *
This operator supports backpressure. Note that the upstream requests are determined by the child
+ * Subscriber which requests the largest amount: i.e., two child Subscribers with requests of 10 and 100 will
+ * request 100 elements from the underlying Observable sequence.
*
Scheduler:
*
you specify which {@link Scheduler} this operator will use
*
@@ -6086,13 +6078,18 @@ public final Subject call() {
* replaying no more than {@code bufferSize} notifications
* @see ReactiveX operators documentation: Replay
*/
- public final Observable replay(Func1 super Observable, ? extends Observable> selector, final int bufferSize, final Scheduler scheduler) {
- return create(new OnSubscribeMulticastSelector(this, new Func0>() {
+ public final Observable replay(final Func1 super Observable, ? extends Observable> selector, final int bufferSize, final Scheduler scheduler) {
+ return OperatorReplay.multicastSelector(new Func0>() {
@Override
- public final Subject call() {
- return OperatorReplay. createScheduledSubject(ReplaySubject.createWithSize(bufferSize), scheduler);
+ public ConnectableObservable call() {
+ return Observable.this.replay(bufferSize);
}
- }, selector));
+ }, new Func1, Observable>() {
+ @Override
+ public Observable call(Observable t) {
+ return selector.call(t).observeOn(scheduler);
+ }
+ });
}
/**
@@ -6103,9 +6100,9 @@ public final Subject call() {
*
*
*
Backpressure Support:
- *
This operator does not support backpressure because multicasting means the stream is "hot" with
- * multiple subscribers. Each child will need to manage backpressure independently using operators such
- * as {@link #onBackpressureDrop} and {@link #onBackpressureBuffer}.
+ *
This operator supports backpressure. Note that the upstream requests are determined by the child
+ * Subscriber which requests the largest amount: i.e., two child Subscribers with requests of 10 and 100 will
+ * request 100 elements from the underlying Observable sequence.
*
Scheduler:
*
This version of {@code replay} operates by default on the {@code computation} {@link Scheduler}.
*
@@ -6136,9 +6133,9 @@ public final Observable replay(Func1 super Observable, ? extends Obs
*
*
*
Backpressure Support:
- *
This operator does not support backpressure because multicasting means the stream is "hot" with
- * multiple subscribers. Each child will need to manage backpressure independently using operators such
- * as {@link #onBackpressureDrop} and {@link #onBackpressureBuffer}.
+ *
This operator supports backpressure. Note that the upstream requests are determined by the child
+ * Subscriber which requests the largest amount: i.e., two child Subscribers with requests of 10 and 100 will
+ * request 100 elements from the underlying Observable sequence.
*
Scheduler:
*
you specify which {@link Scheduler} this operator will use
*
@@ -6160,12 +6157,12 @@ public final Observable replay(Func1 super Observable, ? extends Obs
* @see ReactiveX operators documentation: Replay
*/
public final Observable replay(Func1 super Observable, ? extends Observable> selector, final long time, final TimeUnit unit, final Scheduler scheduler) {
- return create(new OnSubscribeMulticastSelector(this, new Func0>() {
+ return OperatorReplay.multicastSelector(new Func0>() {
@Override
- public final Subject call() {
- return ReplaySubject.createWithTime(time, unit, scheduler);
+ public ConnectableObservable call() {
+ return Observable.this.replay(time, unit, scheduler);
}
- }, selector));
+ }, selector);
}
/**
@@ -6175,9 +6172,9 @@ public final Subject call() {
*
*
*
Backpressure Support:
- *
This operator does not support backpressure because multicasting means the stream is "hot" with
- * multiple subscribers. Each child will need to manage backpressure independently using operators such
- * as {@link #onBackpressureDrop} and {@link #onBackpressureBuffer}.
+ *
This operator supports backpressure. Note that the upstream requests are determined by the child
+ * Subscriber which requests the largest amount: i.e., two child Subscribers with requests of 10 and 100 will
+ * request 100 elements from the underlying Observable sequence.
*
Scheduler:
*
you specify which {@link Scheduler} this operator will use
*
@@ -6194,13 +6191,18 @@ public final Subject call() {
* replaying all items
* @see ReactiveX operators documentation: Replay
*/
- public final Observable replay(Func1 super Observable, ? extends Observable> selector, final Scheduler scheduler) {
- return create(new OnSubscribeMulticastSelector(this, new Func0>() {
+ public final Observable replay(final Func1 super Observable, ? extends Observable> selector, final Scheduler scheduler) {
+ return OperatorReplay.multicastSelector(new Func0>() {
@Override
- public final Subject call() {
- return OperatorReplay.createScheduledSubject(ReplaySubject. create(), scheduler);
+ public ConnectableObservable call() {
+ return Observable.this.replay();
}
- }, selector));
+ }, new Func1, Observable>() {
+ @Override
+ public Observable call(Observable t) {
+ return selector.call(t).observeOn(scheduler);
+ }
+ });
}
/**
@@ -6212,9 +6214,9 @@ public final Subject call() {
*
*
*
Backpressure Support:
- *
This operator does not support backpressure because multicasting means the stream is "hot" with
- * multiple subscribers. Each child will need to manage backpressure independently using operators such
- * as {@link #onBackpressureDrop} and {@link #onBackpressureBuffer}.
+ *
This operator supports backpressure. Note that the upstream requests are determined by the child
+ * Subscriber which requests the largest amount: i.e., two child Subscribers with requests of 10 and 100 will
+ * request 100 elements from the underlying Observable sequence.
*
Scheduler:
*
This version of {@code replay} does not operate by default on a particular {@link Scheduler}.
*
@@ -6226,14 +6228,7 @@ public final Subject call() {
* @see ReactiveX operators documentation: Replay
*/
public final ConnectableObservable replay(final int bufferSize) {
- return new OperatorMulticast(this, new Func0>() {
-
- @Override
- public Subject super T, ? extends T> call() {
- return ReplaySubject.createWithSize(bufferSize);
- }
-
- });
+ return OperatorReplay.create(this, bufferSize);
}
/**
@@ -6245,9 +6240,9 @@ public final ConnectableObservable replay(final int bufferSize) {
*
*
*
Backpressure Support:
- *
This operator does not support backpressure because multicasting means the stream is "hot" with
- * multiple subscribers. Each child will need to manage backpressure independently using operators such
- * as {@link #onBackpressureDrop} and {@link #onBackpressureBuffer}.
+ *
This operator supports backpressure. Note that the upstream requests are determined by the child
+ * Subscriber which requests the largest amount: i.e., two child Subscribers with requests of 10 and 100 will
+ * request 100 elements from the underlying Observable sequence.
*
Scheduler:
*
This version of {@code replay} operates by default on the {@code computation} {@link Scheduler}.
*
@@ -6276,9 +6271,9 @@ public final ConnectableObservable replay(int bufferSize, long time, TimeUnit
*
*
*
Backpressure Support:
- *
This operator does not support backpressure because multicasting means the stream is "hot" with
- * multiple subscribers. Each child will need to manage backpressure independently using operators such
- * as {@link #onBackpressureDrop} and {@link #onBackpressureBuffer}.
+ *
This operator supports backpressure. Note that the upstream requests are determined by the child
+ * Subscriber which requests the largest amount: i.e., two child Subscribers with requests of 10 and 100 will
+ * request 100 elements from the underlying Observable sequence.
*
Scheduler:
*
you specify which {@link Scheduler} this operator will use
*
@@ -6302,14 +6297,7 @@ public final ConnectableObservable replay(final int bufferSize, final long ti
if (bufferSize < 0) {
throw new IllegalArgumentException("bufferSize < 0");
}
- return new OperatorMulticast(this, new Func0>() {
-
- @Override
- public Subject super T, ? extends T> call() {
- return ReplaySubject.createWithTimeAndSize(time, unit, bufferSize, scheduler);
- }
-
- });
+ return OperatorReplay.create(this, time, unit, scheduler, bufferSize);
}
/**
@@ -6321,9 +6309,9 @@ public final ConnectableObservable replay(final int bufferSize, final long ti
*
*
*
Backpressure Support:
- *
This operator does not support backpressure because multicasting means the stream is "hot" with
- * multiple subscribers. Each child will need to manage backpressure independently using operators such
- * as {@link #onBackpressureDrop} and {@link #onBackpressureBuffer}.
+ *
This operator supports backpressure. Note that the upstream requests are determined by the child
+ * Subscriber which requests the largest amount: i.e., two child Subscribers with requests of 10 and 100 will
+ * request 100 elements from the underlying Observable sequence.
*
Scheduler:
*
you specify which {@link Scheduler} this operator will use
*
@@ -6337,14 +6325,7 @@ public final ConnectableObservable replay(final int bufferSize, final long ti
* @see ReactiveX operators documentation: Replay
*/
public final ConnectableObservable replay(final int bufferSize, final Scheduler scheduler) {
- return new OperatorMulticast(this, new Func0>() {
-
- @Override
- public Subject super T, ? extends T> call() {
- return OperatorReplay.createScheduledSubject(ReplaySubject.createWithSize(bufferSize), scheduler);
- }
-
- });
+ return OperatorReplay.observeOn(replay(bufferSize), scheduler);
}
/**
@@ -6356,9 +6337,9 @@ public final ConnectableObservable replay(final int bufferSize, final Schedul
*
*
*
Backpressure Support:
- *
This operator does not support backpressure because multicasting means the stream is "hot" with
- * multiple subscribers. Each child will need to manage backpressure independently using operators such
- * as {@link #onBackpressureDrop} and {@link #onBackpressureBuffer}.
+ *
This operator supports backpressure. Note that the upstream requests are determined by the child
+ * Subscriber which requests the largest amount: i.e., two child Subscribers with requests of 10 and 100 will
+ * request 100 elements from the underlying Observable sequence.
*
Scheduler:
*
This version of {@code replay} operates by default on the {@code computation} {@link Scheduler}.
*
@@ -6384,9 +6365,9 @@ public final ConnectableObservable replay(long time, TimeUnit unit) {
*
*
*
Backpressure Support:
- *
This operator does not support backpressure because multicasting means the stream is "hot" with
- * multiple subscribers. Each child will need to manage backpressure independently using operators such
- * as {@link #onBackpressureDrop} and {@link #onBackpressureBuffer}.
+ *
This operator supports backpressure. Note that the upstream requests are determined by the child
+ * Subscriber which requests the largest amount: i.e., two child Subscribers with requests of 10 and 100 will
+ * request 100 elements from the underlying Observable sequence.
*
Scheduler:
*
you specify which {@link Scheduler} this operator will use
*
@@ -6402,14 +6383,7 @@ public final ConnectableObservable replay(long time, TimeUnit unit) {
* @see ReactiveX operators documentation: Replay
*/
public final ConnectableObservable replay(final long time, final TimeUnit unit, final Scheduler scheduler) {
- return new OperatorMulticast(this, new Func0>() {
-
- @Override
- public Subject super T, ? extends T> call() {
- return ReplaySubject.createWithTime(time, unit, scheduler);
- }
-
- });
+ return OperatorReplay.create(this, time, unit, scheduler);
}
/**
@@ -6421,9 +6395,9 @@ public final ConnectableObservable replay(final long time, final TimeUnit uni
*
*
*
Backpressure Support:
- *
This operator does not support backpressure because multicasting means the stream is "hot" with
- * multiple subscribers. Each child will need to manage backpressure independently using operators such
- * as {@link #onBackpressureDrop} and {@link #onBackpressureBuffer}.
+ *
This operator supports backpressure. Note that the upstream requests are determined by the child
+ * Subscriber which requests the largest amount: i.e., two child Subscribers with requests of 10 and 100 will
+ * request 100 elements from the underlying Observable sequence.
*
Scheduler:
*
you specify which {@link Scheduler} this operator will use
*
@@ -6436,14 +6410,7 @@ public final ConnectableObservable replay(final long time, final TimeUnit uni
* @see ReactiveX operators documentation: Replay
*/
public final ConnectableObservable replay(final Scheduler scheduler) {
- return new OperatorMulticast(this, new Func0>() {
-
- @Override
- public Subject super T, ? extends T> call() {
- return OperatorReplay.createScheduledSubject(ReplaySubject. create(), scheduler);
- }
-
- });
+ return OperatorReplay.observeOn(replay(), scheduler);
}
/**
diff --git a/src/main/java/rx/internal/operators/OperatorReplay.java b/src/main/java/rx/internal/operators/OperatorReplay.java
index 83c76dfe39..2989f50b9e 100644
--- a/src/main/java/rx/internal/operators/OperatorReplay.java
+++ b/src/main/java/rx/internal/operators/OperatorReplay.java
@@ -15,93 +15,1161 @@
*/
package rx.internal.operators;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.*;
+import rx.*;
import rx.Observable;
-import rx.Observable.OnSubscribe;
-import rx.Scheduler;
-import rx.Subscriber;
-import rx.subjects.Subject;
+import rx.exceptions.Exceptions;
+import rx.functions.*;
+import rx.observables.ConnectableObservable;
+import rx.schedulers.Timestamped;
+import rx.subscriptions.Subscriptions;
-/**
- * Replay with limited buffer and/or time constraints.
- *
- *
- * @see MSDN: Observable.Replay overloads
- */
-public final class OperatorReplay {
- /** Utility class. */
- private OperatorReplay() {
- throw new IllegalStateException("No instances!");
+public final class OperatorReplay extends ConnectableObservable {
+ /** The source observable. */
+ final Observable extends T> source;
+ /** Holds the current subscriber that is, will be or just was subscribed to the source observable. */
+ final AtomicReference> current;
+ /** A factory that creates the appropriate buffer for the ReplaySubscriber. */
+ final Func0 extends ReplayBuffer> bufferFactory;
+
+ @SuppressWarnings("rawtypes")
+ static final Func0 DEFAULT_UNBOUNDED_FACTORY = new Func0() {
+ @Override
+ public Object call() {
+ return new UnboundedReplayBuffer