add reindex method to PersistentMap
This commit is contained in:
@@ -16,9 +16,9 @@ import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.lucares.utils.file.FileUtils;
|
||||
|
||||
public class PersistentMapTest {
|
||||
@@ -332,61 +332,92 @@ public class PersistentMapTest {
|
||||
@Test
|
||||
public void testLotsOfValues() throws Exception {
|
||||
final Path file = dataDirectory.resolve("map.db");
|
||||
final var insertedValues = new HashMap<Long, Long>();
|
||||
|
||||
final SecureRandom rnd = new SecureRandom();
|
||||
rnd.setSeed(1);
|
||||
|
||||
final Map<Long, Long> insertedValues;
|
||||
try (final PersistentMap<Long, Long> map = new PersistentMap<>(file, dataDirectory, PersistentMap.LONG_CODER,
|
||||
PersistentMap.LONG_CODER)) {
|
||||
|
||||
for (int i = 0; i < 1_000; i++) {
|
||||
|
||||
final Long key = (long) (rnd.nextGaussian() * Integer.MAX_VALUE);
|
||||
final Long value = (long) (rnd.nextGaussian() * Integer.MAX_VALUE);
|
||||
|
||||
if (insertedValues.containsKey(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Assertions.assertNull(map.putValue(key, value));
|
||||
|
||||
insertedValues.put(key, value);
|
||||
|
||||
final boolean failEarly = false;
|
||||
if (failEarly) {
|
||||
for (final var entry : insertedValues.entrySet()) {
|
||||
final Long actualValue = map.getValue(entry.getKey());
|
||||
|
||||
if (!Objects.equals(actualValue, entry.getValue())) {
|
||||
map.print();
|
||||
}
|
||||
|
||||
Assertions.assertEquals(entry.getValue(), actualValue,
|
||||
"value for key " + entry.getKey() + " in the " + i + "th iteration");
|
||||
}
|
||||
}
|
||||
}
|
||||
insertedValues = fillMap(1000, true, map);
|
||||
}
|
||||
|
||||
try (final PersistentMap<Long, Long> map = new PersistentMap<>(file, dataDirectory, PersistentMap.LONG_CODER,
|
||||
PersistentMap.LONG_CODER)) {
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
final AtomicInteger maxDepth = new AtomicInteger();
|
||||
map.visitNodeEntriesPreOrder((node, parentNode, nodeEntry, depth) -> {
|
||||
counter.addAndGet(nodeEntry.isInnerNode() ? 1 : 0);
|
||||
maxDepth.set(Math.max(maxDepth.get(), depth));
|
||||
});
|
||||
|
||||
final long start = System.nanoTime();
|
||||
for (final var entry : insertedValues.entrySet()) {
|
||||
final Long actualValue = map.getValue(entry.getKey());
|
||||
Assertions.assertEquals(entry.getValue(), actualValue,
|
||||
"value for key " + entry.getKey() + " after all iterations");
|
||||
}
|
||||
System.out.println("nodes=" + counter.get() + ", depth=" + maxDepth.get() + ": "
|
||||
+ (System.nanoTime() - start) / 1_000_000.0 + "ms");
|
||||
assertValuesInMap(insertedValues, map);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReindexing() throws IOException {
|
||||
final Path file = dataDirectory.resolve("map.db");
|
||||
final Map<Long, Long> insertedValuesBeforeReindex;
|
||||
final Map<Long, Long> insertedValuesAfterReindex;
|
||||
try (final PersistentMap<Long, Long> map = new PersistentMap<>(file, dataDirectory, PersistentMap.LONG_CODER,
|
||||
PersistentMap.LONG_CODER)) {
|
||||
insertedValuesBeforeReindex = fillMap(1_000, true, map);
|
||||
|
||||
map.reindex();
|
||||
|
||||
assertValuesInMap(insertedValuesBeforeReindex, map);
|
||||
|
||||
insertedValuesAfterReindex = fillMap(1_000, true, map);
|
||||
|
||||
assertValuesInMap(insertedValuesBeforeReindex, map);
|
||||
assertValuesInMap(insertedValuesAfterReindex, map);
|
||||
}
|
||||
try (final PersistentMap<Long, Long> map = new PersistentMap<>(file, dataDirectory, PersistentMap.LONG_CODER,
|
||||
PersistentMap.LONG_CODER)) {
|
||||
assertValuesInMap(insertedValuesBeforeReindex, map);
|
||||
assertValuesInMap(insertedValuesAfterReindex, map);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertValuesInMap(final Map<Long, Long> insertedValues, final PersistentMap<Long, Long> map) {
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
final AtomicInteger maxDepth = new AtomicInteger();
|
||||
map.visitNodeEntriesPreOrder((node, parentNode, nodeEntry, depth) -> {
|
||||
counter.addAndGet(nodeEntry.isInnerNode() ? 1 : 0);
|
||||
maxDepth.set(Math.max(maxDepth.get(), depth));
|
||||
});
|
||||
|
||||
final long start = System.nanoTime();
|
||||
for (final var entry : insertedValues.entrySet()) {
|
||||
final Long actualValue = map.getValue(entry.getKey());
|
||||
Assertions.assertEquals(entry.getValue(), actualValue,
|
||||
"value for key " + entry.getKey() + " after all iterations");
|
||||
}
|
||||
System.out.println("nodes=" + counter.get() + ", depth=" + maxDepth.get() + ": "
|
||||
+ (System.nanoTime() - start) / 1_000_000.0 + "ms");
|
||||
}
|
||||
|
||||
private Map<Long, Long> fillMap(final int numberOfValues, final boolean failEarly,
|
||||
final PersistentMap<Long, Long> map) {
|
||||
final Map<Long, Long> insertedValues = new HashMap<>();
|
||||
final SecureRandom rnd = new SecureRandom();
|
||||
rnd.setSeed(1);
|
||||
for (int i = 0; i < numberOfValues; i++) {
|
||||
|
||||
final Long key = (long) (rnd.nextGaussian() * Integer.MAX_VALUE);
|
||||
final Long value = (long) (rnd.nextGaussian() * Integer.MAX_VALUE);
|
||||
|
||||
if (insertedValues.containsKey(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Assertions.assertNull(map.putValue(key, value));
|
||||
|
||||
insertedValues.put(key, value);
|
||||
|
||||
if (failEarly) {
|
||||
for (final var entry : insertedValues.entrySet()) {
|
||||
final Long actualValue = map.getValue(entry.getKey());
|
||||
|
||||
if (!Objects.equals(actualValue, entry.getValue())) {
|
||||
map.print();
|
||||
}
|
||||
|
||||
Assertions.assertEquals(entry.getValue(), actualValue,
|
||||
"value for key " + entry.getKey() + " in the " + i + "th iteration");
|
||||
}
|
||||
}
|
||||
}
|
||||
return insertedValues;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user