Last active
March 25, 2024 22:26
-
-
Save DanielThomas/f74d8937a5440685ceef07a70df6433c to your computer and use it in GitHub Desktop.
Tests for HashIndex.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2024 Netflix Inc. | |
* | |
* Licensed 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 com.netflix.index; | |
import org.junit.jupiter.api.Disabled; | |
import org.junit.jupiter.api.Test; | |
import org.junit.jupiter.params.ParameterizedTest; | |
import org.junit.jupiter.params.provider.ValueSource; | |
import java.io.*; | |
import java.util.*; | |
import java.util.stream.LongStream; | |
import java.util.zip.DeflaterInputStream; | |
import java.util.zip.GZIPInputStream; | |
import static org.junit.jupiter.api.Assertions.*; | |
class HashIndexTest { | |
@Test | |
public void getValueMissing() { | |
HashIndex<String> index = new HashIndex<>(10, Long.BYTES); | |
HashIndex.OptionalNumber actual = index.getValue(0, value -> { | |
throw new IllegalStateException(); // predicate should not be called | |
}); | |
assertFalse(actual.isPresent()); | |
} | |
@Test | |
public void getValueMaxKey() { | |
HashIndex<String> index = new HashIndex<>(10, Long.BYTES); | |
HashIndex.OptionalNumber actual = index.getValue(Long.MAX_VALUE, value -> { | |
throw new IllegalStateException(); // predicate should not be called | |
}); | |
assertFalse(actual.isPresent()); | |
} | |
@Test | |
public void getValuePresent() { | |
HashIndex<String> index = new HashIndex<>(10, Long.BYTES); | |
index.put(0, 0); | |
HashIndex.OptionalNumber actual = index.getValue(0, value -> true); | |
assertTrue(actual.isPresent()); | |
assertEquals(0, actual.getAsByte()); | |
} | |
@Test | |
public void getValueNotEqual() { | |
HashIndex<String> index = new HashIndex<>(10, Long.BYTES); | |
index.put(0, 0); | |
HashIndex.OptionalNumber actual = index.getValue(0, value -> false); | |
assertFalse(actual.isPresent()); | |
} | |
@Test | |
public void getValueDuplicateKeys() { | |
HashIndex<String> index = new HashIndex<>(10, Long.BYTES); | |
index.put(1, 1); | |
index.put(1, 2); | |
index.put(1, 3); | |
index.put(1, 4); | |
index.put(1, 5); | |
List<Long> values = new ArrayList<>(); | |
HashIndex.OptionalNumber actual = index.getValue(1, value -> { | |
values.add(value); | |
return value == 5; | |
}); | |
assertTrue(actual.isPresent()); | |
assertEquals(5, actual.get()); | |
assertEquals(5, values.size()); | |
} | |
@Test | |
public void getValueNarrowingDisallowed() { | |
HashIndex<String> index = new HashIndex<>(1, Long.BYTES); | |
index.put(0, Long.MAX_VALUE - 1); | |
Arrays.asList(Byte.BYTES, Short.BYTES, Integer.BYTES).forEach(numBytes -> { | |
Exception exception = assertThrows(IllegalArgumentException.class, () -> { | |
HashIndex.OptionalNumber result = index.getValue(0, value -> true); | |
switch (numBytes) { | |
case Byte.BYTES: | |
result.getAsByte(); | |
break; | |
case Short.BYTES: | |
result.getAsShort(); | |
break; | |
case Integer.BYTES: | |
result.getAsInt(); | |
break; | |
default: | |
result.get(); | |
} | |
}); | |
assertEquals("value is larger than " + numBytes * Byte.SIZE + " bits", exception.getMessage()); | |
}); | |
} | |
@Test | |
public void getMissing() { | |
HashIndex<String> index = new HashIndex<>(10, Long.BYTES); | |
Optional<String> actual = index.get(0, value -> { | |
throw new IllegalStateException(); | |
}); | |
assertFalse(actual.isPresent()); | |
} | |
@Test | |
public void getPresent() { | |
HashIndex<String> index = new HashIndex<>(10, Long.BYTES); | |
index.put(0, 0); | |
Optional<String> actual = index.get(0, value -> Optional.of("match")); | |
assertTrue(actual.isPresent()); | |
assertEquals("match", actual.get()); | |
} | |
@Test | |
public void getNotEqual() { | |
HashIndex<String> index = new HashIndex<>(10, Long.BYTES); | |
index.put(0, 0); | |
Optional<String> actual = index.get(0, value -> Optional.empty()); | |
assertFalse(actual.isPresent()); | |
} | |
@ParameterizedTest | |
@ValueSource(longs = {(long) Byte.MAX_VALUE, (long) Short.MAX_VALUE, (long) Integer.MAX_VALUE, Long.MAX_VALUE}) | |
public void putMaxValueDisallowed(long expected) { | |
int entryBytes = (Long.SIZE - Long.numberOfLeadingZeros(expected) + 1) / Byte.SIZE; | |
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> { | |
HashIndex<String> index = new HashIndex<>(1, entryBytes); | |
index.put(0, expected); | |
}); | |
assertEquals(expected + " is reserved for " + entryBytes + " byte entries", exception.getMessage()); | |
} | |
@ParameterizedTest | |
@ValueSource(longs = {(long) Byte.MAX_VALUE, (long) Short.MAX_VALUE, (long) Integer.MAX_VALUE, Long.MAX_VALUE}) | |
public void putMaxValueMinusOne(long expected) { | |
int entryBytes = (Long.SIZE - Long.numberOfLeadingZeros(expected) + 1) / Byte.SIZE; | |
expected = expected - 1; | |
HashIndex<String> index = new HashIndex<>(1, entryBytes); | |
index.put(0, expected); | |
long actual = index.getValue(0, value -> true).get(); | |
assertEquals(expected, actual); | |
} | |
@ParameterizedTest | |
@ValueSource(longs = {(long) Byte.MIN_VALUE, (long) Short.MIN_VALUE, (long) Integer.MIN_VALUE, Long.MIN_VALUE}) | |
public void putMinValue(long expected) { | |
int numEntries = (Long.SIZE - Long.numberOfLeadingZeros(~expected) + 1) / Byte.SIZE; | |
HashIndex<String> index = new HashIndex<>(1, numEntries); | |
index.put(0, expected); | |
long actual = index.getValue(0, value -> true).get(); | |
assertEquals(expected, actual); | |
} | |
@ParameterizedTest | |
@ValueSource(ints = {Byte.BYTES, Short.BYTES, Integer.BYTES}) | |
public void putNarrowingDisallowed(int numBytes) { | |
Exception exception = assertThrows(IllegalArgumentException.class, () -> { | |
HashIndex<String> index = new HashIndex<>(1, numBytes); | |
index.put(0, 1L << numBytes * Byte.SIZE); | |
}); | |
assertEquals("value is larger than " + numBytes * Byte.SIZE + " bits", exception.getMessage()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment