package com.github.davidmoten.rx2.internal.flowable; import java.util.concurrent.atomic.AtomicLong; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; import io.reactivex.Flowable; import io.reactivex.internal.subscriptions.SubscriptionHelper; import io.reactivex.internal.util.BackpressureHelper; public final class FlowableRepeat<T> extends Flowable<T> { private final T value; private final long count; public FlowableRepeat(T value, long count) { this.value = value; this.count = count; } @Override protected void subscribeActual(org.reactivestreams.Subscriber<? super T> child) { RepeatSubscription<T> sub = new RepeatSubscription<T>(child, value, count); child.onSubscribe(sub); } @SuppressWarnings("serial") private static class RepeatSubscription<T> extends AtomicLong implements Subscription { private final Subscriber<? super T> child; private final T value; private final long count; private volatile boolean cancelled; private long counter; RepeatSubscription(Subscriber<? super T> child, T value, long count) { this.child = child; this.value = value; this.count = count; this.counter = count; } @Override public void request(long n) { if (SubscriptionHelper.validate(n)) { if (BackpressureHelper.add(this, n) == 0) { long requested = n; long emitted = 0; do { emitted = requested; while (requested-- > 0 && !cancelled && (count == -1 || counter-- > 0)) { child.onNext(value); } } while ((requested = this.addAndGet(-emitted)) > 0); if (count >= 0 && !cancelled) { child.onComplete(); } } } } @Override public void cancel() { this.cancelled = true; } } }