diff --git a/clients/src/main/java/org/apache/kafka/common/utils/ImplicitLinkedHashCollection.java b/clients/src/main/java/org/apache/kafka/common/utils/ImplicitLinkedHashCollection.java index 524b20b71887d..4c1ad6e38fe3c 100644 --- a/clients/src/main/java/org/apache/kafka/common/utils/ImplicitLinkedHashCollection.java +++ b/clients/src/main/java/org/apache/kafka/common/utils/ImplicitLinkedHashCollection.java @@ -397,7 +397,7 @@ public final boolean add(E newElement) { if (newElement.prev() != INVALID_INDEX || newElement.next() != INVALID_INDEX) { return false; } - if ((size + 1) >= elements.length / 2) { + if (size >= elements.length / 2) { changeCapacity(calculateCapacity(elements.length)); } int slot = addInternal(newElement, elements); @@ -443,9 +443,7 @@ private void changeCapacity(int newCapacity) { Element[] newElements = new Element[newCapacity]; HeadElement newHead = new HeadElement(); int oldSize = size; - for (Iterator iter = iterator(); iter.hasNext(); ) { - Element element = iter.next(); - iter.remove(); + for (Element element : this) { int newSlot = addInternal(element, newElements); addToListTail(newHead, newElements, newSlot); } diff --git a/clients/src/test/java/org/apache/kafka/common/utils/ImplicitLinkedHashCollectionTest.java b/clients/src/test/java/org/apache/kafka/common/utils/ImplicitLinkedHashCollectionTest.java index 4491fc88fc13f..d828e21a92bed 100644 --- a/clients/src/test/java/org/apache/kafka/common/utils/ImplicitLinkedHashCollectionTest.java +++ b/clients/src/test/java/org/apache/kafka/common/utils/ImplicitLinkedHashCollectionTest.java @@ -475,13 +475,17 @@ public void testCollisions() { @Test public void testEnlargement() { - ImplicitLinkedHashCollection coll = new ImplicitLinkedHashCollection<>(5); + int expectedNumElements = 5; + ImplicitLinkedHashCollection coll = new ImplicitLinkedHashCollection<>(expectedNumElements); assertEquals(11, coll.numSlots()); - for (int i = 0; i < 6; i++) { + for (int i = 0; i < expectedNumElements; i++) { assertTrue(coll.add(new TestElement(i))); } + assertEquals(11, coll.numSlots()); + assertEquals(expectedNumElements, coll.size()); + assertTrue(coll.add(new TestElement(expectedNumElements))); assertEquals(23, coll.numSlots()); - assertEquals(6, coll.size()); + assertEquals(expectedNumElements + 1, coll.size()); expectTraversal(coll.iterator(), 0, 1, 2, 3, 4, 5); for (int i = 0; i < 6; i++) { assertTrue(coll.contains(new TestElement(i)), "Failed to find element " + i); diff --git a/jmh-benchmarks/src/main/java/org/apache/kafka/jmh/common/ImplicitLinkedHashCollectionBenchmark.java b/jmh-benchmarks/src/main/java/org/apache/kafka/jmh/common/ImplicitLinkedHashCollectionBenchmark.java index 8e814daa967f0..09595a7f459f6 100644 --- a/jmh-benchmarks/src/main/java/org/apache/kafka/jmh/common/ImplicitLinkedHashCollectionBenchmark.java +++ b/jmh-benchmarks/src/main/java/org/apache/kafka/jmh/common/ImplicitLinkedHashCollectionBenchmark.java @@ -32,8 +32,11 @@ import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; +import java.util.ArrayList; import java.util.Comparator; +import java.util.List; import java.util.concurrent.TimeUnit; @State(Scope.Benchmark) @@ -102,12 +105,15 @@ public int compare(TestElement a, TestElement b) { private int size; private ImplicitLinkedHashCollection coll; + private List elements; @Setup(Level.Trial) public void setup() { coll = new ImplicitLinkedHashCollection<>(); + elements = new ArrayList<>(size); for (int i = 0; i < size; i++) { coll.add(new TestElement(Uuid.randomUuid().toString())); + elements.add(new TestElement("TestElement-" + i)); } } @@ -119,4 +125,26 @@ public ImplicitLinkedHashCollection testCollectionSort() { coll.sort(TestElementComparator.INSTANCE); return coll; } + + @Benchmark + public void testCreateFromExpectedNumElements(Blackhole blackhole) { + ImplicitLinkedHashCollection sets = new ImplicitLinkedHashCollection<>(elements.size()); + for (TestElement element : elements) { + element.setPrev(ImplicitLinkedHashCollection.INVALID_INDEX); + element.setNext(ImplicitLinkedHashCollection.INVALID_INDEX); + sets.mustAdd(element); + } + blackhole.consume(sets); + } + + @Benchmark + public void testCreateFromEmpty(Blackhole blackhole) { + ImplicitLinkedHashCollection sets = new ImplicitLinkedHashCollection<>(); + for (TestElement element : elements) { + element.setPrev(ImplicitLinkedHashCollection.INVALID_INDEX); + element.setNext(ImplicitLinkedHashCollection.INVALID_INDEX); + sets.mustAdd(element); + } + blackhole.consume(sets); + } }