This is an automated email from the ASF dual-hosted git repository.

jin pushed a commit to branch pd-store
in repository https://gitbox.apache.org/repos/asf/incubator-hugegraph.git

commit e705740e1ee6426eac2d98019f8c7965c575319e
Author: conghuhu <[email protected]>
AuthorDate: Wed Oct 25 04:25:07 2023 -0500

    fix(core): handle schema Cache expandCapacity concurrent problem (#2332)
---
 .../hugegraph/backend/store/ram/IntObjectMap.java  |  9 +--
 .../org/apache/hugegraph/unit/UnitTestSuite.java   |  6 +-
 .../hugegraph/unit/store/RamIntObjectMapTest.java  | 72 ++++++++++++++++++++++
 3 files changed, 82 insertions(+), 5 deletions(-)

diff --git 
a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/ram/IntObjectMap.java
 
b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/ram/IntObjectMap.java
index 78af531a0..735f423ce 100644
--- 
a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/ram/IntObjectMap.java
+++ 
b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/ram/IntObjectMap.java
@@ -29,8 +29,8 @@ public final class IntObjectMap<V> implements RamMap {
     private static final float DEFAULT_INITIAL_FACTOR = 0.25f;
 
     private final int maxSize;
-    private int currentSize;
-    private Object[] array;
+    private volatile int currentSize;
+    private volatile Object[] array;
 
     public IntObjectMap(int size) {
         this.maxSize = size;
@@ -79,10 +79,11 @@ public final class IntObjectMap<V> implements RamMap {
         if (this.currentSize == this.maxSize) {
             return;
         }
-        this.currentSize = Math.min(this.currentSize * 2, this.maxSize);
-        Object[] newArray = new Object[this.currentSize];
+        int newSize = Math.min(this.currentSize * 2, this.maxSize);
+        Object[] newArray = new Object[newSize];
         System.arraycopy(this.array, 0, newArray, 0, this.array.length);
         this.clear();
         this.array = newArray;
+        this.currentSize = newSize;
     }
 }
diff --git 
a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/UnitTestSuite.java
 
b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/UnitTestSuite.java
index 3b8071f9f..d72269a4f 100644
--- 
a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/UnitTestSuite.java
+++ 
b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/unit/UnitTestSuite.java
@@ -27,6 +27,7 @@ import org.apache.hugegraph.unit.mysql.WhereBuilderTest;
 import org.apache.hugegraph.unit.rocksdb.RocksDBCountersTest;
 import org.apache.hugegraph.unit.rocksdb.RocksDBSessionTest;
 import org.apache.hugegraph.unit.rocksdb.RocksDBSessionsTest;
+import org.apache.hugegraph.unit.store.RamIntObjectMapTest;
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
 
@@ -148,7 +149,10 @@ import 
org.apache.hugegraph.unit.util.collection.ObjectIntMappingTest;
     Int2IntsMapTest.class,
     IdSetTest.class,
     IntMapTest.class,
-    IntSetTest.class
+    IntSetTest.class,
+
+    /* store */
+    RamIntObjectMapTest.class
 })
 public class UnitTestSuite {
 }
diff --git 
a/hugegraph-test/src/main/java/org/apache/hugegraph/unit/store/RamIntObjectMapTest.java
 
b/hugegraph-test/src/main/java/org/apache/hugegraph/unit/store/RamIntObjectMapTest.java
new file mode 100644
index 000000000..4e9fe4d95
--- /dev/null
+++ 
b/hugegraph-test/src/main/java/org/apache/hugegraph/unit/store/RamIntObjectMapTest.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You 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 org.apache.hugegraph.unit.store;
+
+import java.util.concurrent.CountDownLatch;
+
+import org.apache.hugegraph.backend.store.ram.IntObjectMap;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class RamIntObjectMapTest {
+
+    @Test
+    public void testConcurrency() {
+        int size = 32;
+        IntObjectMap<Integer> map = new IntObjectMap<>(size);
+
+        final int numThreads = 10;
+        final CountDownLatch startSignal = new CountDownLatch(1);
+        final CountDownLatch doneSignal = new CountDownLatch(numThreads);
+
+        for (int i = 0; i < numThreads; i++) {
+            new Thread(() -> {
+                try {
+                    startSignal.await();
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                    Assert.fail(e.getMessage());
+                }
+
+                for (int j = 0; j < size; j++) {
+                    map.set(j, j);
+                }
+
+                doneSignal.countDown();
+            }).start();
+        }
+
+        startSignal.countDown();
+
+        try {
+            doneSignal.await();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+            Assert.fail(e.getMessage());
+        }
+
+        for (int i = 0; i < numThreads; i++) {
+            new Thread(() -> {
+                for (int j = 0; j < size; j++) {
+                    Integer value = map.get(j);
+                    Assert.assertNotNull(value);
+                }
+            }).start();
+        }
+    }
+}

Reply via email to