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:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user