diff --git a/core/src/main/java/com/muwire/core/search/SearchIndexImpl.java b/core/src/main/java/com/muwire/core/search/SearchIndexImpl.java index 333d28d9..a468d9f6 100644 --- a/core/src/main/java/com/muwire/core/search/SearchIndexImpl.java +++ b/core/src/main/java/com/muwire/core/search/SearchIndexImpl.java @@ -1,5 +1,6 @@ package com.muwire.core.search; +import com.muwire.core.util.DataUtil; import net.metanotionz.io.Serializer; import net.metanotionz.io.block.BlockFile; import net.metanotionz.util.skiplist.SkipList; @@ -32,17 +33,8 @@ public class SearchIndexImpl { keywords.put(keyword, existingHashes); hashes.put(hash, new String[] {string}); } else { - boolean found = false; - for (int existingHash : existingHashes) { - if (existingHash == hash) { - found = true; - break; - } - } - if (!found) { - int [] newHashes = new int[existingHashes.length + 1]; - System.arraycopy(existingHashes, 0, newHashes, 0, existingHashes.length); - newHashes[newHashes.length - 1] = hash; + int [] newHashes = DataUtil.insertIntoSortedArray(existingHashes, hash); + if (newHashes != existingHashes) { keywords.put(keyword, newHashes); } diff --git a/core/src/main/java/com/muwire/core/util/DataUtil.java b/core/src/main/java/com/muwire/core/util/DataUtil.java index 2d0ebbad..d8491cac 100644 --- a/core/src/main/java/com/muwire/core/util/DataUtil.java +++ b/core/src/main/java/com/muwire/core/util/DataUtil.java @@ -5,13 +5,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; import com.muwire.core.Constants; @@ -237,4 +231,24 @@ public class DataUtil { } return name.substring(lastDot + 1); } + + /** + * Inserts an integer into an array if it's not already present + * @param array of sorted unique integers + * @param value to insert + * @return the same instance or a new instance with the element included + */ + public static int[] insertIntoSortedArray(int [] array, int value) { + int pos = Arrays.binarySearch(array, value); + if (pos >= 0) + return array; + pos = - pos - 1; + int [] rv = new int[array.length + 1]; + if (pos > 0) + System.arraycopy(array, 0, rv, 0, pos); + rv[pos] = value; + if (pos < rv.length - 1) + System.arraycopy(array, pos, rv, pos + 1, rv.length - pos - 1); + return rv; + } } diff --git a/core/src/test/groovy/com/muwire/core/util/DataUtilTest.groovy b/core/src/test/groovy/com/muwire/core/util/DataUtilTest.groovy index bdc9374d..58e7be2e 100644 --- a/core/src/test/groovy/com/muwire/core/util/DataUtilTest.groovy +++ b/core/src/test/groovy/com/muwire/core/util/DataUtilTest.groovy @@ -64,4 +64,40 @@ class DataUtilTest { } catch (IllegalArgumentException expected) {} } + + @Test + void testSortedArrayAfter() { + int [] array = new int[]{1} + int [] rv = DataUtil.insertIntoSortedArray(array, 2) + assert rv.length == 2 + assert rv[0] == 1 + assert rv[1] == 2 + } + + @Test + void testSortedArrayBefore() { + int [] array = new int[]{1} + int [] rv = DataUtil.insertIntoSortedArray(array, 0) + assert rv.length == 2 + assert rv[0] == 0 + assert rv[1] == 1 + } + + @Test + void testSortedArrayExisting() { + int [] array = new int[]{1} + int [] rv = DataUtil.insertIntoSortedArray(array, 1) + assert System.identityHashCode(array) == System.identityHashCode(rv) + assert array == rv + } + + @Test + void testSortedArrayMiddle() { + int [] array = new int[] {0, 2} + int [] rv = DataUtil.insertIntoSortedArray(array, 1) + assert rv.length == 3 + assert rv[0] == 0 + assert rv[1] == 1 + assert rv[2] == 2 + } }