From 8a905fbb1873d01adaa94007b13ca61465a34651 Mon Sep 17 00:00:00 2001 From: Vitaliy Biryukov Date: Thu, 26 Apr 2018 17:26:23 +0300 Subject: [PATCH 1/7] IGNITE-7986: GridPartitionStateMap.entrySet() optimization. --- .../internal/util/GridPartitionStateMap.java | 28 ++++++++++++------- .../ignite/util/GridPartitionMapSelfTest.java | 26 ++++++++++++++++- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java b/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java index f5893c02f77b4..0a9578d96c9ac 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java @@ -52,35 +52,43 @@ public class GridPartitionStateMap extends AbstractMap> entrySet() { return new AbstractSet>() { @Override public Iterator> iterator() { - final int size = states.isEmpty() ? 0 : (states.length() - 1) / BITS + 1; - return new Iterator>() { - private int next; + private int idx; private int cur; @Override public boolean hasNext() { - while(state(next) == null && next < size) - next++; + idx = states.nextSetBit(idx); - return next < size; + return idx != -1; } @Override public Entry next() { if (!hasNext()) throw new NoSuchElementException(); - cur = next; - next++; + cur = idx / BITS; + + int bitN = idx % BITS; + + int st = 1 << bitN; + + for (int i = 1; i < BITS - bitN; i++) + st |= (states.get(idx + i) ? 1 : 0) << i + bitN; + + final int ordinal = st - 1; + + idx += (BITS - bitN); return new Entry() { int p = cur; + int state = ordinal; @Override public Integer getKey() { return p; } @Override public GridDhtPartitionState getValue() { - return state(p); + return GridDhtPartitionState.fromOrdinal(state); } @Override public GridDhtPartitionState setValue(GridDhtPartitionState val) { @@ -219,4 +227,4 @@ private GridDhtPartitionState state(int part) { @Override public int hashCode() { return 31 * states.hashCode() + size; } -} \ No newline at end of file +} diff --git a/modules/core/src/test/java/org/apache/ignite/util/GridPartitionMapSelfTest.java b/modules/core/src/test/java/org/apache/ignite/util/GridPartitionMapSelfTest.java index ebb4cd73b31e9..829626e38a3fd 100644 --- a/modules/core/src/test/java/org/apache/ignite/util/GridPartitionMapSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/util/GridPartitionMapSelfTest.java @@ -19,6 +19,7 @@ import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.Map; import java.util.Set; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState; @@ -26,6 +27,8 @@ import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.apache.ignite.testframework.junits.common.GridCommonTest; +import static org.junit.Assert.assertNotEquals; + /** * Grid utils tests. */ @@ -144,6 +147,27 @@ public void testCopyNoActive() { assertEquals(1, cp2.size()); } + /** + * + */ + public void testIteratorNext() { + GridPartitionStateMap map = new GridPartitionStateMap(); + + initMap(map); + + Iterator> iter = map.entrySet().iterator(); + + Map.Entry entry1 = iter.next(); + Map.Entry entry2 = iter.next(); + + iter.remove(); + + assertNotNull(entry1.getValue()); + assertNotNull(entry2.getValue()); + assertNotEquals(entry1.getKey(), entry2.getKey()); + assertNotEquals(entry1.getValue(), entry2.getValue()); + } + /** */ private GridPartitionStateMap initMap(GridPartitionStateMap map) { map.put(0, GridDhtPartitionState.MOVING); @@ -159,4 +183,4 @@ private GridPartitionStateMap initMap(GridPartitionStateMap map) { return map; } -} \ No newline at end of file +} From 76e95403470c3a1af406a4845436f19027742ff7 Mon Sep 17 00:00:00 2001 From: Vitaliy Biryukov Date: Thu, 3 May 2018 15:07:42 +0300 Subject: [PATCH 2/7] IGNITE-7986: review fix. --- .../ignite/internal/util/GridPartitionStateMap.java | 1 + .../apache/ignite/util/GridPartitionMapSelfTest.java | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java b/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java index 0a9578d96c9ac..81b2a22aeba0c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java @@ -70,6 +70,7 @@ public class GridPartitionStateMap extends AbstractMap Date: Thu, 3 May 2018 15:48:20 +0300 Subject: [PATCH 3/7] IGNITE-7986: Removed copy of the field. --- .../org/apache/ignite/internal/util/GridPartitionStateMap.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java b/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java index 81b2a22aeba0c..feccbb92b125c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java @@ -82,14 +82,13 @@ public class GridPartitionStateMap extends AbstractMap() { int p = cur; - int state = ordinal; @Override public Integer getKey() { return p; } @Override public GridDhtPartitionState getValue() { - return GridDhtPartitionState.fromOrdinal(state); + return GridDhtPartitionState.fromOrdinal(ordinal); } @Override public GridDhtPartitionState setValue(GridDhtPartitionState val) { From 31f5a43d0ce11791fb3da904e3214e8cb6c889eb Mon Sep 17 00:00:00 2001 From: Vitaliy Biryukov Date: Thu, 3 May 2018 22:03:59 +0300 Subject: [PATCH 4/7] IGNITE-7986: Review fix. Javadocs and test. --- .../internal/util/GridPartitionStateMap.java | 18 +++++++++++++++++- .../ignite/util/GridPartitionMapSelfTest.java | 7 +++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java b/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java index feccbb92b125c..53a17369a51c5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java @@ -42,7 +42,20 @@ public class GridPartitionStateMap extends AbstractMap + * +-----------+-----------+-----------+ + * | p0 - 100 | p1 - 011 | p2 - 001 | + * +---+---+---++--+---+---+---+---+---+ + * | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | + * +---+---+---+---+---+---+---+---+---+ + * + * + * The first element takes the first {@link GridPartitionStateMap#BITS} bits in reverse order, + * the second element next {@link GridPartitionStateMap#BITS} bits in reverse order, etc. + */ private final BitSet states; /** */ @@ -53,7 +66,10 @@ public class GridPartitionStateMap extends AbstractMap>() { @Override public Iterator> iterator() { return new Iterator>() { + /** Current {@link GridPartitionStateMap#states} index. */ private int idx; + + /** Current key value. */ private int cur; @Override public boolean hasNext() { diff --git a/modules/core/src/test/java/org/apache/ignite/util/GridPartitionMapSelfTest.java b/modules/core/src/test/java/org/apache/ignite/util/GridPartitionMapSelfTest.java index 3964c32c92487..aeaf07e3ad23c 100644 --- a/modules/core/src/test/java/org/apache/ignite/util/GridPartitionMapSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/util/GridPartitionMapSelfTest.java @@ -155,7 +155,14 @@ public void testIteratorNext() { Iterator> iter = map.entrySet().iterator(); + for (int i = 0; i < map.size() + 1; i++) + assertTrue(iter.hasNext()); + Map.Entry entry1 = iter.next(); + + for (int i = 0; i < map.size() + 1; i++) + assertTrue(iter.hasNext()); + Map.Entry entry2 = iter.next(); iter.remove(); From 51619eef326c39eea2b431fc08bb044e3e48c4a3 Mon Sep 17 00:00:00 2001 From: Vitaliy Biryukov Date: Thu, 3 May 2018 22:07:09 +0300 Subject: [PATCH 5/7] IGNITE-7986: Empty line removed. --- .../org/apache/ignite/internal/util/GridPartitionStateMap.java | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java b/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java index 53a17369a51c5..57eb0564b30ec 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java @@ -52,7 +52,6 @@ public class GridPartitionStateMap extends AbstractMap - * * The first element takes the first {@link GridPartitionStateMap#BITS} bits in reverse order, * the second element next {@link GridPartitionStateMap#BITS} bits in reverse order, etc. */ From 7bcac5a24012f7ecd80b1fd9fb8547ed4049ffa7 Mon Sep 17 00:00:00 2001 From: Vitaliy Biryukov Date: Thu, 3 May 2018 22:17:05 +0300 Subject: [PATCH 6/7] IGNITE-7986: fix javadoc. --- .../org/apache/ignite/internal/util/GridPartitionStateMap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java b/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java index 57eb0564b30ec..b256da9edcb1e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java @@ -48,7 +48,7 @@ public class GridPartitionStateMap extends AbstractMap * +-----------+-----------+-----------+ * | p0 - 100 | p1 - 011 | p2 - 001 | - * +---+---+---++--+---+---+---+---+---+ + * +---+---+---+---+---+---+---+---+---+ * | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | * +---+---+---+---+---+---+---+---+---+ * From 226444cbed082e2aa4c6636ea0514e67ca6c7175 Mon Sep 17 00:00:00 2001 From: Vitaliy Biryukov Date: Fri, 4 May 2018 15:05:15 +0300 Subject: [PATCH 7/7] IGNITE-7986: Review. Added test. --- .../ignite/util/GridPartitionMapSelfTest.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/modules/core/src/test/java/org/apache/ignite/util/GridPartitionMapSelfTest.java b/modules/core/src/test/java/org/apache/ignite/util/GridPartitionMapSelfTest.java index aeaf07e3ad23c..b099cf93e8633 100644 --- a/modules/core/src/test/java/org/apache/ignite/util/GridPartitionMapSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/util/GridPartitionMapSelfTest.java @@ -22,6 +22,8 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; +import java.util.TreeMap; +import java.util.concurrent.ThreadLocalRandom; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState; import org.apache.ignite.internal.util.GridPartitionStateMap; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; @@ -177,6 +179,62 @@ public void testIteratorNext() { assertEquals(GridDhtPartitionState.RENTING, entry2.getValue()); } + /** + * Tests {@link GridDhtPartitionState} compatibility with {@link TreeMap} on random operations. + */ + public void testOnRandomOperations() { + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + + Map treeMap = new TreeMap<>(); + Map gridMap = new GridPartitionStateMap(); + + int statesNum = GridDhtPartitionState.values().length; + + for (int i = 0; i < 10_000; i++) { + Integer part = rnd.nextInt(1024); + + GridDhtPartitionState state = GridDhtPartitionState.fromOrdinal(rnd.nextInt(statesNum)); + + int rndOperation = rnd.nextInt(9); + + if (rndOperation <= 5) { + treeMap.put(part, state); + gridMap.put(part, state); + } + else if (rndOperation == 6) { + treeMap.remove(part); + gridMap.remove(part); + } + else if (treeMap.size() > 0) { + int n = rnd.nextInt(0, treeMap.size()); + + Iterator> iter1 = treeMap.entrySet().iterator(); + Iterator> iter2 = gridMap.entrySet().iterator(); + + Map.Entry entry1 = iter1.next(); + Map.Entry entry2 = iter2.next(); + + for (int j = 1; j <= n; j++) { + entry1 = iter1.next(); + entry2 = iter2.next(); + } + + if (rndOperation == 7) { + entry1.setValue(state); + entry2.setValue(state); + } + else { + iter1.remove(); + iter2.remove(); + } + } + + assertEquals(treeMap.size(), gridMap.size()); + } + + assertEquals(treeMap, gridMap); + } + /** */ private GridPartitionStateMap initMap(GridPartitionStateMap map) { map.put(0, GridDhtPartitionState.MOVING);