@comunica/bus-rdf-join 3.1.2 → 3.2.0

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.
@@ -145,6 +145,19 @@
145
145
  },
146
146
  "comment": "If this actor can handle undefs in the bindings. Defaults to false."
147
147
  },
148
+ {
149
+ "@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_isLeaf",
150
+ "range": {
151
+ "@type": "ParameterRangeUnion",
152
+ "parameterRangeElements": [
153
+ "xsd:boolean",
154
+ {
155
+ "@type": "ParameterRangeUndefined"
156
+ }
157
+ ]
158
+ },
159
+ "comment": "If this join operator will not invoke any other join or query operations below, and can therefore be considered a leaf of the join plan. Defaults to true."
160
+ },
148
161
  {
149
162
  "@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_args_beforeActors",
150
163
  "range": {
@@ -231,6 +244,11 @@
231
244
  "memberFieldName": "canHandleUndefs",
232
245
  "range": "xsd:boolean"
233
246
  },
247
+ {
248
+ "@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin__member_isLeaf",
249
+ "memberFieldName": "isLeaf",
250
+ "range": "xsd:boolean"
251
+ },
234
252
  {
235
253
  "@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin__member_constructor",
236
254
  "memberFieldName": "constructor"
@@ -239,6 +257,10 @@
239
257
  "@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin__member_hash",
240
258
  "memberFieldName": "hash"
241
259
  },
260
+ {
261
+ "@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin__member_hashNonClashing",
262
+ "memberFieldName": "hashNonClashing"
263
+ },
242
264
  {
243
265
  "@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin__member_overlappingVariables",
244
266
  "memberFieldName": "overlappingVariables"
@@ -271,6 +293,10 @@
271
293
  "@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin__member_getRequestItemTimes",
272
294
  "memberFieldName": "getRequestItemTimes"
273
295
  },
296
+ {
297
+ "@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin__member_constructState",
298
+ "memberFieldName": "constructState"
299
+ },
274
300
  {
275
301
  "@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin__member_constructResultMetadata",
276
302
  "memberFieldName": "constructResultMetadata"
@@ -358,6 +384,12 @@
358
384
  "value": {
359
385
  "@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_canHandleUndefs"
360
386
  }
387
+ },
388
+ {
389
+ "keyRaw": "isLeaf",
390
+ "value": {
391
+ "@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_isLeaf"
392
+ }
361
393
  }
362
394
  ]
363
395
  }
@@ -412,6 +444,10 @@
412
444
  {
413
445
  "@id": "cbrj:components/ActorRdfJoin.jsonld#IActorRdfJoinInternalOptions__member_canHandleUndefs",
414
446
  "memberFieldName": "canHandleUndefs"
447
+ },
448
+ {
449
+ "@id": "cbrj:components/ActorRdfJoin.jsonld#IActorRdfJoinInternalOptions__member_isLeaf",
450
+ "memberFieldName": "isLeaf"
415
451
  }
416
452
  ],
417
453
  "constructorArguments": []
@@ -32,6 +32,9 @@
32
32
  "options_canHandleUndefs": {
33
33
  "@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_canHandleUndefs"
34
34
  },
35
+ "options_isLeaf": {
36
+ "@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_isLeaf"
37
+ },
35
38
  "args_beforeActors": {
36
39
  "@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_args_beforeActors",
37
40
  "@container": "@list"
@@ -3,6 +3,7 @@ import type { MediatorRdfJoinSelectivity } from '@comunica/bus-rdf-join-selectiv
3
3
  import type { IAction, IActorArgs, Mediate } from '@comunica/core';
4
4
  import { Actor } from '@comunica/core';
5
5
  import type { IMediatorTypeJoinCoefficients } from '@comunica/mediatortype-join-coefficients';
6
+ import { MetadataValidationState } from '@comunica/metadata';
6
7
  import type { IQueryOperationResultBindings, MetadataBindings, Bindings, IActionContext, IJoinEntry, IJoinEntryWithMetadata } from '@comunica/types';
7
8
  import type * as RDF from '@rdfjs/types';
8
9
  /**
@@ -39,6 +40,11 @@ export declare abstract class ActorRdfJoin extends Actor<IActionRdfJoin, IMediat
39
40
  * If this actor can handle undefs in the bindings.
40
41
  */
41
42
  protected readonly canHandleUndefs: boolean;
43
+ /**
44
+ * If this join operator will not invoke any other join or query operations below,
45
+ * and can therefore be considered a leaf of the join plan.
46
+ */
47
+ protected readonly isLeaf: boolean;
42
48
  /**
43
49
  * @param args - @defaultNested {<default_bus> a <cc:components/Bus.jsonld#Bus>} bus
44
50
  * @param options - Actor-specific join options.
@@ -46,12 +52,22 @@ export declare abstract class ActorRdfJoin extends Actor<IActionRdfJoin, IMediat
46
52
  constructor(args: IActorRdfJoinArgs, options: IActorRdfJoinInternalOptions);
47
53
  /**
48
54
  * Creates a hash of the given bindings by concatenating the results of the given variables.
55
+ * This can cause clashes for equal terms.
49
56
  * This function will not sort the variables and expects them to be in the same order for every call.
50
57
  * @param {Bindings} bindings
51
58
  * @param {string[]} variables
52
59
  * @returns {string} A hash string.
53
60
  */
54
61
  static hash(bindings: Bindings, variables: RDF.Variable[]): string;
62
+ /**
63
+ * Creates a hash of the given bindings by concatenating the results of the given variables.
64
+ * This is guaranteed to not produce clashing bindings for unequal terms.
65
+ * This function will not sort the variables and expects them to be in the same order for every call.
66
+ * @param {Bindings} bindings
67
+ * @param {string[]} variables
68
+ * @returns {string} A hash string.
69
+ */
70
+ static hashNonClashing(bindings: RDF.Bindings, variables: RDF.Variable[]): string;
55
71
  /**
56
72
  * Returns an array containing all the variable names that occur in all bindings streams.
57
73
  * @param {MetadataBindings[]} metadatas An array of optional metadata objects for the entries.
@@ -96,6 +112,11 @@ export declare abstract class ActorRdfJoin extends Actor<IActionRdfJoin, IMediat
96
112
  * @param metadatas An array of checked metadata.
97
113
  */
98
114
  static getRequestItemTimes(metadatas: MetadataBindings[]): number[];
115
+ /**
116
+ * Construct a metadata validation state for the given metadata entries.
117
+ * @param metadatas An array of checked metadata.
118
+ */
119
+ constructState(metadatas: MetadataBindings[]): MetadataValidationState;
99
120
  /**
100
121
  * Helper function to create a new metadata object for the join result.
101
122
  * For required metadata entries that are not provided, sane defaults are calculated.
@@ -172,6 +193,12 @@ export interface IActorRdfJoinInternalOptions {
172
193
  * Defaults to false.
173
194
  */
174
195
  canHandleUndefs?: boolean;
196
+ /**
197
+ * If this join operator will not invoke any other join or query operations below,
198
+ * and can therefore be considered a leaf of the join plan.
199
+ * Defaults to true.
200
+ */
201
+ isLeaf?: boolean;
175
202
  }
176
203
  /**
177
204
  * Represents a logical join type.
@@ -5,6 +5,8 @@ const context_entries_1 = require("@comunica/context-entries");
5
5
  const core_1 = require("@comunica/core");
6
6
  const metadata_1 = require("@comunica/metadata");
7
7
  const rdf_data_factory_1 = require("rdf-data-factory");
8
+ const rdf_string_1 = require("rdf-string");
9
+ const instrumentIterator_1 = require("./instrumentIterator");
8
10
  const DF = new rdf_data_factory_1.DataFactory();
9
11
  /**
10
12
  * A comunica actor for joining 2 binding streams.
@@ -33,9 +35,11 @@ class ActorRdfJoin extends core_1.Actor {
33
35
  this.limitEntries = options.limitEntries ?? Number.POSITIVE_INFINITY;
34
36
  this.limitEntriesMin = options.limitEntriesMin ?? false;
35
37
  this.canHandleUndefs = options.canHandleUndefs ?? false;
38
+ this.isLeaf = options.isLeaf ?? true;
36
39
  }
37
40
  /**
38
41
  * Creates a hash of the given bindings by concatenating the results of the given variables.
42
+ * This can cause clashes for equal terms.
39
43
  * This function will not sort the variables and expects them to be in the same order for every call.
40
44
  * @param {Bindings} bindings
41
45
  * @param {string[]} variables
@@ -52,6 +56,25 @@ class ActorRdfJoin extends core_1.Actor {
52
56
  })
53
57
  .join('');
54
58
  }
59
+ /**
60
+ * Creates a hash of the given bindings by concatenating the results of the given variables.
61
+ * This is guaranteed to not produce clashing bindings for unequal terms.
62
+ * This function will not sort the variables and expects them to be in the same order for every call.
63
+ * @param {Bindings} bindings
64
+ * @param {string[]} variables
65
+ * @returns {string} A hash string.
66
+ */
67
+ static hashNonClashing(bindings, variables) {
68
+ return variables
69
+ .map((variable) => {
70
+ const term = bindings.get(variable);
71
+ if (term) {
72
+ return (0, rdf_string_1.termToString)(term);
73
+ }
74
+ return '';
75
+ })
76
+ .join('');
77
+ }
55
78
  /**
56
79
  * Returns an array containing all the variable names that occur in all bindings streams.
57
80
  * @param {MetadataBindings[]} metadatas An array of optional metadata objects for the entries.
@@ -134,6 +157,19 @@ class ActorRdfJoin extends core_1.Actor {
134
157
  return metadatas
135
158
  .map(metadata => metadata.pageSize ? (metadata.requestTime ?? 0) / metadata.pageSize : 0);
136
159
  }
160
+ /**
161
+ * Construct a metadata validation state for the given metadata entries.
162
+ * @param metadatas An array of checked metadata.
163
+ */
164
+ constructState(metadatas) {
165
+ // Propagate metadata invalidations
166
+ const state = new metadata_1.MetadataValidationState();
167
+ const invalidateListener = () => state.invalidate();
168
+ for (const metadata of metadatas) {
169
+ metadata.state.addInvalidateListener(invalidateListener);
170
+ }
171
+ return state;
172
+ }
137
173
  /**
138
174
  * Helper function to create a new metadata object for the join result.
139
175
  * For required metadata entries that are not provided, sane defaults are calculated.
@@ -158,14 +194,8 @@ class ActorRdfJoin extends core_1.Actor {
158
194
  }, { type: 'exact', value: 1 });
159
195
  cardinalityJoined.value *= (await this.mediatorJoinSelectivity.mediate({ entries, context })).selectivity;
160
196
  }
161
- // Propagate metadata invalidations
162
- const state = new metadata_1.MetadataValidationState();
163
- const invalidateListener = () => state.invalidate();
164
- for (const metadata of metadatas) {
165
- metadata.state.addInvalidateListener(invalidateListener);
166
- }
167
197
  return {
168
- state,
198
+ state: this.constructState(metadatas),
169
199
  ...partialMetadata,
170
200
  cardinality: {
171
201
  type: cardinalityJoined.type,
@@ -296,6 +326,8 @@ class ActorRdfJoin extends core_1.Actor {
296
326
  let planMetadata;
297
327
  if (this.includeInLogs && physicalQueryPlanLogger) {
298
328
  planMetadata = {};
329
+ // Stash non-join children, as they will be unstashed later in sub-joins.
330
+ physicalQueryPlanLogger.stashChildren(parentPhysicalQueryPlanNode, node => node.logicalOperator.startsWith('join'));
299
331
  physicalQueryPlanLogger.logOperation(`join-${this.logicalType}`, this.physicalName, action, parentPhysicalQueryPlanNode, this.name, planMetadata);
300
332
  }
301
333
  // Get action output
@@ -303,9 +335,27 @@ class ActorRdfJoin extends core_1.Actor {
303
335
  const metadatas = await ActorRdfJoin.getMetadatas(action.entries);
304
336
  // Fill in the physical plan metadata after determining action output
305
337
  if (planMetadata) {
338
+ // eslint-disable-next-line ts/no-floating-promises
339
+ (0, instrumentIterator_1.instrumentIterator)(result.bindingsStream)
340
+ .then((counters) => {
341
+ physicalQueryPlanLogger.appendMetadata(action, {
342
+ cardinalityReal: counters.count,
343
+ timeSelf: counters.timeSelf,
344
+ timeLife: counters.timeLife,
345
+ });
346
+ });
306
347
  Object.assign(planMetadata, physicalPlanMetadata);
307
- planMetadata.cardinalities = metadatas.map(ActorRdfJoin.getCardinality);
348
+ const cardinalities = metadatas.map(ActorRdfJoin.getCardinality);
349
+ planMetadata.cardinalities = cardinalities;
308
350
  planMetadata.joinCoefficients = await this.getJoinCoefficients(action, metadatas);
351
+ // If this is a leaf operation, include join entries in plan metadata.
352
+ if (this.isLeaf) {
353
+ for (let i = 0; i < action.entries.length; i++) {
354
+ const entry = action.entries[i];
355
+ physicalQueryPlanLogger.unstashChild(entry.operation, action);
356
+ physicalQueryPlanLogger.appendMetadata(entry.operation, { cardinality: cardinalities[i] });
357
+ }
358
+ }
309
359
  }
310
360
  // Cache metadata
311
361
  result.metadata = (0, metadata_1.cachifyMetadata)(result.metadata);
@@ -1 +1 @@
1
- {"version":3,"file":"ActorRdfJoin.js","sourceRoot":"","sources":["ActorRdfJoin.ts"],"names":[],"mappings":"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","sourcesContent":["import type { MediatorRdfJoinEntriesSort } from '@comunica/bus-rdf-join-entries-sort';\nimport type {\n MediatorRdfJoinSelectivity,\n} from '@comunica/bus-rdf-join-selectivity';\nimport { KeysInitQuery } from '@comunica/context-entries';\nimport type { IAction, IActorArgs, Mediate } from '@comunica/core';\nimport { Actor } from '@comunica/core';\nimport type { IMediatorTypeJoinCoefficients } from '@comunica/mediatortype-join-coefficients';\nimport { cachifyMetadata, MetadataValidationState } from '@comunica/metadata';\nimport type {\n IQueryOperationResultBindings,\n MetadataBindings,\n IPhysicalQueryPlanLogger,\n Bindings,\n IActionContext,\n IJoinEntry,\n IJoinEntryWithMetadata,\n} from '@comunica/types';\nimport type * as RDF from '@rdfjs/types';\nimport { DataFactory } from 'rdf-data-factory';\n\nconst DF = new DataFactory();\n\n/**\n * A comunica actor for joining 2 binding streams.\n *\n * Actor types:\n * * Input: IActionRdfJoin: The streams that need to be joined.\n * * Test: IMediatorTypeJoinCoefficients: Join coefficients.\n * * Output: IActorRdfJoinOutput: The resulting joined stream.\n *\n * @see IActionRdfJoin\n * @see IActorQueryOperationOutput\n */\nexport abstract class ActorRdfJoin\n extends Actor<IActionRdfJoin, IMediatorTypeJoinCoefficients, IQueryOperationResultBindings> {\n public readonly mediatorJoinSelectivity: MediatorRdfJoinSelectivity;\n\n /**\n * If this actor will be logged in the debugger and physical query plan logger\n */\n public includeInLogs = true;\n public readonly logicalType: LogicalJoinType;\n public readonly physicalName: string;\n /**\n * Can be used by subclasses to indicate the max or min number of streams that can be joined.\n * 0 for infinity.\n * By default, this indicates the max number, but can be inverted by setting limitEntriesMin to true.\n */\n protected readonly limitEntries: number;\n /**\n * If true, the limitEntries field is a lower limit,\n * otherwise, it is an upper limit.\n */\n protected readonly limitEntriesMin: boolean;\n /**\n * If this actor can handle undefs in the bindings.\n */\n protected readonly canHandleUndefs: boolean;\n\n /**\n * @param args - @defaultNested {<default_bus> a <cc:components/Bus.jsonld#Bus>} bus\n * @param options - Actor-specific join options.\n */\n public constructor(args: IActorRdfJoinArgs, options: IActorRdfJoinInternalOptions) {\n super(args);\n this.logicalType = options.logicalType;\n this.physicalName = options.physicalName;\n this.limitEntries = options.limitEntries ?? Number.POSITIVE_INFINITY;\n this.limitEntriesMin = options.limitEntriesMin ?? false;\n this.canHandleUndefs = options.canHandleUndefs ?? false;\n }\n\n /**\n * Creates a hash of the given bindings by concatenating the results of the given variables.\n * This function will not sort the variables and expects them to be in the same order for every call.\n * @param {Bindings} bindings\n * @param {string[]} variables\n * @returns {string} A hash string.\n */\n public static hash(bindings: Bindings, variables: RDF.Variable[]): string {\n return variables\n .map((variable) => {\n const term = bindings.get(variable);\n if (term) {\n return term.value;\n }\n return '';\n })\n .join('');\n }\n\n /**\n * Returns an array containing all the variable names that occur in all bindings streams.\n * @param {MetadataBindings[]} metadatas An array of optional metadata objects for the entries.\n * @returns {RDF.Variable[]} An array of variables.\n */\n public static overlappingVariables(metadatas: MetadataBindings[]): RDF.Variable[] {\n const variables = metadatas.map(metadata => metadata.variables);\n let baseArray = variables[0];\n for (const array of variables.slice(1)) {\n baseArray = baseArray.filter(el => array.some(value => value.value === el.value));\n }\n return baseArray;\n }\n\n /**\n * Returns the variables that will occur in the joined bindings.\n * @param {MetadataBindings[]} metadatas An array of metadata objects for the entries.\n * @returns {RDF.Variable[]} An array of joined variables.\n */\n public static joinVariables(metadatas: MetadataBindings[]): RDF.Variable[] {\n return [ ...new Set(metadatas.flatMap(metadata => metadata.variables.map(variable => variable.value))) ]\n .map(variable => DF.variable(variable));\n }\n\n /**\n * Returns the result of joining bindings, or `null` if no join is possible.\n * @param {Bindings[]} bindings\n * @returns {Bindings}\n */\n\n public static joinBindings(...bindings: Bindings[]): Bindings | null {\n if (bindings.length === 0) {\n return null;\n }\n if (bindings.length === 1) {\n return bindings[0];\n }\n\n let acc: Bindings = bindings[0];\n for (const binding of bindings.slice(1)) {\n const merged = acc.merge(binding);\n if (!merged) {\n return null;\n }\n acc = merged;\n }\n return acc;\n }\n\n /**\n * Get the estimated number of items from the given metadata.\n * @param {Record<string, any>} metadata A metadata object.\n * @return {number} The estimated number of items, or `Infinity` if cardinality is falsy.\n */\n public static getCardinality(metadata: MetadataBindings): RDF.QueryResultCardinality {\n return metadata.cardinality;\n }\n\n /**\n * Obtain the metadata from all given join entries.\n * @param entries Join entries.\n */\n public static async getMetadatas(entries: IJoinEntry[]): Promise<MetadataBindings[]> {\n return await Promise.all(entries.map(entry => entry.output.metadata()));\n }\n\n /**\n * Obtain the join entries witt metadata from all given join entries.\n * @param entries Join entries.\n */\n public static async getEntriesWithMetadatas(entries: IJoinEntry[]): Promise<IJoinEntryWithMetadata[]> {\n const metadatas = await ActorRdfJoin.getMetadatas(entries);\n return entries.map((entry, i) => ({ ...entry, metadata: metadatas[i] }));\n }\n\n /**\n * Calculate the time to initiate a request for the given metadata entries.\n * @param metadatas An array of checked metadata.\n */\n public static getRequestInitialTimes(metadatas: MetadataBindings[]): number[] {\n return metadatas.map(metadata => metadata.pageSize ? 0 : metadata.requestTime ?? 0);\n }\n\n /**\n * Calculate the time to receive a single item for the given metadata entries.\n * @param metadatas An array of checked metadata.\n */\n public static getRequestItemTimes(metadatas: MetadataBindings[]): number[] {\n return metadatas\n .map(metadata => metadata.pageSize ? (metadata.requestTime ?? 0) / metadata.pageSize : 0);\n }\n\n /**\n * Helper function to create a new metadata object for the join result.\n * For required metadata entries that are not provided, sane defaults are calculated.\n * @param entries Join entries.\n * @param metadatas Metadata of the join entries.\n * @param context The action context.\n * @param partialMetadata Partial metadata entries.\n */\n public async constructResultMetadata(\n entries: IJoinEntry[],\n metadatas: MetadataBindings[],\n context: IActionContext,\n partialMetadata: Partial<MetadataBindings> = {},\n ): Promise<MetadataBindings> {\n let cardinalityJoined: RDF.QueryResultCardinality;\n if (partialMetadata.cardinality) {\n cardinalityJoined = partialMetadata.cardinality;\n } else {\n cardinalityJoined = metadatas\n .reduce((acc: RDF.QueryResultCardinality, metadata) => {\n const cardinalityThis = ActorRdfJoin.getCardinality(metadata);\n return {\n type: cardinalityThis.type === 'estimate' ? 'estimate' : acc.type,\n value: acc.value * cardinalityThis.value,\n };\n }, { type: 'exact', value: 1 });\n cardinalityJoined.value *= (await this.mediatorJoinSelectivity.mediate({ entries, context })).selectivity;\n }\n\n // Propagate metadata invalidations\n const state = new MetadataValidationState();\n const invalidateListener = (): void => state.invalidate();\n for (const metadata of metadatas) {\n metadata.state.addInvalidateListener(invalidateListener);\n }\n\n return {\n state,\n ...partialMetadata,\n cardinality: {\n type: cardinalityJoined.type,\n value: cardinalityJoined.value,\n },\n canContainUndefs: partialMetadata.canContainUndefs ?? metadatas.some(metadata => metadata.canContainUndefs),\n variables: ActorRdfJoin.joinVariables(metadatas),\n };\n }\n\n /**\n * Order the given join entries using the join-entries-sort bus.\n * @param {MediatorRdfJoinEntriesSort} mediatorJoinEntriesSort A mediator for sorting join entries.\n * @param {IJoinEntryWithMetadata[]} entries An array of join entries.\n * @param context The action context.\n * @return {IJoinEntryWithMetadata[]} The sorted join entries.\n */\n public static async sortJoinEntries(\n mediatorJoinEntriesSort: MediatorRdfJoinEntriesSort,\n entries: IJoinEntryWithMetadata[],\n context: IActionContext,\n ): Promise<IJoinEntryWithMetadata[]> {\n // If there is a stream that can contain undefs, we don't modify the join order.\n const canContainUndefs = entries.some(entry => entry.metadata.canContainUndefs);\n if (canContainUndefs) {\n return entries;\n }\n\n // Calculate number of occurrences of each variable\n const variableOccurrences: Record<string, number> = {};\n for (const entry of entries) {\n for (const variable of entry.metadata.variables) {\n let counter = variableOccurrences[variable.value];\n if (!counter) {\n counter = 0;\n }\n variableOccurrences[variable.value] = ++counter;\n }\n }\n\n // Determine variables that occur in at least two join entries\n const multiOccurrenceVariables: string[] = [];\n for (const [ variable, count ] of Object.entries(variableOccurrences)) {\n if (count >= 2) {\n multiOccurrenceVariables.push(variable);\n }\n }\n\n // Reject if no entries have common variables\n if (multiOccurrenceVariables.length === 0) {\n throw new Error(`Bind join can only join entries with at least one common variable`);\n }\n\n // Determine entries without common variables\n // These will be placed in the back of the sorted array\n const entriesWithoutCommonVariables: IJoinEntryWithMetadata[] = [];\n for (const entry of entries) {\n let hasCommon = false;\n for (const variable of entry.metadata.variables) {\n if (multiOccurrenceVariables.includes(variable.value)) {\n hasCommon = true;\n break;\n }\n }\n if (!hasCommon) {\n entriesWithoutCommonVariables.push(entry);\n }\n }\n\n return (await mediatorJoinEntriesSort.mediate({ entries, context })).entries\n .sort((entryLeft, entryRight) => {\n // Sort to make sure that entries without common variables come last in the array.\n // For all other entries, the original order is kept.\n const leftWithoutCommonVariables = entriesWithoutCommonVariables.includes(entryLeft);\n const rightWithoutCommonVariables = entriesWithoutCommonVariables.includes(entryRight);\n if (leftWithoutCommonVariables === rightWithoutCommonVariables) {\n return 0;\n }\n return leftWithoutCommonVariables ?\n 1 :\n -1;\n });\n }\n\n /**\n * Default test function for join actors.\n * Checks whether all iterators have metadata.\n * If yes: call the abstract getIterations method, if not: return Infinity.\n * @param {IActionRdfJoin} action The input action containing the relevant iterators\n * @returns {Promise<IMediatorTypeJoinCoefficients>} The join coefficients.\n */\n public async test(action: IActionRdfJoin): Promise<IMediatorTypeJoinCoefficients> {\n // Validate logical join type\n if (action.type !== this.logicalType) {\n throw new Error(`${this.name} can only handle logical joins of type '${this.logicalType}', while '${action.type}' was given.`);\n }\n\n // Don't allow joining of one or zero streams\n if (action.entries.length <= 1) {\n throw new Error(`${this.name} requires at least two join entries.`);\n }\n\n // Check if this actor can handle the given number of streams\n if (this.limitEntriesMin ? action.entries.length < this.limitEntries : action.entries.length > this.limitEntries) {\n throw new Error(`${this.name} requires ${this.limitEntries\n } join entries at ${this.limitEntriesMin ? 'least' : 'most'\n }. The input contained ${action.entries.length}.`);\n }\n\n // Check if all streams are bindings streams\n for (const entry of action.entries) {\n if (entry.output.type !== 'bindings') {\n // eslint-disable-next-line ts/restrict-template-expressions\n throw new Error(`Invalid type of a join entry: Expected 'bindings' but got '${entry.output.type}'`);\n }\n }\n\n const metadatas = await ActorRdfJoin.getMetadatas(action.entries);\n\n // Check if this actor can handle undefs\n if (!this.canHandleUndefs) {\n for (const metadata of metadatas) {\n if (metadata.canContainUndefs) {\n throw new Error(`Actor ${this.name} can not join streams containing undefs`);\n }\n }\n }\n\n return await this.getJoinCoefficients(action, metadatas);\n }\n\n /**\n * Returns default input for 0 or 1 entries. Calls the getOutput function otherwise\n * @param {IActionRdfJoin} action\n * @returns {Promise<IQueryOperationResultBindings>} A bindings result.\n */\n public async run(action: IActionRdfJoin): Promise<IQueryOperationResultBindings> {\n // Prepare logging to physical plan\n // This must be called before getOutput, because we need to override the plan node in the context\n let parentPhysicalQueryPlanNode;\n if (action.context.has(KeysInitQuery.physicalQueryPlanLogger)) {\n parentPhysicalQueryPlanNode = action.context.get(KeysInitQuery.physicalQueryPlanNode);\n action.context = action.context.set(KeysInitQuery.physicalQueryPlanNode, action);\n }\n\n // Log to physical plan\n const physicalQueryPlanLogger: IPhysicalQueryPlanLogger | undefined = action.context.get(KeysInitQuery\n .physicalQueryPlanLogger);\n let planMetadata: any;\n if (this.includeInLogs && physicalQueryPlanLogger) {\n planMetadata = {};\n physicalQueryPlanLogger.logOperation(\n `join-${this.logicalType}`,\n this.physicalName,\n action,\n parentPhysicalQueryPlanNode,\n this.name,\n planMetadata,\n );\n }\n\n // Get action output\n const { result, physicalPlanMetadata } = await this.getOutput(action);\n const metadatas = await ActorRdfJoin.getMetadatas(action.entries);\n\n // Fill in the physical plan metadata after determining action output\n if (planMetadata) {\n Object.assign(planMetadata, physicalPlanMetadata);\n planMetadata.cardinalities = metadatas.map(ActorRdfJoin.getCardinality);\n planMetadata.joinCoefficients = await this.getJoinCoefficients(action, metadatas);\n }\n\n // Cache metadata\n result.metadata = cachifyMetadata(result.metadata);\n\n return result;\n }\n\n /**\n * Returns the resulting output for joining the given entries.\n * This is called after removing the trivial cases in run.\n * @param {IActionRdfJoin} action\n * @returns {Promise<IActorRdfJoinOutputInner>}\n */\n protected abstract getOutput(action: IActionRdfJoin): Promise<IActorRdfJoinOutputInner>;\n\n /**\n * Calculate the join coefficients.\n * @param {IActionRdfJoin} action Join action\n * @param metadatas Array of resolved metadata objects.\n * @returns {IMediatorTypeJoinCoefficients} The join coefficient estimates.\n */\n protected abstract getJoinCoefficients(\n action: IActionRdfJoin,\n metadatas: MetadataBindings[],\n ): Promise<IMediatorTypeJoinCoefficients>;\n}\n\nexport interface IActorRdfJoinArgs\n extends IActorArgs<IActionRdfJoin, IMediatorTypeJoinCoefficients, IQueryOperationResultBindings> {\n mediatorJoinSelectivity: MediatorRdfJoinSelectivity;\n}\n\nexport interface IActorRdfJoinInternalOptions {\n /**\n * The logical join type this actor can handle.\n */\n logicalType: LogicalJoinType;\n /**\n * The physical name of join operation this actor implements.\n * This is used for debug and query plan logs.\n */\n physicalName: string;\n /**\n * Can be used by subclasses to indicate the max or min number of streams that can be joined.\n * 0 for infinity.\n * By default, this indicates the max number, but can be inverted by setting limitEntriesMin to true.\n */\n limitEntries?: number;\n /**\n * If true, the limitEntries field is a lower limit,\n * otherwise, it is an upper limit.\n * Defaults to false.\n */\n limitEntriesMin?: boolean;\n /**\n * If this actor can handle undefs in the bindings.\n * Defaults to false.\n */\n canHandleUndefs?: boolean;\n}\n\n/**\n * Represents a logical join type.\n */\nexport type LogicalJoinType = 'inner' | 'optional' | 'minus';\n\nexport interface IActionRdfJoin extends IAction {\n /**\n * The logical join type.\n */\n type: LogicalJoinType;\n /**\n * The array of streams to join.\n */\n entries: IJoinEntry[];\n}\n\nexport interface IActorRdfJoinOutputInner {\n /**\n * The join result.\n */\n result: IQueryOperationResultBindings;\n /**\n * Optional metadata that will be included as metadata within the physical query plan output.\n */\n physicalPlanMetadata?: any;\n}\n\nexport type MediatorRdfJoin = Mediate<IActionRdfJoin, IQueryOperationResultBindings, IMediatorTypeJoinCoefficients>;\n"]}
1
+ {"version":3,"file":"ActorRdfJoin.js","sourceRoot":"","sources":["ActorRdfJoin.ts"],"names":[],"mappings":"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","sourcesContent":["import type { MediatorRdfJoinEntriesSort } from '@comunica/bus-rdf-join-entries-sort';\nimport type {\n MediatorRdfJoinSelectivity,\n} from '@comunica/bus-rdf-join-selectivity';\nimport { KeysInitQuery } from '@comunica/context-entries';\nimport type { IAction, IActorArgs, Mediate } from '@comunica/core';\nimport { Actor } from '@comunica/core';\nimport type { IMediatorTypeJoinCoefficients } from '@comunica/mediatortype-join-coefficients';\nimport { cachifyMetadata, MetadataValidationState } from '@comunica/metadata';\nimport type {\n IQueryOperationResultBindings,\n MetadataBindings,\n IPhysicalQueryPlanLogger,\n Bindings,\n IActionContext,\n IJoinEntry,\n IJoinEntryWithMetadata,\n} from '@comunica/types';\nimport type * as RDF from '@rdfjs/types';\nimport { DataFactory } from 'rdf-data-factory';\nimport { termToString } from 'rdf-string';\nimport { instrumentIterator } from './instrumentIterator';\n\nconst DF = new DataFactory();\n\n/**\n * A comunica actor for joining 2 binding streams.\n *\n * Actor types:\n * * Input: IActionRdfJoin: The streams that need to be joined.\n * * Test: IMediatorTypeJoinCoefficients: Join coefficients.\n * * Output: IActorRdfJoinOutput: The resulting joined stream.\n *\n * @see IActionRdfJoin\n * @see IActorQueryOperationOutput\n */\nexport abstract class ActorRdfJoin\n extends Actor<IActionRdfJoin, IMediatorTypeJoinCoefficients, IQueryOperationResultBindings> {\n public readonly mediatorJoinSelectivity: MediatorRdfJoinSelectivity;\n\n /**\n * If this actor will be logged in the debugger and physical query plan logger\n */\n public includeInLogs = true;\n public readonly logicalType: LogicalJoinType;\n public readonly physicalName: string;\n /**\n * Can be used by subclasses to indicate the max or min number of streams that can be joined.\n * 0 for infinity.\n * By default, this indicates the max number, but can be inverted by setting limitEntriesMin to true.\n */\n protected readonly limitEntries: number;\n /**\n * If true, the limitEntries field is a lower limit,\n * otherwise, it is an upper limit.\n */\n protected readonly limitEntriesMin: boolean;\n /**\n * If this actor can handle undefs in the bindings.\n */\n protected readonly canHandleUndefs: boolean;\n /**\n * If this join operator will not invoke any other join or query operations below,\n * and can therefore be considered a leaf of the join plan.\n */\n protected readonly isLeaf: boolean;\n\n /**\n * @param args - @defaultNested {<default_bus> a <cc:components/Bus.jsonld#Bus>} bus\n * @param options - Actor-specific join options.\n */\n public constructor(args: IActorRdfJoinArgs, options: IActorRdfJoinInternalOptions) {\n super(args);\n this.logicalType = options.logicalType;\n this.physicalName = options.physicalName;\n this.limitEntries = options.limitEntries ?? Number.POSITIVE_INFINITY;\n this.limitEntriesMin = options.limitEntriesMin ?? false;\n this.canHandleUndefs = options.canHandleUndefs ?? false;\n this.isLeaf = options.isLeaf ?? true;\n }\n\n /**\n * Creates a hash of the given bindings by concatenating the results of the given variables.\n * This can cause clashes for equal terms.\n * This function will not sort the variables and expects them to be in the same order for every call.\n * @param {Bindings} bindings\n * @param {string[]} variables\n * @returns {string} A hash string.\n */\n public static hash(bindings: Bindings, variables: RDF.Variable[]): string {\n return variables\n .map((variable) => {\n const term = bindings.get(variable);\n if (term) {\n return term.value;\n }\n return '';\n })\n .join('');\n }\n\n /**\n * Creates a hash of the given bindings by concatenating the results of the given variables.\n * This is guaranteed to not produce clashing bindings for unequal terms.\n * This function will not sort the variables and expects them to be in the same order for every call.\n * @param {Bindings} bindings\n * @param {string[]} variables\n * @returns {string} A hash string.\n */\n public static hashNonClashing(bindings: RDF.Bindings, variables: RDF.Variable[]): string {\n return variables\n .map((variable) => {\n const term = bindings.get(variable);\n if (term) {\n return termToString(term);\n }\n return '';\n })\n .join('');\n }\n\n /**\n * Returns an array containing all the variable names that occur in all bindings streams.\n * @param {MetadataBindings[]} metadatas An array of optional metadata objects for the entries.\n * @returns {RDF.Variable[]} An array of variables.\n */\n public static overlappingVariables(metadatas: MetadataBindings[]): RDF.Variable[] {\n const variables = metadatas.map(metadata => metadata.variables);\n let baseArray = variables[0];\n for (const array of variables.slice(1)) {\n baseArray = baseArray.filter(el => array.some(value => value.value === el.value));\n }\n return baseArray;\n }\n\n /**\n * Returns the variables that will occur in the joined bindings.\n * @param {MetadataBindings[]} metadatas An array of metadata objects for the entries.\n * @returns {RDF.Variable[]} An array of joined variables.\n */\n public static joinVariables(metadatas: MetadataBindings[]): RDF.Variable[] {\n return [ ...new Set(metadatas.flatMap(metadata => metadata.variables.map(variable => variable.value))) ]\n .map(variable => DF.variable(variable));\n }\n\n /**\n * Returns the result of joining bindings, or `null` if no join is possible.\n * @param {Bindings[]} bindings\n * @returns {Bindings}\n */\n\n public static joinBindings(...bindings: Bindings[]): Bindings | null {\n if (bindings.length === 0) {\n return null;\n }\n if (bindings.length === 1) {\n return bindings[0];\n }\n\n let acc: Bindings = bindings[0];\n for (const binding of bindings.slice(1)) {\n const merged = acc.merge(binding);\n if (!merged) {\n return null;\n }\n acc = merged;\n }\n return acc;\n }\n\n /**\n * Get the estimated number of items from the given metadata.\n * @param {Record<string, any>} metadata A metadata object.\n * @return {number} The estimated number of items, or `Infinity` if cardinality is falsy.\n */\n public static getCardinality(metadata: MetadataBindings): RDF.QueryResultCardinality {\n return metadata.cardinality;\n }\n\n /**\n * Obtain the metadata from all given join entries.\n * @param entries Join entries.\n */\n public static async getMetadatas(entries: IJoinEntry[]): Promise<MetadataBindings[]> {\n return await Promise.all(entries.map(entry => entry.output.metadata()));\n }\n\n /**\n * Obtain the join entries witt metadata from all given join entries.\n * @param entries Join entries.\n */\n public static async getEntriesWithMetadatas(entries: IJoinEntry[]): Promise<IJoinEntryWithMetadata[]> {\n const metadatas = await ActorRdfJoin.getMetadatas(entries);\n return entries.map((entry, i) => ({ ...entry, metadata: metadatas[i] }));\n }\n\n /**\n * Calculate the time to initiate a request for the given metadata entries.\n * @param metadatas An array of checked metadata.\n */\n public static getRequestInitialTimes(metadatas: MetadataBindings[]): number[] {\n return metadatas.map(metadata => metadata.pageSize ? 0 : metadata.requestTime ?? 0);\n }\n\n /**\n * Calculate the time to receive a single item for the given metadata entries.\n * @param metadatas An array of checked metadata.\n */\n public static getRequestItemTimes(metadatas: MetadataBindings[]): number[] {\n return metadatas\n .map(metadata => metadata.pageSize ? (metadata.requestTime ?? 0) / metadata.pageSize : 0);\n }\n\n /**\n * Construct a metadata validation state for the given metadata entries.\n * @param metadatas An array of checked metadata.\n */\n public constructState(metadatas: MetadataBindings[]): MetadataValidationState {\n // Propagate metadata invalidations\n const state = new MetadataValidationState();\n const invalidateListener = (): void => state.invalidate();\n for (const metadata of metadatas) {\n metadata.state.addInvalidateListener(invalidateListener);\n }\n return state;\n }\n\n /**\n * Helper function to create a new metadata object for the join result.\n * For required metadata entries that are not provided, sane defaults are calculated.\n * @param entries Join entries.\n * @param metadatas Metadata of the join entries.\n * @param context The action context.\n * @param partialMetadata Partial metadata entries.\n */\n public async constructResultMetadata(\n entries: IJoinEntry[],\n metadatas: MetadataBindings[],\n context: IActionContext,\n partialMetadata: Partial<MetadataBindings> = {},\n ): Promise<MetadataBindings> {\n let cardinalityJoined: RDF.QueryResultCardinality;\n if (partialMetadata.cardinality) {\n cardinalityJoined = partialMetadata.cardinality;\n } else {\n cardinalityJoined = metadatas\n .reduce((acc: RDF.QueryResultCardinality, metadata) => {\n const cardinalityThis = ActorRdfJoin.getCardinality(metadata);\n return {\n type: cardinalityThis.type === 'estimate' ? 'estimate' : acc.type,\n value: acc.value * cardinalityThis.value,\n };\n }, { type: 'exact', value: 1 });\n cardinalityJoined.value *= (await this.mediatorJoinSelectivity.mediate({ entries, context })).selectivity;\n }\n\n return {\n state: this.constructState(metadatas),\n ...partialMetadata,\n cardinality: {\n type: cardinalityJoined.type,\n value: cardinalityJoined.value,\n },\n canContainUndefs: partialMetadata.canContainUndefs ?? metadatas.some(metadata => metadata.canContainUndefs),\n variables: ActorRdfJoin.joinVariables(metadatas),\n };\n }\n\n /**\n * Order the given join entries using the join-entries-sort bus.\n * @param {MediatorRdfJoinEntriesSort} mediatorJoinEntriesSort A mediator for sorting join entries.\n * @param {IJoinEntryWithMetadata[]} entries An array of join entries.\n * @param context The action context.\n * @return {IJoinEntryWithMetadata[]} The sorted join entries.\n */\n public static async sortJoinEntries(\n mediatorJoinEntriesSort: MediatorRdfJoinEntriesSort,\n entries: IJoinEntryWithMetadata[],\n context: IActionContext,\n ): Promise<IJoinEntryWithMetadata[]> {\n // If there is a stream that can contain undefs, we don't modify the join order.\n const canContainUndefs = entries.some(entry => entry.metadata.canContainUndefs);\n if (canContainUndefs) {\n return entries;\n }\n\n // Calculate number of occurrences of each variable\n const variableOccurrences: Record<string, number> = {};\n for (const entry of entries) {\n for (const variable of entry.metadata.variables) {\n let counter = variableOccurrences[variable.value];\n if (!counter) {\n counter = 0;\n }\n variableOccurrences[variable.value] = ++counter;\n }\n }\n\n // Determine variables that occur in at least two join entries\n const multiOccurrenceVariables: string[] = [];\n for (const [ variable, count ] of Object.entries(variableOccurrences)) {\n if (count >= 2) {\n multiOccurrenceVariables.push(variable);\n }\n }\n\n // Reject if no entries have common variables\n if (multiOccurrenceVariables.length === 0) {\n throw new Error(`Bind join can only join entries with at least one common variable`);\n }\n\n // Determine entries without common variables\n // These will be placed in the back of the sorted array\n const entriesWithoutCommonVariables: IJoinEntryWithMetadata[] = [];\n for (const entry of entries) {\n let hasCommon = false;\n for (const variable of entry.metadata.variables) {\n if (multiOccurrenceVariables.includes(variable.value)) {\n hasCommon = true;\n break;\n }\n }\n if (!hasCommon) {\n entriesWithoutCommonVariables.push(entry);\n }\n }\n\n return (await mediatorJoinEntriesSort.mediate({ entries, context })).entries\n .sort((entryLeft, entryRight) => {\n // Sort to make sure that entries without common variables come last in the array.\n // For all other entries, the original order is kept.\n const leftWithoutCommonVariables = entriesWithoutCommonVariables.includes(entryLeft);\n const rightWithoutCommonVariables = entriesWithoutCommonVariables.includes(entryRight);\n if (leftWithoutCommonVariables === rightWithoutCommonVariables) {\n return 0;\n }\n return leftWithoutCommonVariables ?\n 1 :\n -1;\n });\n }\n\n /**\n * Default test function for join actors.\n * Checks whether all iterators have metadata.\n * If yes: call the abstract getIterations method, if not: return Infinity.\n * @param {IActionRdfJoin} action The input action containing the relevant iterators\n * @returns {Promise<IMediatorTypeJoinCoefficients>} The join coefficients.\n */\n public async test(action: IActionRdfJoin): Promise<IMediatorTypeJoinCoefficients> {\n // Validate logical join type\n if (action.type !== this.logicalType) {\n throw new Error(`${this.name} can only handle logical joins of type '${this.logicalType}', while '${action.type}' was given.`);\n }\n\n // Don't allow joining of one or zero streams\n if (action.entries.length <= 1) {\n throw new Error(`${this.name} requires at least two join entries.`);\n }\n\n // Check if this actor can handle the given number of streams\n if (this.limitEntriesMin ? action.entries.length < this.limitEntries : action.entries.length > this.limitEntries) {\n throw new Error(`${this.name} requires ${this.limitEntries\n } join entries at ${this.limitEntriesMin ? 'least' : 'most'\n }. The input contained ${action.entries.length}.`);\n }\n\n // Check if all streams are bindings streams\n for (const entry of action.entries) {\n if (entry.output.type !== 'bindings') {\n // eslint-disable-next-line ts/restrict-template-expressions\n throw new Error(`Invalid type of a join entry: Expected 'bindings' but got '${entry.output.type}'`);\n }\n }\n\n const metadatas = await ActorRdfJoin.getMetadatas(action.entries);\n\n // Check if this actor can handle undefs\n if (!this.canHandleUndefs) {\n for (const metadata of metadatas) {\n if (metadata.canContainUndefs) {\n throw new Error(`Actor ${this.name} can not join streams containing undefs`);\n }\n }\n }\n\n return await this.getJoinCoefficients(action, metadatas);\n }\n\n /**\n * Returns default input for 0 or 1 entries. Calls the getOutput function otherwise\n * @param {IActionRdfJoin} action\n * @returns {Promise<IQueryOperationResultBindings>} A bindings result.\n */\n public async run(action: IActionRdfJoin): Promise<IQueryOperationResultBindings> {\n // Prepare logging to physical plan\n // This must be called before getOutput, because we need to override the plan node in the context\n let parentPhysicalQueryPlanNode;\n if (action.context.has(KeysInitQuery.physicalQueryPlanLogger)) {\n parentPhysicalQueryPlanNode = action.context.get(KeysInitQuery.physicalQueryPlanNode);\n action.context = action.context.set(KeysInitQuery.physicalQueryPlanNode, action);\n }\n\n // Log to physical plan\n const physicalQueryPlanLogger: IPhysicalQueryPlanLogger | undefined = action.context.get(KeysInitQuery\n .physicalQueryPlanLogger);\n let planMetadata: any;\n if (this.includeInLogs && physicalQueryPlanLogger) {\n planMetadata = {};\n // Stash non-join children, as they will be unstashed later in sub-joins.\n physicalQueryPlanLogger.stashChildren(\n parentPhysicalQueryPlanNode,\n node => node.logicalOperator.startsWith('join'),\n );\n physicalQueryPlanLogger.logOperation(\n `join-${this.logicalType}`,\n this.physicalName,\n action,\n parentPhysicalQueryPlanNode,\n this.name,\n planMetadata,\n );\n }\n\n // Get action output\n const { result, physicalPlanMetadata } = await this.getOutput(action);\n const metadatas = await ActorRdfJoin.getMetadatas(action.entries);\n\n // Fill in the physical plan metadata after determining action output\n if (planMetadata) {\n // eslint-disable-next-line ts/no-floating-promises\n instrumentIterator(result.bindingsStream)\n .then((counters) => {\n physicalQueryPlanLogger!.appendMetadata(action, {\n cardinalityReal: counters.count,\n timeSelf: counters.timeSelf,\n timeLife: counters.timeLife,\n });\n });\n\n Object.assign(planMetadata, physicalPlanMetadata);\n const cardinalities = metadatas.map(ActorRdfJoin.getCardinality);\n planMetadata.cardinalities = cardinalities;\n planMetadata.joinCoefficients = await this.getJoinCoefficients(action, metadatas);\n\n // If this is a leaf operation, include join entries in plan metadata.\n if (this.isLeaf) {\n for (let i = 0; i < action.entries.length; i++) {\n const entry = action.entries[i];\n physicalQueryPlanLogger!.unstashChild(\n entry.operation,\n action,\n );\n physicalQueryPlanLogger!.appendMetadata(entry.operation, { cardinality: cardinalities[i] });\n }\n }\n }\n\n // Cache metadata\n result.metadata = cachifyMetadata(result.metadata);\n\n return result;\n }\n\n /**\n * Returns the resulting output for joining the given entries.\n * This is called after removing the trivial cases in run.\n * @param {IActionRdfJoin} action\n * @returns {Promise<IActorRdfJoinOutputInner>}\n */\n protected abstract getOutput(action: IActionRdfJoin): Promise<IActorRdfJoinOutputInner>;\n\n /**\n * Calculate the join coefficients.\n * @param {IActionRdfJoin} action Join action\n * @param metadatas Array of resolved metadata objects.\n * @returns {IMediatorTypeJoinCoefficients} The join coefficient estimates.\n */\n protected abstract getJoinCoefficients(\n action: IActionRdfJoin,\n metadatas: MetadataBindings[],\n ): Promise<IMediatorTypeJoinCoefficients>;\n}\n\nexport interface IActorRdfJoinArgs\n extends IActorArgs<IActionRdfJoin, IMediatorTypeJoinCoefficients, IQueryOperationResultBindings> {\n mediatorJoinSelectivity: MediatorRdfJoinSelectivity;\n}\n\nexport interface IActorRdfJoinInternalOptions {\n /**\n * The logical join type this actor can handle.\n */\n logicalType: LogicalJoinType;\n /**\n * The physical name of join operation this actor implements.\n * This is used for debug and query plan logs.\n */\n physicalName: string;\n /**\n * Can be used by subclasses to indicate the max or min number of streams that can be joined.\n * 0 for infinity.\n * By default, this indicates the max number, but can be inverted by setting limitEntriesMin to true.\n */\n limitEntries?: number;\n /**\n * If true, the limitEntries field is a lower limit,\n * otherwise, it is an upper limit.\n * Defaults to false.\n */\n limitEntriesMin?: boolean;\n /**\n * If this actor can handle undefs in the bindings.\n * Defaults to false.\n */\n canHandleUndefs?: boolean;\n /**\n * If this join operator will not invoke any other join or query operations below,\n * and can therefore be considered a leaf of the join plan.\n * Defaults to true.\n */\n isLeaf?: boolean;\n}\n\n/**\n * Represents a logical join type.\n */\nexport type LogicalJoinType = 'inner' | 'optional' | 'minus';\n\nexport interface IActionRdfJoin extends IAction {\n /**\n * The logical join type.\n */\n type: LogicalJoinType;\n /**\n * The array of streams to join.\n */\n entries: IJoinEntry[];\n}\n\nexport interface IActorRdfJoinOutputInner {\n /**\n * The join result.\n */\n result: IQueryOperationResultBindings;\n /**\n * Optional metadata that will be included as metadata within the physical query plan output.\n */\n physicalPlanMetadata?: any;\n}\n\nexport type MediatorRdfJoin = Mediate<IActionRdfJoin, IQueryOperationResultBindings, IMediatorTypeJoinCoefficients>;\n"]}
@@ -0,0 +1,20 @@
1
+ import type { AsyncIterator } from 'asynciterator';
2
+ export type IteratorCounters = {
3
+ /**
4
+ * The total time spent within `_read` and `read`.
5
+ */
6
+ timeSelf: number;
7
+ /**
8
+ * The time between creation and ending.
9
+ */
10
+ timeLife: number;
11
+ /**
12
+ * The number of elements produced.
13
+ */
14
+ count: number;
15
+ };
16
+ /**
17
+ * Profile an iterator by monkey-patching its `_read` and `read` methods.
18
+ * @param iterator
19
+ */
20
+ export declare function instrumentIterator(iterator: AsyncIterator<any>): Promise<IteratorCounters>;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.instrumentIterator = void 0;
4
+ /**
5
+ * Profile an iterator by monkey-patching its `_read` and `read` methods.
6
+ * @param iterator
7
+ */
8
+ function instrumentIterator(iterator) {
9
+ const counters = {
10
+ count: 0,
11
+ timeSelf: 0,
12
+ timeLife: 0,
13
+ };
14
+ instrumentIteratorInner(iterator, counters, true);
15
+ return new Promise((resolve) => {
16
+ iterator.on('end', () => {
17
+ resolve(counters);
18
+ });
19
+ });
20
+ }
21
+ exports.instrumentIterator = instrumentIterator;
22
+ function instrumentIteratorInner(iterator, counter, top) {
23
+ if (!('_profileInstrumented' in iterator)) {
24
+ // Only patch an iterator once.
25
+ iterator._profileInstrumented = true;
26
+ // Patch _read
27
+ if ('_read' in iterator) {
28
+ const readOld = iterator._read;
29
+ iterator._read = (count, done) => {
30
+ const startTime = performance.now();
31
+ readOld.call(iterator, count, () => {
32
+ counter.timeSelf += performance.now() - startTime;
33
+ done();
34
+ });
35
+ };
36
+ }
37
+ // Patch read
38
+ if ('read' in iterator) {
39
+ // eslint-disable-next-line ts/unbound-method
40
+ const readOld = iterator.read;
41
+ iterator.read = () => {
42
+ const startTime = performance.now();
43
+ const ret = readOld.call(iterator);
44
+ if (top && ret) {
45
+ counter.count++;
46
+ }
47
+ counter.timeSelf += performance.now() - startTime;
48
+ return ret;
49
+ };
50
+ }
51
+ // Measure total time
52
+ if (top) {
53
+ const startTime = performance.now();
54
+ iterator.on('end', () => {
55
+ counter.timeLife = performance.now() - startTime;
56
+ });
57
+ }
58
+ // Also patch children
59
+ if ('_source' in iterator) {
60
+ instrumentIteratorInner(iterator._source, counter, false);
61
+ }
62
+ }
63
+ }
64
+ //# sourceMappingURL=instrumentIterator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instrumentIterator.js","sourceRoot":"","sources":["instrumentIterator.ts"],"names":[],"mappings":";;;AAiBA;;;GAGG;AACH,SAAgB,kBAAkB,CAAC,QAA4B;IAC7D,MAAM,QAAQ,GAAqB;QACjC,KAAK,EAAE,CAAC;QACR,QAAQ,EAAE,CAAC;QACX,QAAQ,EAAE,CAAC;KACZ,CAAC;IACF,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACtB,OAAO,CAAC,QAAQ,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAZD,gDAYC;AAED,SAAS,uBAAuB,CAC9B,QAA4B,EAC5B,OAA8D,EAC9D,GAAY;IAEZ,IAAI,CAAC,CAAC,sBAAsB,IAAI,QAAQ,CAAC,EAAE,CAAC;QAC1C,+BAA+B;QACzB,QAAS,CAAC,oBAAoB,GAAG,IAAI,CAAC;QAE5C,cAAc;QACd,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;YACxB,MAAM,OAAO,GAAQ,QAAQ,CAAC,KAAK,CAAC;YACpC,QAAQ,CAAC,KAAK,GAAG,CAAC,KAAa,EAAE,IAAgB,EAAE,EAAE;gBACnD,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;gBACpC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;oBACjC,OAAO,CAAC,QAAQ,IAAI,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;oBAClD,IAAI,EAAE,CAAC;gBACT,CAAC,CAAC,CAAC;YACL,CAAC,CAAC;QACJ,CAAC;QAED,aAAa;QACb,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC;YACvB,6CAA6C;YAC7C,MAAM,OAAO,GAAQ,QAAQ,CAAC,IAAI,CAAC;YACnC,QAAQ,CAAC,IAAI,GAAG,GAAG,EAAE;gBACnB,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;gBACpC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACnC,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,EAAE,CAAC;gBAClB,CAAC;gBACD,OAAO,CAAC,QAAQ,IAAI,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;gBAClD,OAAO,GAAG,CAAC;YACb,CAAC,CAAC;QACJ,CAAC;QAED,qBAAqB;QACrB,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YACpC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACtB,OAAO,CAAC,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YACnD,CAAC,CAAC,CAAC;QACL,CAAC;QAED,sBAAsB;QACtB,IAAI,SAAS,IAAI,QAAQ,EAAE,CAAC;YAC1B,uBAAuB,CAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import type { AsyncIterator } from 'asynciterator';\n\nexport type IteratorCounters = {\n /**\n * The total time spent within `_read` and `read`.\n */\n timeSelf: number;\n /**\n * The time between creation and ending.\n */\n timeLife: number;\n /**\n * The number of elements produced.\n */\n count: number;\n};\n\n/**\n * Profile an iterator by monkey-patching its `_read` and `read` methods.\n * @param iterator\n */\nexport function instrumentIterator(iterator: AsyncIterator<any>): Promise<IteratorCounters> {\n const counters: IteratorCounters = {\n count: 0,\n timeSelf: 0,\n timeLife: 0,\n };\n instrumentIteratorInner(iterator, counters, true);\n return new Promise((resolve) => {\n iterator.on('end', () => {\n resolve(counters);\n });\n });\n}\n\nfunction instrumentIteratorInner(\n iterator: AsyncIterator<any>,\n counter: { timeSelf: number; timeLife: number; count: number },\n top: boolean,\n): void {\n if (!('_profileInstrumented' in iterator)) {\n // Only patch an iterator once.\n (<any>iterator)._profileInstrumented = true;\n\n // Patch _read\n if ('_read' in iterator) {\n const readOld: any = iterator._read;\n iterator._read = (count: number, done: () => void) => {\n const startTime = performance.now();\n readOld.call(iterator, count, () => {\n counter.timeSelf += performance.now() - startTime;\n done();\n });\n };\n }\n\n // Patch read\n if ('read' in iterator) {\n // eslint-disable-next-line ts/unbound-method\n const readOld: any = iterator.read;\n iterator.read = () => {\n const startTime = performance.now();\n const ret = readOld.call(iterator);\n if (top && ret) {\n counter.count++;\n }\n counter.timeSelf += performance.now() - startTime;\n return ret;\n };\n }\n\n // Measure total time\n if (top) {\n const startTime = performance.now();\n iterator.on('end', () => {\n counter.timeLife = performance.now() - startTime;\n });\n }\n\n // Also patch children\n if ('_source' in iterator) {\n instrumentIteratorInner(<any>iterator._source, counter, false);\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comunica/bus-rdf-join",
3
- "version": "3.1.2",
3
+ "version": "3.2.0",
4
4
  "description": "A comunica bus for rdf-join events.",
5
5
  "lsd:module": true,
6
6
  "license": "MIT",
@@ -36,16 +36,17 @@
36
36
  "build:components": "componentsjs-generator"
37
37
  },
38
38
  "dependencies": {
39
- "@comunica/bus-rdf-join-entries-sort": "^3.1.0",
40
- "@comunica/bus-rdf-join-selectivity": "^3.1.0",
41
- "@comunica/context-entries": "^3.1.0",
42
- "@comunica/core": "^3.1.0",
43
- "@comunica/mediatortype-join-coefficients": "^3.1.0",
44
- "@comunica/metadata": "^3.1.0",
45
- "@comunica/types": "^3.1.0",
39
+ "@comunica/bus-rdf-join-entries-sort": "^3.2.0",
40
+ "@comunica/bus-rdf-join-selectivity": "^3.2.0",
41
+ "@comunica/context-entries": "^3.2.0",
42
+ "@comunica/core": "^3.2.0",
43
+ "@comunica/mediatortype-join-coefficients": "^3.2.0",
44
+ "@comunica/metadata": "^3.2.0",
45
+ "@comunica/types": "^3.2.0",
46
46
  "@rdfjs/types": "*",
47
47
  "asynciterator": "^3.9.0",
48
- "rdf-data-factory": "^1.1.1"
48
+ "rdf-data-factory": "^1.1.1",
49
+ "rdf-string": "^1.6.3"
49
50
  },
50
- "gitHead": "db31677bdef5400194783048840c147e04b793e5"
51
+ "gitHead": "87baf2afed021a254859e64b92f34d9b51c6a7db"
51
52
  }