From 9b503e5043932a3875558d601841ff7ae17c2500 Mon Sep 17 00:00:00 2001 From: zsxwing Date: Sun, 30 Nov 2014 00:52:49 +0800 Subject: [PATCH] Fix the bug that Scan may request 0 when n is 1 --- .../rx/internal/operators/OperatorScan.java | 17 +++++++++++++++-- .../rx/internal/operators/OperatorScanTest.java | 17 +++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/main/java/rx/internal/operators/OperatorScan.java b/src/main/java/rx/internal/operators/OperatorScan.java index b0685edb3f..2621ec452d 100644 --- a/src/main/java/rx/internal/operators/OperatorScan.java +++ b/src/main/java/rx/internal/operators/OperatorScan.java @@ -140,17 +140,30 @@ public void setProducer(final Producer producer) { final AtomicBoolean once = new AtomicBoolean(); + final AtomicBoolean excessive = new AtomicBoolean(); + @Override public void request(long n) { if (once.compareAndSet(false, true)) { if (initialValue == NO_INITIAL_VALUE || n == Long.MAX_VALUE) { producer.request(n); } else { - producer.request(n - 1); + if (n == Long.MAX_VALUE) { + producer.request(Long.MAX_VALUE); + } else if (n == 1) { + excessive.set(true); + producer.request(1); // request at least 1 + } else { + producer.request(n - 1); + } } } else { // pass-thru after first time - producer.request(n); + if (excessive.compareAndSet(true, false) && n != Long.MAX_VALUE) { + producer.request(n - 1); + } else { + producer.request(n); + } } } }); diff --git a/src/test/java/rx/internal/operators/OperatorScanTest.java b/src/test/java/rx/internal/operators/OperatorScanTest.java index a2361c1e6f..e3ed546347 100644 --- a/src/test/java/rx/internal/operators/OperatorScanTest.java +++ b/src/test/java/rx/internal/operators/OperatorScanTest.java @@ -295,4 +295,21 @@ public void call(List list, Integer t2) { assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), o.toBlocking().single()); assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), o.toBlocking().single()); } + + @Test + public void testScanWithRequestOne() { + Observable o = Observable.just(1, 2).scan(0, new Func2() { + + @Override + public Integer call(Integer t1, Integer t2) { + return t1 + t2; + } + + }).take(1); + TestSubscriber subscriber = new TestSubscriber(); + o.subscribe(subscriber); + subscriber.assertReceivedOnNext(Arrays.asList(0)); + subscriber.assertTerminalEvent(); + subscriber.assertNoErrors(); + } }