@@ -83,7 +83,8 @@ private static final class ObserveOnSubscriber<T> extends Subscriber<T> implemen
83
83
final NotificationLite <T > on ;
84
84
final boolean delayError ;
85
85
final Queue <Object > queue ;
86
- final int bufferSize ;
86
+ /** The emission threshold that should trigger a replenishing request. */
87
+ final int limit ;
87
88
88
89
// the status of the current stream
89
90
volatile boolean finished ;
@@ -97,6 +98,9 @@ private static final class ObserveOnSubscriber<T> extends Subscriber<T> implemen
97
98
* reading finished (acquire).
98
99
*/
99
100
Throwable error ;
101
+
102
+ /** Remembers how many elements have been emitted before the requests run out. */
103
+ long emitted ;
100
104
101
105
// do NOT pass the Subscriber through to couple the subscription chain ... unsubscribing on the parent should
102
106
// not prevent anything downstream from consuming, which will happen if the Subscription is chained
@@ -105,12 +109,16 @@ public ObserveOnSubscriber(Scheduler scheduler, Subscriber<? super T> child, boo
105
109
this .recursiveScheduler = scheduler .createWorker ();
106
110
this .delayError = delayError ;
107
111
this .on = NotificationLite .instance ();
108
- this .bufferSize = (bufferSize > 0 ) ? bufferSize : RxRingBuffer .SIZE ;
112
+ int calculatedSize = (bufferSize > 0 ) ? bufferSize : RxRingBuffer .SIZE ;
113
+ // this formula calculates the 75% of the bufferSize, rounded up to the next integer
114
+ this .limit = calculatedSize - (calculatedSize >> 2 );
109
115
if (UnsafeAccess .isUnsafeAvailable ()) {
110
- queue = new SpscArrayQueue <Object >(this . bufferSize );
116
+ queue = new SpscArrayQueue <Object >(calculatedSize );
111
117
} else {
112
- queue = new SpscAtomicArrayQueue <Object >(this . bufferSize );
118
+ queue = new SpscAtomicArrayQueue <Object >(calculatedSize );
113
119
}
120
+ // signal that this is an async operator capable of receiving this many
121
+ request (calculatedSize );
114
122
}
115
123
116
124
void init () {
@@ -133,12 +141,6 @@ public void request(long n) {
133
141
localChild .add (this );
134
142
}
135
143
136
- @ Override
137
- public void onStart () {
138
- // signal that this is an async operator capable of receiving this many
139
- request (this .bufferSize );
140
- }
141
-
142
144
@ Override
143
145
public void onNext (final T t ) {
144
146
if (isUnsubscribed () || finished ) {
@@ -180,9 +182,8 @@ protected void schedule() {
180
182
// only execute this from schedule()
181
183
@ Override
182
184
public void call () {
183
- long emitted = 0L ;
184
-
185
185
long missed = 1L ;
186
+ long currentEmission = emitted ;
186
187
187
188
// these are accessed in a tight loop around atomics so
188
189
// loading them into local variables avoids the mandatory re-reading
@@ -197,7 +198,6 @@ public void call() {
197
198
198
199
for (;;) {
199
200
long requestAmount = requested .get ();
200
- long currentEmission = 0L ;
201
201
202
202
while (requestAmount != currentEmission ) {
203
203
boolean done = finished ;
@@ -215,28 +215,25 @@ public void call() {
215
215
localChild .onNext (localOn .getValue (v ));
216
216
217
217
currentEmission ++;
218
- emitted ++;
218
+ if (currentEmission == limit ) {
219
+ requestAmount = BackpressureUtils .produced (requested , currentEmission );
220
+ request (currentEmission );
221
+ currentEmission = 0L ;
222
+ }
219
223
}
220
224
221
225
if (requestAmount == currentEmission ) {
222
226
if (checkTerminated (finished , q .isEmpty (), localChild , q )) {
223
227
return ;
224
228
}
225
229
}
226
-
227
- if (currentEmission != 0L ) {
228
- BackpressureUtils .produced (requested , currentEmission );
229
- }
230
-
230
+
231
+ emitted = currentEmission ;
231
232
missed = counter .addAndGet (-missed );
232
233
if (missed == 0L ) {
233
234
break ;
234
235
}
235
236
}
236
-
237
- if (emitted != 0L ) {
238
- request (emitted );
239
- }
240
237
}
241
238
242
239
boolean checkTerminated (boolean done , boolean isEmpty , Subscriber <? super T > a , Queue <Object > q ) {
@@ -285,4 +282,4 @@ boolean checkTerminated(boolean done, boolean isEmpty, Subscriber<? super T> a,
285
282
return false ;
286
283
}
287
284
}
288
- }
285
+ }
0 commit comments