rdf-stores
Version:
A TypeScript/JavaScript implementation of the RDF/JS store interface with support for quoted triples.
166 lines • 5.72 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RdfStoreIndexNestedMapRecursive = void 0;
const OrderUtils_1 = require("../OrderUtils");
/**
* An RDF store index that is implemented using nested Maps,
* and finds quads components via recursive methods calls.
*/
class RdfStoreIndexNestedMapRecursive {
constructor(options) {
this.features = {
quotedTripleFiltering: false,
};
this.dictionary = options.dictionary;
this.nestedMap = new Map();
}
set(terms, value) {
let map = this.nestedMap;
let contained = false;
for (const [i, term] of terms.entries()) {
const mapActual = map;
let nextMap = mapActual.get(term);
if (!nextMap) {
nextMap = i === terms.length - 1 ? value : new Map();
mapActual.set(term, nextMap);
}
else if (i === terms.length - 1) {
contained = true;
}
map = nextMap;
}
return !contained;
}
remove(terms) {
const map0 = this.nestedMap;
const map1 = map0.get(terms[0]);
if (!map1) {
return false;
}
const map2 = map1.get(terms[1]);
if (!map2) {
return false;
}
const map3 = map2.get(terms[2]);
if (!map3) {
return false;
}
const ret = map3.delete(terms[3]);
// Clean up intermediate maps
if (ret && map3.size === 0) {
map2.delete(terms[2]);
if (map2.size === 0) {
map1.delete(terms[1]);
if (map1.size === 0) {
map0.delete(terms[0]);
}
}
}
return ret;
}
get(key) {
const encoded = (0, OrderUtils_1.encodeOptionalTerms)(key, this.dictionary);
// eslint-disable-next-line unicorn/no-useless-undefined
if (!encoded || encoded.includes(undefined)) {
return undefined;
}
return this.getEncoded(encoded);
}
getEncoded(ids) {
const map1 = this.nestedMap.get(ids[0]);
if (!map1) {
return undefined;
}
const map2 = map1.get(ids[1]);
if (!map2) {
return undefined;
}
const map3 = map2.get(ids[2]);
if (!map3) {
return undefined;
}
return map3.get(ids[3]);
}
*find(terms) {
const ids = (0, OrderUtils_1.encodeOptionalTerms)(terms, this.dictionary);
if (!ids) {
return;
}
for (const termsEncoded of this.findEncoded(ids, terms)) {
yield [
ids[0] !== undefined ? terms[0] : this.dictionary.decode(termsEncoded[0]),
ids[1] !== undefined ? terms[1] : this.dictionary.decode(termsEncoded[1]),
ids[2] !== undefined ? terms[2] : this.dictionary.decode(termsEncoded[2]),
ids[3] !== undefined ? terms[3] : this.dictionary.decode(termsEncoded[3]),
];
}
}
*findEncoded(ids, terms) {
return yield* this
.findEncodedInner(0, ids, terms, this.nestedMap, []);
}
*findEncodedInner(index, ids, terms, map, partialQuad) {
if (index === ids.length) {
yield [...partialQuad];
}
else {
const id = ids[index];
const currentTerm = terms[index];
// If current term is undefined, iterate over all terms at this level.
if (!currentTerm) {
for (const [key, subMap] of map.entries()) {
partialQuad[index] = key;
yield* this
.findEncodedInner(index + 1, ids, terms, subMap, partialQuad);
}
}
else {
// If the current term is defined, find one matching map for the current term.
const encodedTerm = id;
if (encodedTerm !== undefined) {
const subMap = map.get(encodedTerm);
if (subMap) {
partialQuad[index] = id;
yield* this
.findEncodedInner(index + 1, ids, terms, subMap, partialQuad);
}
}
}
}
}
count(terms) {
return this.countInner(0, terms, this.nestedMap);
}
countInner(index, terms, map) {
const currentTerm = terms[index];
let count = 0;
// If current term is undefined, iterate over all terms at this level.
if (!currentTerm) {
if (index === terms.length - 1) {
return map.size;
}
for (const subMap of map.values()) {
count += this.countInner(index + 1, terms, subMap);
}
}
else {
// If the current term is defined, find one matching map for the current term.
const encodedTerm = this.dictionary.encodeOptional(currentTerm);
if (encodedTerm !== undefined) {
if (index === terms.length - 1) {
if (map.has(encodedTerm)) {
return 1;
}
return 0;
}
const subMap = map.get(encodedTerm);
if (subMap) {
count += this.countInner(index + 1, terms, subMap);
}
}
}
return count;
}
}
exports.RdfStoreIndexNestedMapRecursive = RdfStoreIndexNestedMapRecursive;
//# sourceMappingURL=RdfStoreIndexNestedMapRecursive.js.map