@@ -91,7 +91,7 @@ public void onStart() {
9191 // we decouple the Producer chain while keeping the Subscription chain together (perf benefit) via super(actual)
9292 request (RxRingBuffer .SIZE );
9393 }
94-
94+
9595 /*
9696 * This is expected to be executed sequentially as per the Rx contract or it will not work.
9797 */
@@ -309,12 +309,7 @@ public Boolean call(InnerSubscriber<T> s) {
309309 if (s .q != null ) {
310310 long r = mergeProducer .requested ;
311311 int emitted = 0 ;
312- if (r < 0 ) {
313- emitted += drainAll (s );
314- } else if (r > 0 ) {
315- emitted += drainRequested (s , r );
316- }
317-
312+ emitted += s .drainQueue ();
318313 if (emitted > 0 ) {
319314 /*
320315 * `s.emitted` is not volatile (because of performance impact of making it so shown by JMH tests)
@@ -336,46 +331,6 @@ public Boolean call(InnerSubscriber<T> s) {
336331 return Boolean .TRUE ;
337332 }
338333
339- private int drainRequested (InnerSubscriber <T > s , long r ) {
340- int emitted = 0 ;
341- // drain what was requested
342- long toEmit = r ;
343- Object o ;
344- for (int i = 0 ; i < toEmit ; i ++) {
345- o = s .q .poll ();
346- if (o == null ) {
347- // no more items
348- break ;
349- } else if (s .q .isCompleted (o )) {
350- completeInner (s );
351- } else {
352- if (!s .q .accept (o , actual )) {
353- emitted ++;
354- }
355- }
356- }
357-
358- // decrement the number we emitted from outstanding requests
359- mergeProducer .REQUESTED .getAndAdd (mergeProducer , -emitted );
360- return emitted ;
361- }
362-
363- private int drainAll (InnerSubscriber <T > s ) {
364- int emitted = 0 ;
365- // drain it all
366- Object o ;
367- while ((o = s .q .poll ()) != null ) {
368- if (s .q .isCompleted (o )) {
369- completeInner (s );
370- } else {
371- if (!s .q .accept (o , actual )) {
372- emitted ++;
373- }
374- }
375- }
376- return emitted ;
377- }
378-
379334 };
380335
381336 @ Override
@@ -451,7 +406,6 @@ private static final class InnerSubscriber<T> extends Subscriber<T> {
451406 @ SuppressWarnings ("rawtypes" )
452407 static final AtomicIntegerFieldUpdater <InnerSubscriber > ONCE_UPDATER = AtomicIntegerFieldUpdater .newUpdater (InnerSubscriber .class , "once" );
453408 private final RxRingBuffer q = RxRingBuffer .getSpmcInstance ();
454- private boolean mayNeedToDrain = false ;
455409 /* protected by emitLock */
456410 int emitted = 0 ;
457411 final int THRESHOLD = (int ) (q .capacity () * 0.7 );
@@ -526,12 +480,9 @@ private void emit(T t, boolean complete) {
526480 if (parentSubscriber .getEmitLock ()) {
527481 enqueue = false ;
528482 try {
529- // when we have the lock, nothing else can cause producer.requested to decrement, but it can increment at any time
530- if (mayNeedToDrain ) {
531- // drain the queue if there is anything in it before emitting the current value
532- emitted += drainQueue ();
533- mayNeedToDrain = false ;
534- }
483+ // drain the queue if there is anything in it before emitting the current value
484+ emitted += drainQueue ();
485+ // }
535486 if (producer == null ) {
536487 // no backpressure requested
537488 if (complete ) {
@@ -600,7 +551,7 @@ private void emit(T t, boolean complete) {
600551 * r.o.OperatorMergePerf.mergeNSyncStreamsOfN 1000 thrpt 5 78.795 1.766 ops/s
601552 * } </pre>
602553 */
603- mayNeedToDrain = ! parentSubscriber .drainQueuesIfNeeded ();
554+ parentSubscriber .drainQueuesIfNeeded ();
604555 }
605556 }
606557
@@ -611,41 +562,57 @@ private void enqueue(T t, boolean complete) {
611562 } else {
612563 q .onNext (t );
613564 }
614- mayNeedToDrain = true ;
615565 } catch (MissingBackpressureException e ) {
616566 onError (e );
617567 }
618568 }
619569
620- private int drainQueue () {
621- int emittedWhileDraining = 0 ;
622- if (q != null ) {
623- if (producer == null ) {
624- Object o ;
625- while ((o = q .poll ()) != null ) {
626- if (!q .accept (o , parentSubscriber .actual )) {
627- // non-terminal event so let's increment count
628- emittedWhileDraining ++;
629- }
570+ private int drainRequested () {
571+ int emitted = 0 ;
572+ // drain what was requested
573+ long toEmit = producer .requested ;
574+ Object o ;
575+ for (int i = 0 ; i < toEmit ; i ++) {
576+ o = q .poll ();
577+ if (o == null ) {
578+ // no more items
579+ break ;
580+ } else if (q .isCompleted (o )) {
581+ parentSubscriber .completeInner (this );
582+ } else {
583+ if (!q .accept (o , parentSubscriber .actual )) {
584+ emitted ++;
630585 }
586+ }
587+ }
588+
589+ // decrement the number we emitted from outstanding requests
590+ producer .REQUESTED .getAndAdd (producer , -emitted );
591+ return emitted ;
592+ }
593+
594+ private int drainAll () {
595+ int emitted = 0 ;
596+ // drain it all
597+ Object o ;
598+ while ((o = q .poll ()) != null ) {
599+ if (q .isCompleted (o )) {
600+ parentSubscriber .completeInner (this );
631601 } else {
632- long toEmit = producer .requested ;
633- for (int i = 0 ; i < toEmit ; i ++) {
634- Object o = q .poll ();
635- if (o == null ) {
636- break ;
637- } else {
638- if (!q .accept (o , parentSubscriber .actual )) {
639- // non-terminal event so let's increment count
640- emittedWhileDraining ++;
641- }
642- }
602+ if (!q .accept (o , parentSubscriber .actual )) {
603+ emitted ++;
643604 }
644- // decrement the number we emitted from outstanding requests
645- producer .REQUESTED .getAndAdd (producer , -emittedWhileDraining );
646605 }
647606 }
648- return emittedWhileDraining ;
607+ return emitted ;
608+ }
609+
610+ private int drainQueue () {
611+ if (producer != null ) {
612+ return drainRequested ();
613+ } else {
614+ return drainAll ();
615+ }
649616 }
650617 }
651618}
0 commit comments