@jahed/sparql-engine
Version:
SPARQL query engine for servers and web browsers.
51 lines • 2.35 kB
JavaScript
import ExecutionContext from "../engine/context/execution-context.js";
import ContextSymbols from "../engine/context/symbols.js";
import { Pipeline } from "../engine/pipeline/pipeline.js";
import BGPStageBuilder from "../engine/stages/bgp-stage-builder.js";
import { Bindings } from "../rdf/bindings.js";
import Graph from "../rdf/graph.js";
/**
* Evaluate a Basic Graph pattern on a RDF graph using a cache
* @param bgp - Basic Graph pattern to evaluate
* @param graph - RDF graph
* @param cache - Cache used
* @return A pipeline stage that produces the evaluation results
*/
export async function cacheEvalBGP(patterns, graph, cache, builder, context) {
const bgp = {
patterns,
graphIRI: graph.iri,
};
const [subsetBGP, missingBGP] = cache.findSubset(bgp);
// case 1: no subset of the BGP are in cache => classic evaluation (most frequent)
if (subsetBGP.length === 0) {
// we cannot cache the BGP if the query has a LIMIT and/or OFFSET modiifier
// otherwise we will cache incomplete results. So, we just evaluate the BGP
if (context.hasProperty(ContextSymbols.HAS_LIMIT_OFFSET) &&
context.getProperty(ContextSymbols.HAS_LIMIT_OFFSET)) {
return graph.evalBGP(patterns, context);
}
// generate an unique writer ID
const writerID = crypto.randomUUID();
// evaluate the BGP while saving all solutions into the cache
const iterator = Pipeline.getInstance().tap(graph.evalBGP(patterns, context), (b) => {
cache.update(bgp, b, writerID);
});
// commit the cache entry when the BGP evaluation is done
return Pipeline.getInstance().finalize(iterator, () => {
cache.commit(bgp, writerID);
});
}
// case 2: no missing patterns => the complete BGP is in the cache
if (missingBGP.length === 0) {
return cache.getAsPipeline(bgp, () => graph.evalBGP(patterns, context));
}
const cachedBGP = {
patterns: subsetBGP,
graphIRI: graph.iri,
};
// case 3: evaluate the subset BGP using the cache, then join with the missing patterns
const iterator = cache.getAsPipeline(cachedBGP, () => graph.evalBGP(subsetBGP, context));
return builder.execute(iterator, missingBGP, context);
}
//# sourceMappingURL=evaluation.js.map