You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by md...@apache.org on 2017/05/08 10:31:30 UTC
svn commit: r1794319 - in /jackrabbit/oak/trunk/oak-commons/src:
main/java/org/apache/jackrabbit/oak/commons/IOUtils.java
test/java/org/apache/jackrabbit/oak/commons/IOUtilsTest.java
Author: mduerig
Date: Mon May 8 10:31:30 2017
New Revision: 1794319
URL: http://svn.apache.org/viewvc?rev=1794319&view=rev
Log:
OAK-6164: IOUtils.nextPowerOf2() returns lower power of 2 for very high int values
Return long instead of in from nextPowerOf2 so we can cover the whole integer range uniformly.
Credits to Matt Ryan for the patch.
Modified:
jackrabbit/oak/trunk/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/IOUtils.java
jackrabbit/oak/trunk/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/IOUtilsTest.java
Modified: jackrabbit/oak/trunk/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/IOUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/IOUtils.java?rev=1794319&r1=1794318&r2=1794319&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/IOUtils.java (original)
+++ jackrabbit/oak/trunk/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/IOUtils.java Mon May 8 10:31:30 2017
@@ -274,17 +274,20 @@ public final class IOUtils {
/**
* Get the value that is equal or higher than this value, and that is a
- * power of two.
+ * power of two. The returned value will be in the range [0, 2^31].
+ * If the input is less than zero, the result of 1 is returned (powers of
+ * negative numbers are not integer values).
*
- * @param x the original value
- * @return the next power of two value
+ * @param x the original value.
+ * @return the next power of two value. Results are always in the
+ * range [0, 2^31].
*/
- public static int nextPowerOf2(int x) {
+ public static long nextPowerOf2(int x) {
long i = 1;
- while (i < x && i < (Integer.MAX_VALUE / 2)) {
+ while (i < x) {
i += i;
}
- return (int) i;
+ return i;
}
/**
Modified: jackrabbit/oak/trunk/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/IOUtilsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/IOUtilsTest.java?rev=1794319&r1=1794318&r2=1794319&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/IOUtilsTest.java (original)
+++ jackrabbit/oak/trunk/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/IOUtilsTest.java Mon May 8 10:31:30 2017
@@ -250,6 +250,30 @@ public class IOUtilsTest extends TestCas
}
}
+ public void testNextPowerOf2() {
+ assertEquals(1L, IOUtils.nextPowerOf2(0));
+ assertEquals(1L, IOUtils.nextPowerOf2(1));
+ assertEquals(2L, IOUtils.nextPowerOf2(2));
+ assertEquals(4L, IOUtils.nextPowerOf2(3));
+ assertEquals(4L, IOUtils.nextPowerOf2(4));
+ assertEquals(8L, IOUtils.nextPowerOf2(5));
+ assertEquals(8L, IOUtils.nextPowerOf2(7));
+ assertEquals(8L, IOUtils.nextPowerOf2(8));
+ assertEquals(16L, IOUtils.nextPowerOf2(12)); // it is powers of 2, not evens
+ assertEquals(32L, IOUtils.nextPowerOf2(21)); // random mid-range number
+
+ // Test values around the upper limit of powers of 2 in the signed int range
+ assertEquals(0x01L << (Integer.SIZE-2), IOUtils.nextPowerOf2(Integer.MAX_VALUE >> 1));
+ assertEquals(0x01L << (Integer.SIZE-2), IOUtils.nextPowerOf2((Integer.MAX_VALUE >> 1) + 1));
+ assertEquals( 0x01L << ((long)Integer.SIZE - 1L), IOUtils.nextPowerOf2((Integer.MAX_VALUE >> 1) + 2));
+ assertEquals(0x01L << ((long)Integer.SIZE - 1L), IOUtils.nextPowerOf2(Integer.MAX_VALUE));
+
+ // Negative values
+ assertEquals(1L, IOUtils.nextPowerOf2(-1));
+ assertEquals(1L, IOUtils.nextPowerOf2(-2));
+ assertEquals(1L, IOUtils.nextPowerOf2(Integer.MIN_VALUE));
+ }
+
private static void testVarInt(int x, int expectedLen) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.writeVarInt(out, x);