26
26
import rx .exceptions .Exceptions ;
27
27
import rx .internal .operators .BackpressureUtils ;
28
28
import rx .internal .util .RxJavaPluginUtils ;
29
+ import rx .schedulers .Schedulers ;
29
30
30
31
/**
31
32
* Subject that buffers all items it observes and replays them to any {@link Observer} that subscribes.
@@ -110,6 +111,24 @@ public static <T> ReplaySubject<T> create(int capacity) {
110
111
ReplayState <T > state = new ReplayState <T >(buffer );
111
112
return new ReplaySubject <T >(state );
112
113
}
114
+ /**
115
+ * Creates an unbounded replay subject with the time-bounded-implementation for testing purposes.
116
+ * <p>
117
+ * This variant behaves like the regular unbounded {@code ReplaySubject} created via {@link #create()} but
118
+ * uses the structures of the bounded-implementation. This is by no means intended for the replacement of
119
+ * the original, array-backed and unbounded {@code ReplaySubject} due to the additional overhead of the
120
+ * linked-list based internal buffer. The sole purpose is to allow testing and reasoning about the behavior
121
+ * of the bounded implementations without the interference of the eviction policies.
122
+ *
123
+ * @param <T>
124
+ * the type of items observed and emitted by the Subject
125
+ * @return the created subject
126
+ */
127
+ /* public */ static <T > ReplaySubject <T > createUnboundedTime () {
128
+ ReplayBuffer <T > buffer = new ReplaySizeAndTimeBoundBuffer <T >(Integer .MAX_VALUE , Long .MAX_VALUE , Schedulers .immediate ());
129
+ ReplayState <T > state = new ReplayState <T >(buffer );
130
+ return new ReplaySubject <T >(state );
131
+ }
113
132
/**
114
133
* Creates a size-bounded replay subject.
115
134
* <p>
@@ -431,14 +450,7 @@ public void onNext(T t) {
431
450
432
451
b .next (t );
433
452
for (ReplayProducer <T > rp : get ()) {
434
- if (rp .caughtUp ) {
435
- rp .actual .onNext (t );
436
- } else {
437
- if (b .drain (rp )) {
438
- rp .caughtUp = true ;
439
- rp .node = null ;
440
- }
441
- }
453
+ b .drain (rp );
442
454
}
443
455
}
444
456
@@ -451,14 +463,7 @@ public void onError(Throwable e) {
451
463
List <Throwable > errors = null ;
452
464
for (ReplayProducer <T > rp : getAndSet (TERMINATED )) {
453
465
try {
454
- if (rp .caughtUp ) {
455
- rp .actual .onError (e );
456
- } else {
457
- if (b .drain (rp )) {
458
- rp .caughtUp = true ;
459
- rp .node = null ;
460
- }
461
- }
466
+ b .drain (rp );
462
467
} catch (Throwable ex ) {
463
468
if (errors == null ) {
464
469
errors = new ArrayList <Throwable >();
@@ -477,14 +482,7 @@ public void onCompleted() {
477
482
478
483
b .complete ();
479
484
for (ReplayProducer <T > rp : getAndSet (TERMINATED )) {
480
- if (rp .caughtUp ) {
481
- rp .actual .onCompleted ();
482
- } else {
483
- if (b .drain (rp )) {
484
- rp .caughtUp = true ;
485
- rp .node = null ;
486
- }
487
- }
485
+ b .drain (rp );
488
486
}
489
487
}
490
488
@@ -508,7 +506,7 @@ interface ReplayBuffer<T> {
508
506
509
507
void complete ();
510
508
511
- boolean drain (ReplayProducer <T > rp );
509
+ void drain (ReplayProducer <T > rp );
512
510
513
511
boolean isComplete ();
514
512
@@ -585,9 +583,9 @@ public void complete() {
585
583
}
586
584
587
585
@ Override
588
- public boolean drain (ReplayProducer <T > rp ) {
586
+ public void drain (ReplayProducer <T > rp ) {
589
587
if (rp .getAndIncrement () != 0 ) {
590
- return false ;
588
+ return ;
591
589
}
592
590
593
591
int missed = 1 ;
@@ -610,7 +608,7 @@ public boolean drain(ReplayProducer<T> rp) {
610
608
while (e != r ) {
611
609
if (a .isUnsubscribed ()) {
612
610
rp .node = null ;
613
- return false ;
611
+ return ;
614
612
}
615
613
616
614
boolean d = done ;
@@ -624,7 +622,7 @@ public boolean drain(ReplayProducer<T> rp) {
624
622
} else {
625
623
a .onCompleted ();
626
624
}
627
- return false ;
625
+ return ;
628
626
}
629
627
630
628
if (empty ) {
@@ -649,7 +647,7 @@ public boolean drain(ReplayProducer<T> rp) {
649
647
if (e == r ) {
650
648
if (a .isUnsubscribed ()) {
651
649
rp .node = null ;
652
- return false ;
650
+ return ;
653
651
}
654
652
655
653
boolean d = done ;
@@ -663,7 +661,7 @@ public boolean drain(ReplayProducer<T> rp) {
663
661
} else {
664
662
a .onCompleted ();
665
663
}
666
- return false ;
664
+ return ;
667
665
}
668
666
}
669
667
@@ -679,7 +677,7 @@ public boolean drain(ReplayProducer<T> rp) {
679
677
680
678
missed = rp .addAndGet (-missed );
681
679
if (missed == 0 ) {
682
- return r == Long . MAX_VALUE ;
680
+ return ;
683
681
}
684
682
}
685
683
}
@@ -799,9 +797,9 @@ public void complete() {
799
797
}
800
798
801
799
@ Override
802
- public boolean drain (ReplayProducer <T > rp ) {
800
+ public void drain (ReplayProducer <T > rp ) {
803
801
if (rp .getAndIncrement () != 0 ) {
804
- return false ;
802
+ return ;
805
803
}
806
804
807
805
final Subscriber <? super T > a = rp .actual ;
@@ -822,7 +820,7 @@ public boolean drain(ReplayProducer<T> rp) {
822
820
while (e != r ) {
823
821
if (a .isUnsubscribed ()) {
824
822
rp .node = null ;
825
- return false ;
823
+ return ;
826
824
}
827
825
828
826
boolean d = done ;
@@ -837,7 +835,7 @@ public boolean drain(ReplayProducer<T> rp) {
837
835
} else {
838
836
a .onCompleted ();
839
837
}
840
- return false ;
838
+ return ;
841
839
}
842
840
843
841
if (empty ) {
@@ -853,7 +851,7 @@ public boolean drain(ReplayProducer<T> rp) {
853
851
if (e == r ) {
854
852
if (a .isUnsubscribed ()) {
855
853
rp .node = null ;
856
- return false ;
854
+ return ;
857
855
}
858
856
859
857
boolean d = done ;
@@ -867,7 +865,7 @@ public boolean drain(ReplayProducer<T> rp) {
867
865
} else {
868
866
a .onCompleted ();
869
867
}
870
- return false ;
868
+ return ;
871
869
}
872
870
}
873
871
@@ -881,7 +879,7 @@ public boolean drain(ReplayProducer<T> rp) {
881
879
882
880
missed = rp .addAndGet (-missed );
883
881
if (missed == 0 ) {
884
- return r == Long . MAX_VALUE ;
882
+ return ;
885
883
}
886
884
}
887
885
}
@@ -1051,9 +1049,9 @@ TimedNode<T> latestHead() {
1051
1049
}
1052
1050
1053
1051
@ Override
1054
- public boolean drain (ReplayProducer <T > rp ) {
1052
+ public void drain (ReplayProducer <T > rp ) {
1055
1053
if (rp .getAndIncrement () != 0 ) {
1056
- return false ;
1054
+ return ;
1057
1055
}
1058
1056
1059
1057
final Subscriber <? super T > a = rp .actual ;
@@ -1074,7 +1072,7 @@ public boolean drain(ReplayProducer<T> rp) {
1074
1072
while (e != r ) {
1075
1073
if (a .isUnsubscribed ()) {
1076
1074
rp .node = null ;
1077
- return false ;
1075
+ return ;
1078
1076
}
1079
1077
1080
1078
boolean d = done ;
@@ -1089,7 +1087,7 @@ public boolean drain(ReplayProducer<T> rp) {
1089
1087
} else {
1090
1088
a .onCompleted ();
1091
1089
}
1092
- return false ;
1090
+ return ;
1093
1091
}
1094
1092
1095
1093
if (empty ) {
@@ -1105,7 +1103,7 @@ public boolean drain(ReplayProducer<T> rp) {
1105
1103
if (e == r ) {
1106
1104
if (a .isUnsubscribed ()) {
1107
1105
rp .node = null ;
1108
- return false ;
1106
+ return ;
1109
1107
}
1110
1108
1111
1109
boolean d = done ;
@@ -1119,7 +1117,7 @@ public boolean drain(ReplayProducer<T> rp) {
1119
1117
} else {
1120
1118
a .onCompleted ();
1121
1119
}
1122
- return false ;
1120
+ return ;
1123
1121
}
1124
1122
}
1125
1123
@@ -1133,7 +1131,7 @@ public boolean drain(ReplayProducer<T> rp) {
1133
1131
1134
1132
missed = rp .addAndGet (-missed );
1135
1133
if (missed == 0 ) {
1136
- return r == Long . MAX_VALUE ;
1134
+ return ;
1137
1135
}
1138
1136
}
1139
1137
}
@@ -1226,14 +1224,6 @@ static final class ReplayProducer<T>
1226
1224
/** Holds the back-reference to the replay state object. */
1227
1225
final ReplayState <T > state ;
1228
1226
1229
- /**
1230
- * Indicates this Subscriber runs unbounded and the <b>source</b>-triggered
1231
- * buffer.drain() has emitted all available values.
1232
- * <p>
1233
- * This field has to be read and written from the source emitter's thread only.
1234
- */
1235
- boolean caughtUp ;
1236
-
1237
1227
/**
1238
1228
* Unbounded buffer.drain() uses this field to remember the absolute index of
1239
1229
* values replayed to this Subscriber.
@@ -1276,6 +1266,5 @@ public void request(long n) {
1276
1266
throw new IllegalArgumentException ("n >= required but it was " + n );
1277
1267
}
1278
1268
}
1279
-
1280
1269
}
1281
1270
}
0 commit comments