All Downloads are FREE. Search and download functionalities are using the official Maven repository.

rx.internal.operators.OperatorMergeMaxConcurrent Maven / Gradle / Ivy

There is a newer version: 0.20.7
Show newest version
 /**
  * Copyright 2014 Netflix, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
  *
  * http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  * License for the specific language governing permissions and limitations under
  * the License.
  */
package rx.internal.operators;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import rx.Observable;
import rx.Observable.Operator;
import rx.Subscriber;
import rx.observers.SerializedSubscriber;
import rx.subscriptions.CompositeSubscription;

/**
 * Flattens a list of Observables into one Observable sequence, without any transformation.
 * 

* *

* You can combine the items emitted by multiple Observables so that they act like a single * Observable, by using the merge operation. * * @param the emitted value type */ public final class OperatorMergeMaxConcurrent implements Operator> { final int maxConcurrency; public OperatorMergeMaxConcurrent(int maxConcurrency) { this.maxConcurrency = maxConcurrency; } @Override public Subscriber> call(Subscriber child) { final SerializedSubscriber s = new SerializedSubscriber(child); final CompositeSubscription csub = new CompositeSubscription(); child.add(csub); return new SourceSubscriber(maxConcurrency, s, csub); } static final class SourceSubscriber extends Subscriber> { final int maxConcurrency; final Subscriber s; final CompositeSubscription csub; final Object guard; volatile int wip; @SuppressWarnings("rawtypes") static final AtomicIntegerFieldUpdater WIP_UPDATER = AtomicIntegerFieldUpdater.newUpdater(SourceSubscriber.class, "wip"); /** Guarded by guard. */ int active; /** Guarded by guard. */ final Queue> queue; public SourceSubscriber(int maxConcurrency, Subscriber s, CompositeSubscription csub) { super(s); this.maxConcurrency = maxConcurrency; this.s = s; this.csub = csub; this.guard = new Object(); this.queue = new LinkedList>(); this.wip = 1; } @Override public void onNext(Observable t) { synchronized (guard) { queue.add(t); } subscribeNext(); } void subscribeNext() { Observable t; synchronized (guard) { t = queue.peek(); if (t == null || active >= maxConcurrency) { return; } active++; queue.poll(); } Subscriber itemSub = new Subscriber() { boolean once = true; @Override public void onNext(T t) { s.onNext(t); } @Override public void onError(Throwable e) { SourceSubscriber.this.onError(e); } @Override public void onCompleted() { if (once) { once = false; synchronized (guard) { active--; } csub.remove(this); subscribeNext(); SourceSubscriber.this.onCompleted(); } } }; csub.add(itemSub); WIP_UPDATER.incrementAndGet(this); t.unsafeSubscribe(itemSub); } @Override public void onError(Throwable e) { s.onError(e); unsubscribe(); } @Override public void onCompleted() { if (WIP_UPDATER.decrementAndGet(this) == 0) { s.onCompleted(); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy