add cache for docId to Doc mapping

A Doc does not change once it is created, so it is easy to cache.
Speedup was from 1ms per Doc to 3ms for 444 Docs (0.00675ms/Doc).
This commit is contained in:
2018-11-22 19:51:07 +01:00
parent 6c546bd5b3
commit f78f69328b
6 changed files with 158 additions and 17 deletions

View File

@@ -2,6 +2,7 @@ package org.lucares.pdb.datastore.internal;
import java.io.IOException;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -29,6 +30,7 @@ import org.lucares.pdb.map.PersistentMap;
import org.lucares.pdb.map.PersistentMap.EncoderDecoder;
import org.lucares.utils.Preconditions;
import org.lucares.utils.byteencoder.VariableByteEncoder;
import org.lucares.utils.cache.HotEntryCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -148,6 +150,10 @@ public class DataStore implements AutoCloseable {
private final PersistentMap<Tag, Long> tagToDocsId;
// A Doc will never be changed once it is created. Therefore we can cache them
// easily.
private final HotEntryCache<Long, Doc> docIdToDocCache = new HotEntryCache<>(Duration.ofMinutes(10));
private final DiskStorage diskStorage;
private final Path diskStorageFilePath;
private final Path storageBasePath;
@@ -287,32 +293,48 @@ public class DataStore implements AutoCloseable {
synchronized (docIdToDoc) {
final long start = System.nanoTime();
for (int i = 0; i < docIdsList.size(); i++) {
final long docId = docIdsList.get(i);
final Doc doc = docIdToDoc.getValue(docId);
final Doc doc = getDocByDocId(docId);
Objects.requireNonNull(doc, "Doc with id " + docId + " did not exist.");
result.add(doc);
}
System.out.println(
"mapDocIdsToDocs: " + (System.nanoTime() - start) / 1_000_000.0 + "ms ; tags:" + result.size());
}
return result;
}
public List<Doc> getByTags(final Tags tags) {
final long start = System.nanoTime();
try {
final Long docId = tagsToDocId.getValue(tags);
final List<Doc> result = new ArrayList<>(0);
if (docId != null) {
final Doc doc = docIdToDoc.getValue(docId);
final Doc doc = getDocByDocId(docId);
result.add(doc);
}
System.out
.println("getByTags: " + (System.nanoTime() - start) / 1_000_000.0 + "ms ; tags:" + result.size());
return result;
} catch (final IOException e) {
throw new RuntimeIOException(e);
}
}
private Doc getDocByDocId(final Long docId) {
return docIdToDocCache.putIfAbsent(docId, k -> {
try {
return docIdToDoc.getValue(k);
} catch (final IOException e) {
throw new RuntimeIOException(e);
}
});
}
@Override
public void close() throws IOException {
try {