Skip to content

Commit

Permalink
Improve performance of IntHashSet via avoiding the fill operation by …
Browse files Browse the repository at this point in the history
…using 0 as MISSING_VALUE.
  • Loading branch information
mjpt777 committed Jun 21, 2024
1 parent b515f38 commit a49ea67
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 40 deletions.
11 changes: 4 additions & 7 deletions agrona/src/main/java/org/agrona/collections/IntHashSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public class IntHashSet extends AbstractSet<Integer>
*/
@DoNotSub public static final int DEFAULT_INITIAL_CAPACITY = 8;

static final int MISSING_VALUE = -1;
static final int MISSING_VALUE = 0;

private final boolean shouldAvoidAllocation;
private boolean containsMissingValue;
Expand All @@ -67,7 +67,7 @@ public class IntHashSet extends AbstractSet<Integer>

/**
* Construct a hash set with {@link #DEFAULT_INITIAL_CAPACITY}, {@link Hashing#DEFAULT_LOAD_FACTOR}, iterator
* caching support and {@code -1} as a missing value.
* caching support and {@code 0} as a missing value.
*/
public IntHashSet()
{
Expand All @@ -76,7 +76,7 @@ public IntHashSet()

/**
* Construct a hash set with a proposed capacity, {@link Hashing#DEFAULT_LOAD_FACTOR}, iterator
* caching support and {@code -1} as a missing value.
* caching support and {@code 0} as a missing value.
*
* @param proposedCapacity for the initial capacity of the set.
*/
Expand All @@ -87,7 +87,7 @@ public IntHashSet(
}

/**
* Construct a hash set with a proposed initial capacity, load factor, iterator caching support and {@code -1} as a
* Construct a hash set with a proposed initial capacity, load factor, iterator caching support and {@code 0} as a
* missing value.
*
* @param proposedCapacity for the initial capacity of the set.
Expand Down Expand Up @@ -121,7 +121,6 @@ public IntHashSet(
@DoNotSub final int capacity = findNextPositivePowerOfTwo(Math.max(DEFAULT_INITIAL_CAPACITY, proposedCapacity));
resizeThreshold = (int)(capacity * loadFactor); // @DoNotSub
values = new int[capacity];
Arrays.fill(values, MISSING_VALUE);
}

/**
Expand Down Expand Up @@ -222,8 +221,6 @@ private void rehash(@DoNotSub final int newCapacity)
/* @DoNotSub */ resizeThreshold = (int)(newCapacity * loadFactor);

final int[] tempValues = new int[capacity];
Arrays.fill(tempValues, MISSING_VALUE);

final int[] values = this.values;
for (final int value : values)
{
Expand Down
46 changes: 13 additions & 33 deletions agrona/src/test/java/org/agrona/collections/IntHashSetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

Expand Down Expand Up @@ -791,25 +790,6 @@ void consecutiveValuesShouldBeCorrectlyStored()
assertThat(testSet, hasSize(10_000));
}

@Test
void hashCodeAccountsForMissingValue()
{
addTwoElements(testSet);
testSet.add(MISSING_VALUE);

final IntHashSet other = new IntHashSet(100);
addTwoElements(other);

assertNotEquals(testSet.hashCode(), other.hashCode());

other.add(MISSING_VALUE);
assertEquals(testSet.hashCode(), other.hashCode());

testSet.remove(MISSING_VALUE);

assertNotEquals(testSet.hashCode(), other.hashCode());
}

@Test
void iteratorAccountsForMissingValue()
{
Expand Down Expand Up @@ -858,8 +838,8 @@ void shouldGenerateStringRepresentation()
set.add(testEntry);
}

final String mapAsAString = "{0, 12, 3, 7, 11, 1, 19, -1}";
assertThat(set.toString(), equalTo(mapAsAString));
final String mapAsAString = "{-1, 12, 3, 7, 11, 1, 19, 0}";
assertEquals(mapAsAString, set.toString());
}

@Test
Expand Down Expand Up @@ -1030,7 +1010,7 @@ void retainAllCollectionRemovesNonMissingValuesNotFoundInAGivenCollection()
@Test
void retainAllCollectionRemovesMissingValueWhichWasAddedToTheSet()
{
final List<Integer> coll = Arrays.asList(42, 42, 42, 0, 500);
final List<Integer> coll = Arrays.asList(42, 42, 42, 500);
testSet.add(MISSING_VALUE);
testSet.add(42);

Expand Down Expand Up @@ -1081,7 +1061,7 @@ void retainAllRemovesNonMissingValuesNotFoundInAGivenCollection()
void retainAllRemovesMissingValueWhichWasAddedToTheSet()
{
final IntHashSet coll = new IntHashSet(5);
coll.addAll(Arrays.asList(42, 42, 42, 0, 500));
coll.addAll(Arrays.asList(42, 42, 42, -1, 500));
testSet.add(MISSING_VALUE);
testSet.add(42);
testSet.add(500);
Expand Down Expand Up @@ -1151,17 +1131,17 @@ void removeIfIntIsANoOpIfNoValuesMatchFilter()
@Test
void removeIfIntDeletesAllMatchingValues()
{
final IntPredicate filter = (v) -> v < 0;
final IntPredicate filter = (v) -> v < 1;
testSet.add(1);
testSet.add(2);
testSet.add(-2);
testSet.add(0);
testSet.add(MISSING_VALUE);

assertTrue(testSet.removeIfInt(filter));

assertEquals(2, testSet.size());
assertTrue(testSet.contains(1));
assertTrue(testSet.contains(0));
assertTrue(testSet.contains(2));
assertFalse(testSet.contains(MISSING_VALUE));
}

Expand All @@ -1187,15 +1167,15 @@ void removeIfDeletesAllMatchingValues()
final Predicate<Integer> filter = (v) -> v < 0;
testSet.add(1);
testSet.add(-2);
testSet.add(0);
testSet.add(MISSING_VALUE);
testSet.add(-1);

assertTrue(testSet.removeIf(filter));

assertEquals(2, testSet.size());
assertTrue(testSet.contains(1));
assertTrue(testSet.contains(0));
assertFalse(testSet.contains(MISSING_VALUE));
assertTrue(testSet.contains(MISSING_VALUE));
assertFalse(testSet.contains(-1));
}

@Test
Expand All @@ -1222,18 +1202,18 @@ void addAllShouldAddOnlyNonMissingValuesIfTheSourceListDoesNotContainExplicitMis
}

@Test
void addAllShouldAddMissingVaueFromAnotherSet()
void addAllShouldAddMissingValueFromAnotherSet()
{
final IntHashSet other = new IntHashSet(5);
other.add(1);
other.add(2);
other.add(3);
testSet.add(0);
testSet.add(-1);

assertTrue(testSet.addAll(other));

assertEquals(4, testSet.size());
for (int i = 0; i <= 3; i++)
for (int i = 1; i <= 3; i++)
{
assertTrue(testSet.contains(i));
}
Expand Down

0 comments on commit a49ea67

Please sign in to comment.