n3 2.7.0 → 2.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/N3Store.js CHANGED
@@ -249,13 +249,12 @@ class N3Store {
249
249
 
250
250
  // ### `_findInIndex` finds a set of quads in a three-layered index.
251
251
  // The index base is `index0` and the keys at each level are `key0`, `key1`, and `key2`.
252
- // Any of these keys can be undefined, which is interpreted as a wildcard.
252
+ // A key and any keys after it can be null or undefined, which is interpreted as a wildcard.
253
253
  // `name0`, `name1`, and `name2` are the names of the keys at each level,
254
254
  // used when reconstructing the resulting quad
255
255
  // (for instance: _subject_, _predicate_, and _object_).
256
256
  // Finally, `graphId` will be the graph of the created quads.
257
257
  *_findInIndex(index0, key0, key1, key2, name0, name1, name2, graphId) {
258
- let tmp, index1, index2;
259
258
  const entityKeys = this._entities;
260
259
  const graph = this._termFromId(entityKeys[graphId]);
261
260
  const parts = {
@@ -264,24 +263,32 @@ class N3Store {
264
263
  object: null
265
264
  };
266
265
 
267
- // If a key is specified, use only that part of index 0.
268
- if (key0) (tmp = index0, index0 = {})[key0] = tmp[key0];
269
- for (const value0 in index0) {
270
- if (index1 = index0[value0]) {
271
- parts[name0] = this._termFromId(entityKeys[value0]);
272
- // If a key is specified, use only that part of index 1.
273
- if (key1) (tmp = index1, index1 = {})[key1] = tmp[key1];
274
- for (const value1 in index1) {
275
- if (index2 = index1[value1]) {
276
- parts[name1] = this._termFromId(entityKeys[value1]);
277
- // If a key is specified, use only that part of index 2, if it exists.
278
- const values = key2 ? key2 in index2 ? [key2] : [] : Object.keys(index2);
279
- // Create quads for all items found in index 2.
280
- for (let l = 0; l < values.length; l++) {
281
- parts[name2] = this._termFromId(entityKeys[values[l]]);
282
- yield this._factory.quad(parts.subject, parts.predicate, parts.object, graph);
283
- }
284
- }
266
+ // Exact matches avoid allocating key arrays or entering generic loops.
267
+ if (key2) {
268
+ const index1 = index0[key0];
269
+ const index2 = index1 && index1[key1];
270
+ if (!index2 || !(key2 in index2)) return;
271
+ parts[name0] = this._termFromId(entityKeys[key0]);
272
+ parts[name1] = this._termFromId(entityKeys[key1]);
273
+ parts[name2] = this._termFromId(entityKeys[key2]);
274
+ yield this._factory.quad(parts.subject, parts.predicate, parts.object, graph);
275
+ return;
276
+ }
277
+ if (key0 && !(key0 in index0)) return;
278
+ // A null key list stops after visiting a bound key, avoiding a one-item array.
279
+ const keys0 = key0 ? null : Object.keys(index0);
280
+ for (let i0 = 0, value0 = key0 || keys0[0]; value0; value0 = keys0 && keys0[++i0]) {
281
+ const index1 = index0[value0];
282
+ parts[name0] = this._termFromId(entityKeys[value0]);
283
+ if (key1 && !(key1 in index1)) return;
284
+ const keys1 = key1 ? null : Object.keys(index1);
285
+ for (let i1 = 0, value1 = key1 || keys1[0]; value1; value1 = keys1 && keys1[++i1]) {
286
+ const index2 = index1[value1];
287
+ parts[name1] = this._termFromId(entityKeys[value1]);
288
+ const values = Object.keys(index2);
289
+ for (let l = 0; l < values.length; l++) {
290
+ parts[name2] = this._termFromId(entityKeys[values[l]]);
291
+ yield this._factory.quad(parts.subject, parts.predicate, parts.object, graph);
285
292
  }
286
293
  }
287
294
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n3",
3
- "version": "2.7.0",
3
+ "version": "2.7.2",
4
4
  "description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.",
5
5
  "author": "Ruben Verborgh <ruben.verborgh@gmail.com>",
6
6
  "keywords": [
package/src/N3Store.js CHANGED
@@ -268,35 +268,49 @@ export default class N3Store {
268
268
 
269
269
  // ### `_findInIndex` finds a set of quads in a three-layered index.
270
270
  // The index base is `index0` and the keys at each level are `key0`, `key1`, and `key2`.
271
- // Any of these keys can be undefined, which is interpreted as a wildcard.
271
+ // A key and any keys after it can be null or undefined, which is interpreted as a wildcard.
272
272
  // `name0`, `name1`, and `name2` are the names of the keys at each level,
273
273
  // used when reconstructing the resulting quad
274
274
  // (for instance: _subject_, _predicate_, and _object_).
275
275
  // Finally, `graphId` will be the graph of the created quads.
276
276
  *_findInIndex(index0, key0, key1, key2, name0, name1, name2, graphId) {
277
- let tmp, index1, index2;
278
277
  const entityKeys = this._entities;
279
278
  const graph = this._termFromId(entityKeys[graphId]);
280
279
  const parts = { subject: null, predicate: null, object: null };
281
280
 
282
- // If a key is specified, use only that part of index 0.
283
- if (key0) (tmp = index0, index0 = {})[key0] = tmp[key0];
284
- for (const value0 in index0) {
285
- if (index1 = index0[value0]) {
286
- parts[name0] = this._termFromId(entityKeys[value0]);
287
- // If a key is specified, use only that part of index 1.
288
- if (key1) (tmp = index1, index1 = {})[key1] = tmp[key1];
289
- for (const value1 in index1) {
290
- if (index2 = index1[value1]) {
291
- parts[name1] = this._termFromId(entityKeys[value1]);
292
- // If a key is specified, use only that part of index 2, if it exists.
293
- const values = key2 ? (key2 in index2 ? [key2] : []) : Object.keys(index2);
294
- // Create quads for all items found in index 2.
295
- for (let l = 0; l < values.length; l++) {
296
- parts[name2] = this._termFromId(entityKeys[values[l]]);
297
- yield this._factory.quad(parts.subject, parts.predicate, parts.object, graph);
298
- }
299
- }
281
+ // Exact matches avoid allocating key arrays or entering generic loops.
282
+ if (key2) {
283
+ const index1 = index0[key0];
284
+ const index2 = index1 && index1[key1];
285
+ if (!index2 || !(key2 in index2))
286
+ return;
287
+ parts[name0] = this._termFromId(entityKeys[key0]);
288
+ parts[name1] = this._termFromId(entityKeys[key1]);
289
+ parts[name2] = this._termFromId(entityKeys[key2]);
290
+ yield this._factory.quad(parts.subject, parts.predicate, parts.object, graph);
291
+ return;
292
+ }
293
+
294
+ if (key0 && !(key0 in index0))
295
+ return;
296
+ // A null key list stops after visiting a bound key, avoiding a one-item array.
297
+ const keys0 = key0 ? null : Object.keys(index0);
298
+ for (let i0 = 0, value0 = key0 || keys0[0]; value0;
299
+ value0 = keys0 && keys0[++i0]) {
300
+ const index1 = index0[value0];
301
+ parts[name0] = this._termFromId(entityKeys[value0]);
302
+
303
+ if (key1 && !(key1 in index1))
304
+ return;
305
+ const keys1 = key1 ? null : Object.keys(index1);
306
+ for (let i1 = 0, value1 = key1 || keys1[0]; value1;
307
+ value1 = keys1 && keys1[++i1]) {
308
+ const index2 = index1[value1];
309
+ parts[name1] = this._termFromId(entityKeys[value1]);
310
+ const values = Object.keys(index2);
311
+ for (let l = 0; l < values.length; l++) {
312
+ parts[name2] = this._termFromId(entityKeys[values[l]]);
313
+ yield this._factory.quad(parts.subject, parts.predicate, parts.object, graph);
300
314
  }
301
315
  }
302
316
  }