Skip to content

Commit

Permalink
Merge pull request #3177 from akarnokd/BackpressureUtilsExtra
Browse files Browse the repository at this point in the history
BackpressureUtils capped add/multiply methods + tests
  • Loading branch information
akarnokd committed Aug 24, 2015
2 parents d71314e + 1cad3e6 commit 7a77072
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 10 deletions.
43 changes: 33 additions & 10 deletions src/main/java/rx/internal/operators/BackpressureUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,7 @@ public static <T> long getAndAddRequest(AtomicLongFieldUpdater<T> requested, T o
// add n to field but check for overflow
while (true) {
long current = requested.get(object);
long next = current + n;
// check for overflow
if (next < 0) {
next = Long.MAX_VALUE;
}
long next = addCap(current, n);
if (requested.compareAndSet(object, current, next)) {
return current;
}
Expand All @@ -70,14 +66,41 @@ public static long getAndAddRequest(AtomicLong requested, long n) {
// add n to field but check for overflow
while (true) {
long current = requested.get();
long next = current + n;
// check for overflow
if (next < 0) {
next = Long.MAX_VALUE;
}
long next = addCap(current, n);
if (requested.compareAndSet(current, next)) {
return current;
}
}
}

/**
* Multiplies two positive longs and caps the result at Long.MAX_VALUE.
* @param a the first value
* @param b the second value
* @return the capped product of a and b
*/
public static long multiplyCap(long a, long b) {
long u = a * b;
if (((a | b) >>> 31) != 0) {
if (b != 0L && (u / b != a)) {
u = Long.MAX_VALUE;
}
}
return u;
}

/**
* Adds two positive longs and caps the result at Long.MAX_VALUE.
* @param a the first value
* @param b the second value
* @return the capped sum of a and b
*/
public static long addCap(long a, long b) {
long u = a + b;
if (u < 0L) {
u = Long.MAX_VALUE;
}
return u;
}

}
39 changes: 39 additions & 0 deletions src/test/java/rx/internal/operators/BackpressureUtilsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright 2015 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 org.junit.Test;
import static org.junit.Assert.*;

public class BackpressureUtilsTest {
@Test
public void testAddCap() {
assertEquals(2L, BackpressureUtils.addCap(1, 1));
assertEquals(Long.MAX_VALUE, BackpressureUtils.addCap(1, Long.MAX_VALUE - 1));
assertEquals(Long.MAX_VALUE, BackpressureUtils.addCap(1, Long.MAX_VALUE));
assertEquals(Long.MAX_VALUE, BackpressureUtils.addCap(Long.MAX_VALUE - 1, Long.MAX_VALUE - 1));
assertEquals(Long.MAX_VALUE, BackpressureUtils.addCap(Long.MAX_VALUE, Long.MAX_VALUE));
}

@Test
public void testMultiplyCap() {
assertEquals(6, BackpressureUtils.multiplyCap(2, 3));
assertEquals(Long.MAX_VALUE, BackpressureUtils.multiplyCap(2, Long.MAX_VALUE));
assertEquals(Long.MAX_VALUE, BackpressureUtils.multiplyCap(Long.MAX_VALUE, Long.MAX_VALUE));
assertEquals(Long.MAX_VALUE, BackpressureUtils.multiplyCap(1L << 32, 1L << 32));

}
}

0 comments on commit 7a77072

Please sign in to comment.