package org.warp.jcwdb; import it.unimi.dsi.fastutil.longs.Long2LongLinkedOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2LongMap; import java.io.IOException; import java.nio.file.Path; import java.util.function.Consumer; public class MixedIndexDatabase implements IndexManager { private final Long2LongMap mostAccessedIndices; private final FileIndexManager fileIndices; private final CacheIndexManager cacheIndices; public MixedIndexDatabase(TypesManager typesManager, Path dataFile, Path metadataFile) throws IOException { this.mostAccessedIndices = new Long2LongLinkedOpenHashMap(); this.fileIndices = new FileIndexManager(dataFile, metadataFile); this.cacheIndices = new CacheIndexManager(); } @Override public T get(long index, DBReader reader) throws IOException { incrementUsage(index); if (cacheIndices.has(index)) { return cacheIndices.get(index, reader); } else { return fileIndices.get(index, reader); } } @Override public int getType(long index) throws IOException { if (cacheIndices.has(index)) { return cacheIndices.getType(index); } else { return fileIndices.getType(index); } } @Override public long getHash(long index) throws IOException { if (cacheIndices.has(index)) { return cacheIndices.getHash(index); } else { return fileIndices.getHash(index); } } @Override public long add(DBDataOutput writer) throws IOException { return fileIndices.add(writer); } @Override public IndexDetails set(long index, DBDataOutput writer) throws IOException { if (cacheIndices.has(index)) { return cacheIndices.set(index, writer); } else { return fileIndices.set(index, writer); } } @Override public void delete(long index) throws IOException { cacheIndices.delete(index); fileIndices.delete(index); } @Override public boolean has(long index) { return cacheIndices.has(index) || fileIndices.has(index); } private void incrementUsage(long index) { mostAccessedIndices.put(index, mostAccessedIndices.getOrDefault(index, 0) + 1); } @Override public void close() throws IOException { // TODO: move all cached indices to filesIndices before closing. this.cacheIndices.close(); this.fileIndices.close(); } @Override public long clean() { return fileIndices.clean() + cacheIndices.clean(); } }