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

bchapuis pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-baremaps.git


The following commit(s) were added to refs/heads/main by this push:
     new 8716d535 Performance improvement (#882)
8716d535 is described below

commit 8716d5354d25bffaf71272629b16ac7d8fbaf9cf
Author: yagagagaga <[email protected]>
AuthorDate: Wed Jun 26 03:46:03 2024 +0800

    Performance improvement (#882)
    
    * Improve Time Complexity from O(n) to O(1) in `DataConversions#get` in 
some cases
---
 .../baremaps/data/collection/DataConversions.java  |  11 ++
 .../data/collection/IndexedDataMapTest.java        | 192 +++++++++++++++++++++
 2 files changed, 203 insertions(+)

diff --git 
a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataConversions.java
 
b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataConversions.java
index dd327e31..1211985d 100644
--- 
a/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataConversions.java
+++ 
b/baremaps-data/src/main/java/org/apache/baremaps/data/collection/DataConversions.java
@@ -268,6 +268,17 @@ public class DataConversions {
       return map.put(key, value);
     }
 
+    @Override
+    public V get(Object key) {
+      if (map instanceof MemoryAlignedDataMap) {
+        return map.get(key);
+      } else if (map instanceof IndexedDataMap) {
+        return map.get(key);
+      } else {
+        return super.get(key);
+      }
+    }
+
     @Override
     public Set<Entry<K, V>> entrySet() {
       return new AbstractSet<>() {
diff --git 
a/baremaps-data/src/test/java/org/apache/baremaps/data/collection/IndexedDataMapTest.java
 
b/baremaps-data/src/test/java/org/apache/baremaps/data/collection/IndexedDataMapTest.java
new file mode 100644
index 00000000..5eaa87fa
--- /dev/null
+++ 
b/baremaps-data/src/test/java/org/apache/baremaps/data/collection/IndexedDataMapTest.java
@@ -0,0 +1,192 @@
+/*
+ * 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.baremaps.data.collection;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import org.apache.baremaps.data.type.IntegerDataType;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class IndexedDataMapTest {
+
+  private IndexedDataMap<Integer> map;
+
+  @BeforeEach
+  void setUp() {
+    map = new IndexedDataMap<>(new AppendOnlyLog<>(new IntegerDataType()));
+  }
+
+  @AfterEach
+  void tearDown() {
+    map.clear();
+    map = null;
+  }
+
+  @Test
+  void put() {
+    map.put(-1L, 1);
+    map.put(0L, 1);
+    map.put(1L, 1);
+    map.put(Long.MAX_VALUE, 1);
+    map.put(Long.MIN_VALUE, 1);
+    map.put(null, 1);
+
+    assertThrows(NullPointerException.class, () -> map.put(256L, null));
+  }
+
+  @Test
+  void get() {
+    map.put(1L, 1);
+    map.put(2L, 2);
+    assertEquals(2, map.get(2L));
+    assertEquals(1, map.get(1L));
+    map.put(2L, 3);
+    assertEquals(3, map.get(2L));
+    assertNull(map.get(3L));
+    assertNull(map.get(-1L));
+    assertNull(map.get(549755813888L));
+    assertNull(map.get(null));
+    map.put(549755813888L, Integer.MAX_VALUE);
+    assertEquals(Integer.MAX_VALUE, map.get(549755813888L));
+    map.put(Long.MIN_VALUE, Integer.MIN_VALUE);
+    assertEquals(Integer.MIN_VALUE, map.get(Long.MIN_VALUE));
+  }
+
+  @Test
+  void containsKey() {
+    assertFalse(map.containsKey(1));
+    assertFalse(map.containsKey(1L));
+    map.put(1L, 1);
+    assertFalse(map.containsKey(1));
+    assertFalse(map.containsKey(0L));
+    assertTrue(map.containsKey(1L));
+    assertFalse(map.containsKey(5L));
+    assertFalse(map.containsKey(256L));
+    assertFalse(map.containsKey(null));
+  }
+
+  @Test
+  void containsValue() {
+    assertFalse(map.containsValue(0));
+    assertFalse(map.containsValue(1));
+    map.put(1L, 1);
+    assertTrue(map.containsValue(1));
+    assertFalse(map.containsValue(2));
+    assertFalse(map.containsValue(255));
+    map.put(256L, 1);
+    assertFalse(map.containsValue(256));
+
+    assertThrows(NullPointerException.class, () -> map.containsValue(null));
+  }
+
+  @Test
+  void size() {
+    assertEquals(0, map.size());
+    map.put(0L, 1);
+    map.put(1L, 1);
+    assertEquals(2, map.size());
+    map.put(1L, 2);
+    assertEquals(2, map.size());
+    map.put(256L, 1);
+    assertEquals(3, map.size());
+    map.put(600L, 6);
+    assertEquals(4, map.size());
+    map.put(549755813887L, 7);
+    assertEquals(5, map.size());
+  }
+
+  @Test
+  void clear() {
+    assertTrue(map.isEmpty());
+    map.clear();
+    assertTrue(map.isEmpty());
+
+    map.put(1L, 1);
+    assertEquals(1, map.size());
+    map.put(324L, 1);
+    assertEquals(2, map.size());
+    map.clear();
+    assertTrue(map.isEmpty());
+  }
+
+  @Test
+  void keyIterator() {
+    Iterator<Long> itr1 = map.keyIterator();
+    assertFalse(itr1.hasNext());
+    assertThrows(NoSuchElementException.class, itr1::next);
+
+    for (long i = 0; i < 256; i += 2) {
+      map.put(i, 1);
+    }
+    Iterator<Long> itr2 = map.keyIterator();
+    assertTrue(itr2.hasNext());
+    for (long i = 0; i < 256; i += 2) {
+      assertEquals(i, itr2.next());
+    }
+  }
+
+  @Test
+  void valueIterator() {
+    Iterator<Integer> itr1 = map.valueIterator();
+    assertFalse(itr1.hasNext());
+    assertThrows(NoSuchElementException.class, itr1::next);
+
+    for (long i = 0; i < 256; i += 2) {
+      map.put(i, (int) (i - 1));
+    }
+    Iterator<Integer> itr2 = map.valueIterator();
+    assertTrue(itr2.hasNext());
+    for (long i = 0; i < 256; i += 2) {
+      assertEquals((int) (i - 1), itr2.next());
+    }
+  }
+
+  @Test
+  void entryIterator() {
+    Iterator<Map.Entry<Long, Integer>> itr1 = map.entryIterator();
+    assertFalse(itr1.hasNext());
+    assertThrows(NoSuchElementException.class, itr1::next);
+
+    for (long i = 0; i < 256; i += 2) {
+      map.put(i, (int) (i - 1));
+    }
+    Iterator<Map.Entry<Long, Integer>> itr2 = map.entryIterator();
+    assertTrue(itr2.hasNext());
+    for (long i = 0; i < 256; i += 2) {
+      assertEquals(Map.entry(i, (int) (i - 1)), itr2.next());
+    }
+  }
+
+  @Test
+  void isEmpty() {
+    assertTrue(map.isEmpty());
+    map.put(1L, 1);
+    assertFalse(map.isEmpty());
+    map.clear();
+    assertTrue(map.isEmpty());
+  }
+}

Reply via email to