You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2016/03/04 18:30:17 UTC
[05/14] incubator-geode git commit: Fix for GEODE-106 Invalidate
operation fails with IndexMaintenanceException with underlying
java.lang.ArrayIndexOutOfBoundsException.
Fix for GEODE-106 Invalidate operation fails with IndexMaintenanceException with underlying java.lang.ArrayIndexOutOfBoundsException.
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/39969409
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/39969409
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/39969409
Branch: refs/heads/feature/GEODE-949-2
Commit: 3996940954e6099fb927c1703a2c085760c4899a
Parents: c18f515
Author: Anil <ag...@pivotal.io>
Authored: Wed Feb 24 17:13:04 2016 -0800
Committer: Anil <ag...@pivotal.io>
Committed: Tue Mar 1 16:13:13 2016 -0800
----------------------------------------------------------------------
.../query/internal/index/IndexElemArray.java | 34 +++++-----
.../internal/index/IndexElemArrayJUnitTest.java | 66 +++++++++++++++++---
2 files changed, 74 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/39969409/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/IndexElemArray.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/IndexElemArray.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/IndexElemArray.java
index de694a4..7fdce2d 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/IndexElemArray.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/IndexElemArray.java
@@ -199,18 +199,20 @@ public class IndexElemArray implements Iterable, Collection {
* @return <tt>true</tt> if this list contained the specified element
*/
public boolean remove(Object o) {
- if (o == null) {
- for (int index = 0; index < size; index++)
- if (elementData[index] == null) {
- fastRemove(index);
- return true;
- }
- } else {
- for (int index = 0; index < size; index++)
- if (o.equals(elementData[index])) {
- fastRemove(index);
- return true;
- }
+ synchronized (lock) {
+ if (o == null) {
+ for (int index = 0; index < size; index++)
+ if (elementData[index] == null) {
+ fastRemove(index);
+ return true;
+ }
+ } else {
+ for (int index = 0; index < size; index++)
+ if (o.equals(elementData[index])) {
+ fastRemove(index);
+ return true;
+ }
+ }
}
return false;
}
@@ -224,13 +226,11 @@ public class IndexElemArray implements Iterable, Collection {
Object[] newArray = new Object[len - 1];
System.arraycopy(elementData, 0, newArray, 0, index);
int numMoved = len - index - 1;
- if (numMoved > 0)
+ if (numMoved > 0) {
System.arraycopy(elementData, index + 1, newArray, index, numMoved);
-
- synchronized (lock) {
- elementData = newArray;
- --size;
}
+ elementData = newArray;
+ --size;
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/39969409/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/IndexElemArrayJUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/IndexElemArrayJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/IndexElemArrayJUnitTest.java
index 8c51264..91dbf7b 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/IndexElemArrayJUnitTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/IndexElemArrayJUnitTest.java
@@ -19,36 +19,37 @@ package com.gemstone.gemfire.cache.query.internal.index;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Iterator;
+import java.util.Random;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.stream.IntStream;
import org.junit.After;
import org.junit.Test;
import org.junit.experimental.categories.Category;
+import com.gemstone.gemfire.cache.query.MultithreadedTester;
import com.gemstone.gemfire.test.junit.categories.UnitTest;
@Category(UnitTest.class)
public class IndexElemArrayJUnitTest {
- private IndexElemArray list;
+ private IndexElemArray list = new IndexElemArray(7);
@After
public void tearDown() {
- System.clearProperty("index_elemarray_size");
+ //System.clearProperty("index_elemarray_size");
}
@Test
public void testFunctionality() throws Exception {
- // test disabled due to frequent failures that indicate that the product
- // is malfunctioning. See internal ticket #52285
- if (true) {
- return;
- }
- System.setProperty("index_elemarray_size", "7");
- list = new IndexElemArray();
+ list.clear();
boundaryCondition();
add();
clearAndAdd();
@@ -62,6 +63,52 @@ public class IndexElemArrayJUnitTest {
clearAndAdd();
}
+ @Test
+ /**
+ * This tests concurrent modification of IndexElemArray and to make
+ * sure elementData and size are updated atomically. Ticket# GEODE-106.
+ */
+ public void testFunctionalityUsingMultiThread() throws Exception {
+ list.clear();
+ Collection<Callable> callables = new ConcurrentLinkedQueue<>();
+ IntStream.range(0, 1000).parallel().forEach(i -> {
+ callables.add(() -> {
+ if (i%3 == 0) {
+ return add(Integer.valueOf(new Random().nextInt(4)));
+ } else if (i%3 == 1) {
+ return remove(Integer.valueOf(new Random().nextInt(4)));
+ } else {
+ return iterateList();
+ }
+ });
+ });
+
+ Collection<Object> results = MultithreadedTester.runMultithreaded(callables);
+ results.forEach(result -> {
+ // There should not be any Exception here.
+ // E.g. ArrayIndexOutOfBoundsException when multiple threads are acting.
+ assertTrue(result.getClass().getName() + " was not an expected result", result instanceof Integer);
+ });
+ }
+
+ private Integer add(Integer i) {
+ list.add(i);
+ return i;
+ }
+
+ private Integer remove(Integer i) {
+ list.remove(i);
+ return i;
+ }
+
+ private Integer iterateList() {
+ Iterator iter = list.iterator();
+ if (iter.hasNext()){
+ iter.next();
+ }
+ return Integer.valueOf(list.size());
+ }
+
private void add() {
Object objBefore = list.getElementData();
insert(7);
@@ -134,4 +181,5 @@ public class IndexElemArrayJUnitTest {
// ok
}
}
+
}