diff --git a/core/src/main/java/org/apache/accumulo/core/util/LocalityGroupUtil.java b/core/src/main/java/org/apache/accumulo/core/util/LocalityGroupUtil.java index ee27c220911..c4ced7d223d 100644 --- a/core/src/main/java/org/apache/accumulo/core/util/LocalityGroupUtil.java +++ b/core/src/main/java/org/apache/accumulo/core/util/LocalityGroupUtil.java @@ -290,32 +290,31 @@ public boolean equals(Mutation m) { public static class Partitioner { private Map colfamToLgidMap; - private PreAllocatedArray> groups; + private List> groups; - public Partitioner(PreAllocatedArray> groups) { + public Partitioner(List> groups) { this.groups = groups; this.colfamToLgidMap = new HashMap<>(); - for (int i = 0; i < groups.length; i++) { + for (int i = 0; i < groups.size(); i++) { for (ByteSequence cf : groups.get(i).keySet()) { colfamToLgidMap.put(cf, i); } } } - public void partition(List mutations, - PreAllocatedArray> partitionedMutations) { + public void partition(List mutations, List> partitionedMutations) { final var mbs = new ArrayByteSequence(new byte[0], 0, 0); - PreAllocatedArray> parts = new PreAllocatedArray<>(groups.length + 1); + List> parts = PreallocatedList.create(groups.size() + 1); for (Mutation mutation : mutations) { if (mutation.getUpdates().size() == 1) { int lgid = getLgid(mbs, mutation.getUpdates().get(0)); partitionedMutations.get(lgid).add(mutation); } else { - for (int i = 0; i < parts.length; i++) { + for (int i = 0; i < parts.size(); i++) { parts.set(i, null); } @@ -333,14 +332,14 @@ public void partition(List mutations, } if (lgcount == 1) { - for (int i = 0; i < parts.length; i++) { + for (int i = 0; i < parts.size(); i++) { if (parts.get(i) != null) { partitionedMutations.get(i).add(mutation); break; } } } else { - for (int i = 0; i < parts.length; i++) { + for (int i = 0; i < parts.size(); i++) { if (parts.get(i) != null) { partitionedMutations.get(i) .add(new PartitionedMutation(mutation.getRow(), parts.get(i))); @@ -355,7 +354,7 @@ private Integer getLgid(ArrayByteSequence mbs, ColumnUpdate cu) { mbs.reset(cu.getColumnFamily(), 0, cu.getColumnFamily().length); Integer lgid = colfamToLgidMap.get(mbs); if (lgid == null) { - lgid = groups.length; + lgid = groups.size(); } return lgid; } diff --git a/core/src/main/java/org/apache/accumulo/core/util/PreAllocatedArray.java b/core/src/main/java/org/apache/accumulo/core/util/PreAllocatedArray.java deleted file mode 100644 index 679b06f9ad6..00000000000 --- a/core/src/main/java/org/apache/accumulo/core/util/PreAllocatedArray.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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 - * - * https://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.accumulo.core.util; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -/** - * A {@link List} implementation that represents a type-safe pre-allocated array. This should be - * used exactly like an array, but helps avoid type-safety issues when mixing arrays with generics. - * The iterator is unmodifiable. - */ -public final class PreAllocatedArray implements Iterable { - - private final List internal; - public final int length; - - /** - * Creates an instance of the given capacity, with all elements initialized to null - */ - @SuppressWarnings("unchecked") - public PreAllocatedArray(final int capacity) { - internal = Arrays.asList((T[]) new Object[capacity]); - length = capacity; - } - - /** - * Set the element at the specified index, and return the old value. - */ - public T set(final int index, final T element) { - return internal.set(index, element); - } - - /** - * Get the item stored at the specified index. - */ - public T get(final int index) { - return internal.get(index); - } - - @Override - public Iterator iterator() { - return internal.iterator(); - } -} diff --git a/core/src/main/java/org/apache/accumulo/core/util/PreallocatedList.java b/core/src/main/java/org/apache/accumulo/core/util/PreallocatedList.java new file mode 100644 index 00000000000..6fa1d3f62af --- /dev/null +++ b/core/src/main/java/org/apache/accumulo/core/util/PreallocatedList.java @@ -0,0 +1,29 @@ +/* + * 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 + * + * https://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.accumulo.core.util; + +import java.util.Arrays; +import java.util.List; + +public class PreallocatedList { + @SuppressWarnings("unchecked") + public static List create(int size) { + return Arrays.asList((T[]) new Object[size]); + } +} diff --git a/core/src/test/java/org/apache/accumulo/core/util/PartitionerTest.java b/core/src/test/java/org/apache/accumulo/core/util/PartitionerTest.java index ab57aedd469..ba42f6d77d5 100644 --- a/core/src/test/java/org/apache/accumulo/core/util/PartitionerTest.java +++ b/core/src/test/java/org/apache/accumulo/core/util/PartitionerTest.java @@ -41,7 +41,7 @@ public class PartitionerTest { @Test public void test1() { - PreAllocatedArray> groups = new PreAllocatedArray<>(2); + List> groups = PreallocatedList.create(2); groups.set(0, new HashMap<>()); groups.get(0).put(new ArrayByteSequence("cf1"), new MutableLong(1)); @@ -72,9 +72,9 @@ public void test1() { m5.put("cf5", "cq3", "v9"); List mutations = Arrays.asList(m1, m2, m3, m4, m5); - PreAllocatedArray> partitioned = new PreAllocatedArray<>(3); + List> partitioned = PreallocatedList.create(3); - for (int i = 0; i < partitioned.length; i++) { + for (int i = 0; i < partitioned.size(); i++) { partitioned.set(i, new ArrayList<>()); } diff --git a/core/src/test/java/org/apache/accumulo/core/util/PreAllocatedArrayTest.java b/core/src/test/java/org/apache/accumulo/core/util/PreAllocatedListTest.java similarity index 71% rename from core/src/test/java/org/apache/accumulo/core/util/PreAllocatedArrayTest.java rename to core/src/test/java/org/apache/accumulo/core/util/PreAllocatedListTest.java index b25a43aea37..09060cc471b 100644 --- a/core/src/test/java/org/apache/accumulo/core/util/PreAllocatedArrayTest.java +++ b/core/src/test/java/org/apache/accumulo/core/util/PreAllocatedListTest.java @@ -25,6 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Iterator; +import java.util.List; import org.junit.jupiter.api.Test; @@ -32,49 +33,48 @@ @SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT", justification = "lambda assertThrows testing exception thrown") -public class PreAllocatedArrayTest { +public class PreAllocatedListTest { /** - * Test method for {@link org.apache.accumulo.core.util.PreAllocatedArray#PreAllocatedArray(int)}. + * Test method for {@link org.apache.accumulo.core.util.PreallocatedList#create(int)}. */ @Test public void testPreAllocatedArray() { - PreAllocatedArray strings = new PreAllocatedArray<>(5); - assertEquals(5, strings.length); + List strings = PreallocatedList.create(5); + assertEquals(5, strings.size()); - strings = new PreAllocatedArray<>(3); - assertEquals(3, strings.length); + strings = PreallocatedList.create(3); + assertEquals(3, strings.size()); - strings = new PreAllocatedArray<>(0); - assertEquals(0, strings.length); + strings = PreallocatedList.create(0); + assertEquals(0, strings.size()); } @Test public void testPreAllocatedArray_Fail() { - assertThrows(NegativeArraySizeException.class, () -> new PreAllocatedArray(-5)); + assertThrows(NegativeArraySizeException.class, () -> PreallocatedList.create(-5)); } /** - * Test method for - * {@link org.apache.accumulo.core.util.PreAllocatedArray#set(int, java.lang.Object)}.
- * Test method for {@link org.apache.accumulo.core.util.PreAllocatedArray#get(int)}.
- * Test method for {@link org.apache.accumulo.core.util.PreAllocatedArray#iterator()}. + * Test method for {@link List#set(int, java.lang.Object)}.
+ * Test method for {@link List#get(int)}.
+ * Test method for {@link List#iterator()}. */ @Test public void testSet() { int capacity = 5; - PreAllocatedArray strings = new PreAllocatedArray<>(capacity); - assertEquals(capacity, strings.length); + List strings = PreallocatedList.create(capacity); + assertEquals(capacity, strings.size()); // everything else should be null strings.set(1, "a"); strings.set(4, "b"); - assertEquals(capacity, strings.length); + assertEquals(capacity, strings.size()); // overwrite String b = strings.set(4, "c"); assertEquals("b", b); - assertEquals(capacity, strings.length); + assertEquals(capacity, strings.size()); Iterator iter = strings.iterator(); assertNull(iter.next()); // index 0 @@ -87,21 +87,21 @@ public void testSet() { @Test public void testSetIndexHigh() { - PreAllocatedArray strings = new PreAllocatedArray<>(3); + List strings = PreallocatedList.create(3); strings.set(2, "in bounds"); assertThrows(IndexOutOfBoundsException.class, () -> strings.set(3, "out of bounds")); } @Test public void testSetIndexNegative() { - PreAllocatedArray strings = new PreAllocatedArray<>(3); + List strings = PreallocatedList.create(3); strings.set(0, "in bounds"); assertThrows(IndexOutOfBoundsException.class, () -> strings.set(-3, "out of bounds")); } @Test public void testGetIndexHigh() { - PreAllocatedArray strings = new PreAllocatedArray<>(3); + List strings = PreallocatedList.create(3); assertNull(strings.get(2)); // spotbugs error suppressed at class level for lambda assertThrows(IndexOutOfBoundsException.class, () -> strings.get(3)); @@ -109,7 +109,7 @@ public void testGetIndexHigh() { @Test public void testGetIndexNegative() { - PreAllocatedArray strings = new PreAllocatedArray<>(3); + List strings = PreallocatedList.create(3); assertNull(strings.get(0)); // spotbugs error suppressed at class level for lambda assertThrows(IndexOutOfBoundsException.class, () -> strings.get(-3)); @@ -117,7 +117,7 @@ public void testGetIndexNegative() { @Test public void testIteratorRemove() { - PreAllocatedArray strings = new PreAllocatedArray<>(3); + List strings = PreallocatedList.create(3); strings.set(1, "data"); var iter = strings.iterator(); for (int i = 0; i < 3; i++) { diff --git a/server/tserver/src/main/java/org/apache/accumulo/tserver/InMemoryMap.java b/server/tserver/src/main/java/org/apache/accumulo/tserver/InMemoryMap.java index d943e3f6f85..d272c4c8141 100644 --- a/server/tserver/src/main/java/org/apache/accumulo/tserver/InMemoryMap.java +++ b/server/tserver/src/main/java/org/apache/accumulo/tserver/InMemoryMap.java @@ -69,7 +69,7 @@ import org.apache.accumulo.core.util.LocalityGroupUtil; import org.apache.accumulo.core.util.LocalityGroupUtil.Partitioner; import org.apache.accumulo.core.util.Pair; -import org.apache.accumulo.core.util.PreAllocatedArray; +import org.apache.accumulo.core.util.PreallocatedList; import org.apache.accumulo.server.ServerContext; import org.apache.accumulo.server.conf.TableConfiguration; import org.apache.commons.lang3.mutable.MutableLong; @@ -280,17 +280,17 @@ public void mutate(List mutations, int kvCount) { private static class LocalityGroupMap implements SimpleMap { - private final PreAllocatedArray> groupFams; + private final List> groupFams; // the last map in the array is the default locality group private final SimpleMap[] maps; private final Partitioner partitioner; - private final PreAllocatedArray> partitioned; + private final List> partitioned; LocalityGroupMap(Map> groups, boolean useNativeMap) { - this.groupFams = new PreAllocatedArray<>(groups.size()); + this.groupFams = PreallocatedList.create(groups.size()); this.maps = new SimpleMap[groups.size() + 1]; - this.partitioned = new PreAllocatedArray<>(groups.size() + 1); + this.partitioned = PreallocatedList.create(groups.size() + 1); for (int i = 0; i < maps.length; i++) { maps[i] = newMap(useNativeMap); @@ -307,7 +307,7 @@ private static class LocalityGroupMap implements SimpleMap { partitioner = new LocalityGroupUtil.Partitioner(this.groupFams); - for (int i = 0; i < partitioned.length; i++) { + for (int i = 0; i < partitioned.size(); i++) { partitioned.set(i, new ArrayList<>()); } } @@ -329,7 +329,7 @@ public InterruptibleIterator skvIterator(SamplerConfigurationImpl samplerConfig) LocalityGroup[] groups = new LocalityGroup[maps.length]; for (int i = 0; i < groups.length; i++) { - if (i < groupFams.length) { + if (i < groupFams.size()) { groups[i] = new LocalityGroup(maps[i].skvIterator(null), groupFams.get(i), false); } else { groups[i] = new LocalityGroup(maps[i].skvIterator(null), null, true); @@ -364,7 +364,7 @@ public synchronized void mutate(List mutations, int kvCount) { try { partitioner.partition(mutations, partitioned); - for (int i = 0; i < partitioned.length; i++) { + for (int i = 0; i < partitioned.size(); i++) { if (!partitioned.get(i).isEmpty()) { maps[i].mutate(partitioned.get(i), kvCount); for (Mutation m : partitioned.get(i)) { diff --git a/server/tserver/src/main/java/org/apache/accumulo/tserver/NativeMap.java b/server/tserver/src/main/java/org/apache/accumulo/tserver/NativeMap.java index 0b8a6816c29..38721ccb864 100644 --- a/server/tserver/src/main/java/org/apache/accumulo/tserver/NativeMap.java +++ b/server/tserver/src/main/java/org/apache/accumulo/tserver/NativeMap.java @@ -45,7 +45,7 @@ import org.apache.accumulo.core.iterators.SortedKeyValueIterator; import org.apache.accumulo.core.iteratorsImpl.system.InterruptibleIterator; import org.apache.accumulo.core.iteratorsImpl.system.IterationInterruptedException; -import org.apache.accumulo.core.util.PreAllocatedArray; +import org.apache.accumulo.core.util.PreallocatedList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -181,7 +181,7 @@ private class ConcurrentIterator implements Iterator> { private NMIterator source; - private PreAllocatedArray> nextEntries; + private List> nextEntries; private int index; private int end; @@ -191,7 +191,7 @@ private class ConcurrentIterator implements Iterator> { ConcurrentIterator(Key key) { // start off with a small read ahead - nextEntries = new PreAllocatedArray<>(1); + nextEntries = PreallocatedList.create(1); rlock.lock(); try { @@ -214,12 +214,12 @@ private void fill() { int amountRead = 0; // as we keep filling, increase the read ahead buffer - if (nextEntries.length < MAX_READ_AHEAD_ENTRIES) { + if (nextEntries.size() < MAX_READ_AHEAD_ENTRIES) { nextEntries = - new PreAllocatedArray<>(Math.min(nextEntries.length * 2, MAX_READ_AHEAD_ENTRIES)); + PreallocatedList.create(Math.min(nextEntries.size() * 2, MAX_READ_AHEAD_ENTRIES)); } - while (source.hasNext() && end < nextEntries.length) { + while (source.hasNext() && end < nextEntries.size()) { Entry ne = source.next(); nextEntries.set(end++, ne); amountRead += ne.getKey().getSize() + ne.getValue().getSize();