From 1362dab2c10d00705f5e0528ab48b964468483e3 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Thu, 6 Aug 2020 21:36:45 +0300 Subject: [PATCH] Updated BinUtil and CoordinatePacker - Added packing 2 ints into a long to CoordinatePacker - Added iPowerOf2(int) to BinUtil --- .../windcorp/optica/common/util/BinUtil.java | 4 ++ .../optica/common/util/CoordinatePacker.java | 27 ++++++- .../optica/util/BinUtilIsPowerOf2Test.java | 72 +++++++++++++++++++ ...BinUtilTest.java => BinUtilRoundTest.java} | 2 +- .../optica/util/CoordinatePacker2Test.java | 69 ++++++++++++++++++ ...erTest.java => CoordinatePacker3Test.java} | 2 +- 6 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 src/test/java/ru/windcorp/optica/util/BinUtilIsPowerOf2Test.java rename src/test/java/ru/windcorp/optica/util/{BinUtilTest.java => BinUtilRoundTest.java} (94%) create mode 100644 src/test/java/ru/windcorp/optica/util/CoordinatePacker2Test.java rename src/test/java/ru/windcorp/optica/util/{CoordinatePackerTest.java => CoordinatePacker3Test.java} (95%) diff --git a/src/main/java/ru/windcorp/optica/common/util/BinUtil.java b/src/main/java/ru/windcorp/optica/common/util/BinUtil.java index 43b8424..10193fd 100644 --- a/src/main/java/ru/windcorp/optica/common/util/BinUtil.java +++ b/src/main/java/ru/windcorp/optica/common/util/BinUtil.java @@ -31,5 +31,9 @@ public class BinUtil { public static int roundToGreaterPowerOf2(int x) { return closestGreaterPowerOf2(x - 1); } + + public static boolean isPowerOf2(int x) { + return (x > 0) && ((x & (x - 1)) == 0); + } } diff --git a/src/main/java/ru/windcorp/optica/common/util/CoordinatePacker.java b/src/main/java/ru/windcorp/optica/common/util/CoordinatePacker.java index 5d2f297..d54e6e2 100644 --- a/src/main/java/ru/windcorp/optica/common/util/CoordinatePacker.java +++ b/src/main/java/ru/windcorp/optica/common/util/CoordinatePacker.java @@ -22,6 +22,9 @@ public class CoordinatePacker { private static final int BITS_3_INTS_INTO_LONG; private static final long MASK_3_INTS_INTO_LONG; + private static final int BITS_2_INTS_INTO_LONG; + private static final long MASK_2_INTS_INTO_LONG; + static { BITS_3_INTS_INTO_LONG = 64 / 3; @@ -37,7 +40,10 @@ public class CoordinatePacker { * \_________/ - BITS_3_INTS_INTO_LONG ones - WIN */ - MASK_3_INTS_INTO_LONG = (1 << BITS_3_INTS_INTO_LONG) - 1; + MASK_3_INTS_INTO_LONG = (1l << BITS_3_INTS_INTO_LONG) - 1; + + BITS_2_INTS_INTO_LONG = 64 / 2; + MASK_2_INTS_INTO_LONG = (1l << BITS_2_INTS_INTO_LONG) - 1; } public static long pack3IntsIntoLong(int a, int b, int c) { @@ -65,5 +71,24 @@ public class CoordinatePacker { return result; } + + public static long pack2IntsIntoLong(int a, int b) { + return + ((a & MASK_2_INTS_INTO_LONG) << (1 * BITS_2_INTS_INTO_LONG)) | + ((b & MASK_2_INTS_INTO_LONG) << (0 * BITS_2_INTS_INTO_LONG)); + } + + public static int unpack2IntsFromLong(long packed, int index) { + if (index < 0 || index >= 2) { + throw new IllegalArgumentException("Invalid index " + index); + } + + int result = (int) ( + (packed >>> ((1 - index) * BITS_2_INTS_INTO_LONG)) + & MASK_2_INTS_INTO_LONG + ); + + return result; + } } diff --git a/src/test/java/ru/windcorp/optica/util/BinUtilIsPowerOf2Test.java b/src/test/java/ru/windcorp/optica/util/BinUtilIsPowerOf2Test.java new file mode 100644 index 0000000..8db1b18 --- /dev/null +++ b/src/test/java/ru/windcorp/optica/util/BinUtilIsPowerOf2Test.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Optica + * Copyright (C) 2020 Wind Corporation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *******************************************************************************/ +package ru.windcorp.optica.util; + +import static org.junit.Assert.assertEquals; + +import java.util.Random; + +import org.junit.Test; + +import ru.windcorp.optica.common.util.BinUtil; + +public class BinUtilIsPowerOf2Test { + + @Test + public void cornerCases() { + test(-1); + test(0); + test(1); + + test(15); + test(16); + test(17); + + test(1 << 30); + test(Integer.MAX_VALUE); + test(Integer.MIN_VALUE); + } + + @Test + public void random() { + Random random = new Random(0); + + for (int x = 0; x < 10000; ++x) { + test(x); + } + + for (int i = 0; i < 10000; ++i) { + test(random.nextInt()); + } + } + + void test(int x) { + assertEquals("Round, x = " + x, referenceIsPowerOf2(x), BinUtil.isPowerOf2(x)); + } + + boolean referenceIsPowerOf2(int x) { + for (int power = 1; power > 0; power *= 2) { + if (x == power) { + return true; + } + } + + return false; + } + +} diff --git a/src/test/java/ru/windcorp/optica/util/BinUtilTest.java b/src/test/java/ru/windcorp/optica/util/BinUtilRoundTest.java similarity index 94% rename from src/test/java/ru/windcorp/optica/util/BinUtilTest.java rename to src/test/java/ru/windcorp/optica/util/BinUtilRoundTest.java index 0588084..b959a81 100644 --- a/src/test/java/ru/windcorp/optica/util/BinUtilTest.java +++ b/src/test/java/ru/windcorp/optica/util/BinUtilRoundTest.java @@ -25,7 +25,7 @@ import org.junit.Test; import ru.windcorp.optica.common.util.BinUtil; -public class BinUtilTest { +public class BinUtilRoundTest { @Test public void cornerCases() { diff --git a/src/test/java/ru/windcorp/optica/util/CoordinatePacker2Test.java b/src/test/java/ru/windcorp/optica/util/CoordinatePacker2Test.java new file mode 100644 index 0000000..b7b667f --- /dev/null +++ b/src/test/java/ru/windcorp/optica/util/CoordinatePacker2Test.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Optica + * Copyright (C) 2020 Wind Corporation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *******************************************************************************/ +package ru.windcorp.optica.util; + +import static org.junit.Assert.assertEquals; + +import java.util.Random; + +import org.junit.Test; + +import ru.windcorp.optica.common.util.CoordinatePacker; + +public class CoordinatePacker2Test { + + @Test + public void cornerCases() { + check(0, 0); + check(0, 42); + check(42, 0); + check(1, 1); + check(-1, -1); + + for (int a : new int[] {Integer.MAX_VALUE, Integer.MIN_VALUE, 0}) { + for (int b : new int[] {Integer.MAX_VALUE, Integer.MIN_VALUE, 0}) { + check(a, b); + } + } + } + + @Test + public void randomValues() { + Random random = new Random(0);; + + for (int i = 0; i < 1000000; ++i) { + check( + random.nextInt(), + random.nextInt() + ); + } + } + + private void check(int a, int b) { + + long packed = CoordinatePacker.pack2IntsIntoLong(a, b); + + int unpackedA = CoordinatePacker.unpack2IntsFromLong(packed, 0); + int unpackedB = CoordinatePacker.unpack2IntsFromLong(packed, 1); + + assertEquals(a, unpackedA); + assertEquals(b, unpackedB); + + } + +} diff --git a/src/test/java/ru/windcorp/optica/util/CoordinatePackerTest.java b/src/test/java/ru/windcorp/optica/util/CoordinatePacker3Test.java similarity index 95% rename from src/test/java/ru/windcorp/optica/util/CoordinatePackerTest.java rename to src/test/java/ru/windcorp/optica/util/CoordinatePacker3Test.java index 9768c45..06fcb46 100644 --- a/src/test/java/ru/windcorp/optica/util/CoordinatePackerTest.java +++ b/src/test/java/ru/windcorp/optica/util/CoordinatePacker3Test.java @@ -25,7 +25,7 @@ import org.junit.Test; import ru.windcorp.optica.common.util.CoordinatePacker; -public class CoordinatePackerTest { +public class CoordinatePacker3Test { @Test public void cornerCases() {