File tree Expand file tree Collapse file tree 2 files changed +32
-9
lines changed
src/main/java/rx/internal/operators Expand file tree Collapse file tree 2 files changed +32
-9
lines changed Original file line number Diff line number Diff line change @@ -75,16 +75,16 @@ public void request(long n) {
75
75
*/
76
76
void slowpath (long r ) {
77
77
long idx = index ;
78
+ long e = 0L ;
78
79
while (true ) {
79
80
/*
80
81
* This complicated logic is done to avoid touching the volatile `index` and `requested` values
81
82
* during the loop itself. If they are touched during the loop the performance is impacted significantly.
82
83
*/
83
84
long fs = end - idx + 1 ;
84
- long e = Math .min (fs , r );
85
85
final boolean complete = fs <= r ;
86
86
87
- fs = e + idx ;
87
+ fs = Math . min ( fs , r ) + idx ;
88
88
final Subscriber <? super Integer > o = this .o ;
89
89
90
90
for (long i = idx ; i != fs ; i ++) {
@@ -102,13 +102,19 @@ void slowpath(long r) {
102
102
return ;
103
103
}
104
104
105
+ e -= fs - idx ;
106
+
105
107
idx = fs ;
106
- index = fs ;
107
108
108
- r = addAndGet (- e ) ;
109
+ r = get () + e ;
109
110
if (r == 0L ) {
110
- // we're done emitting the number requested so return
111
- return ;
111
+ index = fs ;
112
+ r = addAndGet (e );
113
+ if (r == 0L ) {
114
+ // we're done emitting the number requested so return
115
+ return ;
116
+ }
117
+ e = 0L ;
112
118
}
113
119
}
114
120
}
@@ -131,4 +137,4 @@ void fastpath() {
131
137
}
132
138
}
133
139
134
- }
140
+ }
Original file line number Diff line number Diff line change @@ -177,14 +177,28 @@ static final class MergeSubscriber<T> extends Subscriber<Observable<? extends T>
177
177
/** An empty array to avoid creating new empty arrays in removeInner. */
178
178
static final InnerSubscriber <?>[] EMPTY = new InnerSubscriber <?>[0 ];
179
179
180
+ int scalarEmission ;
181
+
182
+ final int scalarLimit ;
183
+
180
184
public MergeSubscriber (Subscriber <? super T > child , boolean delayErrors , int maxConcurrent ) {
181
185
this .child = child ;
182
186
this .delayErrors = delayErrors ;
183
187
this .maxConcurrent = maxConcurrent ;
184
188
this .nl = NotificationLite .instance ();
185
189
this .innerGuard = new Object ();
186
190
this .innerSubscribers = EMPTY ;
187
- request (maxConcurrent == Integer .MAX_VALUE ? Long .MAX_VALUE : maxConcurrent );
191
+ long r ;
192
+ int lim ;
193
+ if (maxConcurrent == Integer .MAX_VALUE ) {
194
+ r = Long .MAX_VALUE ;
195
+ lim = Integer .MAX_VALUE ;
196
+ } else {
197
+ r = maxConcurrent ;
198
+ lim = Math .max (maxConcurrent >> 1 , 1 );
199
+ }
200
+ this .scalarLimit = lim ;
201
+ request (r );
188
202
}
189
203
190
204
Queue <Throwable > getOrCreateErrorQueue () {
@@ -488,7 +502,10 @@ protected void emitScalar(T value, long r) {
488
502
if (r != Long .MAX_VALUE ) {
489
503
producer .produced (1 );
490
504
}
491
- this .requestMore (1 );
505
+ if (++scalarEmission == scalarLimit ) {
506
+ scalarEmission = 0 ;
507
+ this .requestMore (scalarLimit );
508
+ }
492
509
// check if some state changed while emitting
493
510
synchronized (this ) {
494
511
skipFinal = true ;
You can’t perform that action at this time.
0 commit comments