package net.fortytwo.sesametools.caching;
import org.openrdf.model.IRI;
import org.openrdf.model.Resource;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.sail.Sail;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.sail.StackableSail;
import org.openrdf.sail.helpers.AbstractSail;
import org.openrdf.sail.memory.MemoryStore;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
/**
* A <code>Sail</code> which caches statements retrieved from a base <code>Sail</code>
* in an internal <code>MemoryStore</code>, speeding up subsequent queries for the same data.
*
* @author Joshua Shinavier (http://fortytwo.net)
*/
// Note: assumes that the value factories of the base Sail and the MemoryStore
// cache are compatible.
public class CachingSail extends AbstractSail implements StackableSail {
private static final long DEFAULT_CAPACITY = 1000000L;
private boolean cacheSubject, cachePredicate, cacheObject;
private Sail baseSail;
private Sail cache;
private Set<Resource> cachedSubjects;
private Set<IRI> cachedPredicates;
private Set<Value> cachedObjects;
private long capacity;
public CachingSail(final Sail baseSail,
final boolean cacheSubject,
final boolean cachePredicate,
final boolean cacheObject,
final long capacity) {
this.baseSail = baseSail;
this.cacheSubject = cacheSubject;
this.cachePredicate = cachePredicate;
this.cacheObject = cacheObject;
this.capacity = (capacity <= 0) ? DEFAULT_CAPACITY : capacity;
}
public SailConnection getConnectionInternal() throws SailException {
return new CachingSailConnection(this, baseSail, cache,
cacheSubject, cachePredicate, cacheObject,
cachedSubjects, cachedPredicates, cachedObjects);
}
@Override
public File getDataDir() {
return baseSail.getDataDir();
}
@Override
public ValueFactory getValueFactory() {
return baseSail.getValueFactory();
}
public void initializeInternal() throws SailException {
baseSail.initialize();
cache = new MemoryStore();
cache.initialize();
if (cacheSubject) {
cachedSubjects = new HashSet<>();
}
if (cachePredicate) {
cachedPredicates = new HashSet<>();
}
if (cacheObject) {
cachedObjects = new HashSet<>();
}
}
@Override
public boolean isWritable() throws SailException {
return baseSail.isWritable();
}
@Override
public void setDataDir(final File dir) {
baseSail.setDataDir(dir);
}
public void shutDownInternal() throws SailException {
baseSail.shutDown();
cache.shutDown();
}
public Sail getBaseSail() {
return baseSail;
}
public void setBaseSail(final Sail sail) {
baseSail = sail;
}
public long getCapacity() {
return this.capacity;
}
}