@comunica/bus-rdf-join 4.0.2 → 4.1.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.
- package/components/ActorRdfJoin.jsonld +21 -49
- package/components/context.jsonld +8 -8
- package/lib/ActorRdfJoin.d.ts +2 -5
- package/lib/ActorRdfJoin.js +12 -29
- package/lib/ActorRdfJoin.js.map +1 -1
- package/package.json +9 -9
|
@@ -35,31 +35,17 @@
|
|
|
35
35
|
}
|
|
36
36
|
],
|
|
37
37
|
"parameters": [
|
|
38
|
-
{
|
|
39
|
-
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_args_mediatorJoinSelectivity",
|
|
40
|
-
"range": "cc:components/Mediator.jsonld#Mediator"
|
|
41
|
-
},
|
|
42
38
|
{
|
|
43
39
|
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_logicalType",
|
|
44
40
|
"range": {
|
|
45
|
-
"@type": "
|
|
46
|
-
"parameterRangeElements": [
|
|
47
|
-
{
|
|
48
|
-
"@type": "ParameterRangeLiteral",
|
|
49
|
-
"parameterRangeValueLiteral": "inner"
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
"@type": "ParameterRangeLiteral",
|
|
53
|
-
"parameterRangeValueLiteral": "optional"
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
"@type": "ParameterRangeLiteral",
|
|
57
|
-
"parameterRangeValueLiteral": "minus"
|
|
58
|
-
}
|
|
59
|
-
]
|
|
41
|
+
"@type": "ParameterRangeWildcard"
|
|
60
42
|
},
|
|
61
43
|
"comment": "The logical join type this actor can handle."
|
|
62
44
|
},
|
|
45
|
+
{
|
|
46
|
+
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_args_mediatorJoinSelectivity",
|
|
47
|
+
"range": "cc:components/Mediator.jsonld#Mediator"
|
|
48
|
+
},
|
|
63
49
|
{
|
|
64
50
|
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_physicalName",
|
|
65
51
|
"range": "xsd:string",
|
|
@@ -99,6 +85,19 @@
|
|
|
99
85
|
},
|
|
100
86
|
"comment": "If true, the limitEntries field is a lower limit, otherwise, it is an upper limit. Defaults to false."
|
|
101
87
|
},
|
|
88
|
+
{
|
|
89
|
+
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_canHandleUndefs",
|
|
90
|
+
"range": {
|
|
91
|
+
"@type": "ParameterRangeUnion",
|
|
92
|
+
"parameterRangeElements": [
|
|
93
|
+
"xsd:boolean",
|
|
94
|
+
{
|
|
95
|
+
"@type": "ParameterRangeUndefined"
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
"comment": "If this actor can handle undefs overlapping variable bindings. Defaults to false."
|
|
100
|
+
},
|
|
102
101
|
{
|
|
103
102
|
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_args_bus",
|
|
104
103
|
"range": {
|
|
@@ -152,7 +151,7 @@
|
|
|
152
151
|
"comment": "The bus this actor subscribes to."
|
|
153
152
|
},
|
|
154
153
|
{
|
|
155
|
-
"@id": "cbrj:components/ActorRdfJoin.jsonld#
|
|
154
|
+
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_isLeaf",
|
|
156
155
|
"range": {
|
|
157
156
|
"@type": "ParameterRangeUnion",
|
|
158
157
|
"parameterRangeElements": [
|
|
@@ -162,7 +161,7 @@
|
|
|
162
161
|
}
|
|
163
162
|
]
|
|
164
163
|
},
|
|
165
|
-
"comment": "If this
|
|
164
|
+
"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."
|
|
166
165
|
},
|
|
167
166
|
{
|
|
168
167
|
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_args_busFailMessage",
|
|
@@ -178,19 +177,6 @@
|
|
|
178
177
|
"default": "RDF joining failed: none of the configured actors were able to handle the join type ${action.type}",
|
|
179
178
|
"comment": "The message that will be configured in the bus for reporting failures. This message may be a template string that contains references to the executed `action`. For example, the following templated string is allowed: \"RDF dereferencing failed: no actors could handle ${action.handle.mediaType}\""
|
|
180
179
|
},
|
|
181
|
-
{
|
|
182
|
-
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_isLeaf",
|
|
183
|
-
"range": {
|
|
184
|
-
"@type": "ParameterRangeUnion",
|
|
185
|
-
"parameterRangeElements": [
|
|
186
|
-
"xsd:boolean",
|
|
187
|
-
{
|
|
188
|
-
"@type": "ParameterRangeUndefined"
|
|
189
|
-
}
|
|
190
|
-
]
|
|
191
|
-
},
|
|
192
|
-
"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."
|
|
193
|
-
},
|
|
194
180
|
{
|
|
195
181
|
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_requiresVariableOverlap",
|
|
196
182
|
"range": {
|
|
@@ -257,21 +243,7 @@
|
|
|
257
243
|
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin__member_logicalType",
|
|
258
244
|
"memberFieldName": "logicalType",
|
|
259
245
|
"range": {
|
|
260
|
-
"@type": "
|
|
261
|
-
"parameterRangeElements": [
|
|
262
|
-
{
|
|
263
|
-
"@type": "ParameterRangeLiteral",
|
|
264
|
-
"parameterRangeValueLiteral": "inner"
|
|
265
|
-
},
|
|
266
|
-
{
|
|
267
|
-
"@type": "ParameterRangeLiteral",
|
|
268
|
-
"parameterRangeValueLiteral": "optional"
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
"@type": "ParameterRangeLiteral",
|
|
272
|
-
"parameterRangeValueLiteral": "minus"
|
|
273
|
-
}
|
|
274
|
-
]
|
|
246
|
+
"@type": "ParameterRangeWildcard"
|
|
275
247
|
}
|
|
276
248
|
},
|
|
277
249
|
{
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin",
|
|
9
9
|
"@prefix": true,
|
|
10
10
|
"@context": {
|
|
11
|
-
"args_mediatorJoinSelectivity": {
|
|
12
|
-
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_args_mediatorJoinSelectivity"
|
|
13
|
-
},
|
|
14
11
|
"options_logicalType": {
|
|
15
12
|
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_logicalType"
|
|
16
13
|
},
|
|
14
|
+
"args_mediatorJoinSelectivity": {
|
|
15
|
+
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_args_mediatorJoinSelectivity"
|
|
16
|
+
},
|
|
17
17
|
"options_physicalName": {
|
|
18
18
|
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_physicalName"
|
|
19
19
|
},
|
|
@@ -26,18 +26,18 @@
|
|
|
26
26
|
"options_limitEntriesMin": {
|
|
27
27
|
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_limitEntriesMin"
|
|
28
28
|
},
|
|
29
|
-
"args_bus": {
|
|
30
|
-
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_args_bus"
|
|
31
|
-
},
|
|
32
29
|
"options_canHandleUndefs": {
|
|
33
30
|
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_canHandleUndefs"
|
|
34
31
|
},
|
|
35
|
-
"
|
|
36
|
-
"@id": "cbrj:components/ActorRdfJoin.jsonld#
|
|
32
|
+
"args_bus": {
|
|
33
|
+
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_args_bus"
|
|
37
34
|
},
|
|
38
35
|
"options_isLeaf": {
|
|
39
36
|
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_isLeaf"
|
|
40
37
|
},
|
|
38
|
+
"args_busFailMessage": {
|
|
39
|
+
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_args_busFailMessage"
|
|
40
|
+
},
|
|
41
41
|
"options_requiresVariableOverlap": {
|
|
42
42
|
"@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_options_requiresVariableOverlap"
|
|
43
43
|
},
|
package/lib/ActorRdfJoin.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { MediatorRdfJoinSelectivity } from '@comunica/bus-rdf-join-selectiv
|
|
|
3
3
|
import type { IAction, IActorArgs, Mediate, TestResult } from '@comunica/core';
|
|
4
4
|
import { Actor } from '@comunica/core';
|
|
5
5
|
import type { IMediatorTypeJoinCoefficients } from '@comunica/mediatortype-join-coefficients';
|
|
6
|
-
import type { IQueryOperationResultBindings, MetadataBindings, Bindings, IActionContext, IJoinEntry, IJoinEntryWithMetadata, ComunicaDataFactory, MetadataVariable } from '@comunica/types';
|
|
6
|
+
import type { IQueryOperationResultBindings, MetadataBindings, Bindings, IActionContext, IJoinEntry, IJoinEntryWithMetadata, ComunicaDataFactory, MetadataVariable, LogicalJoinType } from '@comunica/types';
|
|
7
7
|
import { MetadataValidationState } from '@comunica/utils-metadata';
|
|
8
8
|
import type * as RDF from '@rdfjs/types';
|
|
9
9
|
/**
|
|
@@ -197,10 +197,6 @@ export interface IActorRdfJoinInternalOptions {
|
|
|
197
197
|
*/
|
|
198
198
|
requiresVariableOverlap?: boolean;
|
|
199
199
|
}
|
|
200
|
-
/**
|
|
201
|
-
* Represents a logical join type.
|
|
202
|
-
*/
|
|
203
|
-
export type LogicalJoinType = 'inner' | 'optional' | 'minus';
|
|
204
200
|
export interface IActionRdfJoin extends IAction {
|
|
205
201
|
/**
|
|
206
202
|
* The logical join type.
|
|
@@ -225,3 +221,4 @@ export interface IActorRdfJoinTestSideData {
|
|
|
225
221
|
metadatas: MetadataBindings[];
|
|
226
222
|
}
|
|
227
223
|
export type MediatorRdfJoin = Mediate<IActionRdfJoin, IQueryOperationResultBindings, IMediatorTypeJoinCoefficients>;
|
|
224
|
+
export { LogicalJoinType } from '@comunica/types';
|
package/lib/ActorRdfJoin.js
CHANGED
|
@@ -172,15 +172,25 @@ class ActorRdfJoin extends core_1.Actor {
|
|
|
172
172
|
cardinalityJoined = partialMetadata.cardinality;
|
|
173
173
|
}
|
|
174
174
|
else {
|
|
175
|
+
let hasZeroCardinality = false;
|
|
175
176
|
cardinalityJoined = metadatas
|
|
176
177
|
.reduce((acc, metadata) => {
|
|
177
178
|
const cardinalityThis = ActorRdfJoin.getCardinality(metadata);
|
|
179
|
+
if (cardinalityThis.value === 0) {
|
|
180
|
+
hasZeroCardinality = true;
|
|
181
|
+
}
|
|
178
182
|
return {
|
|
179
183
|
type: cardinalityThis.type === 'estimate' ? 'estimate' : acc.type,
|
|
180
184
|
value: acc.value * (optional ? Math.max(1, cardinalityThis.value) : cardinalityThis.value),
|
|
181
185
|
};
|
|
182
186
|
}, { type: 'exact', value: 1 });
|
|
183
|
-
|
|
187
|
+
// The cardinality should only be zero if one of the entries has zero cardinality, not due to float overflow
|
|
188
|
+
if (!hasZeroCardinality || optional) {
|
|
189
|
+
cardinalityJoined.value *= (await this.mediatorJoinSelectivity.mediate({ entries, context })).selectivity;
|
|
190
|
+
if (cardinalityJoined.value === 0) {
|
|
191
|
+
cardinalityJoined.value = Number.MIN_VALUE;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
184
194
|
}
|
|
185
195
|
return {
|
|
186
196
|
state: this.constructState(metadatas),
|
|
@@ -227,34 +237,7 @@ class ActorRdfJoin extends core_1.Actor {
|
|
|
227
237
|
if (multiOccurrenceVariables.length === 0) {
|
|
228
238
|
return (0, core_1.failTest)(`Bind join can only join entries with at least one common variable`);
|
|
229
239
|
}
|
|
230
|
-
|
|
231
|
-
// These will be placed in the back of the sorted array
|
|
232
|
-
const entriesWithoutCommonVariables = [];
|
|
233
|
-
for (const entry of entries) {
|
|
234
|
-
let hasCommon = false;
|
|
235
|
-
for (const variable of entry.metadata.variables) {
|
|
236
|
-
if (multiOccurrenceVariables.includes(variable.variable.value)) {
|
|
237
|
-
hasCommon = true;
|
|
238
|
-
break;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
if (!hasCommon) {
|
|
242
|
-
entriesWithoutCommonVariables.push(entry);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
return (0, core_1.passTest)((await mediatorJoinEntriesSort.mediate({ entries, context })).entries
|
|
246
|
-
.sort((entryLeft, entryRight) => {
|
|
247
|
-
// Sort to make sure that entries without common variables come last in the array.
|
|
248
|
-
// For all other entries, the original order is kept.
|
|
249
|
-
const leftWithoutCommonVariables = entriesWithoutCommonVariables.includes(entryLeft);
|
|
250
|
-
const rightWithoutCommonVariables = entriesWithoutCommonVariables.includes(entryRight);
|
|
251
|
-
if (leftWithoutCommonVariables === rightWithoutCommonVariables) {
|
|
252
|
-
return 0;
|
|
253
|
-
}
|
|
254
|
-
return leftWithoutCommonVariables ?
|
|
255
|
-
1 :
|
|
256
|
-
-1;
|
|
257
|
-
}));
|
|
240
|
+
return (0, core_1.passTest)((await mediatorJoinEntriesSort.mediate({ entries, context })).entries);
|
|
258
241
|
}
|
|
259
242
|
/**
|
|
260
243
|
* Default test function for join actors.
|
package/lib/ActorRdfJoin.js.map
CHANGED
|
@@ -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, TestResult } from '@comunica/core';\nimport { passTest, failTest, Actor } from '@comunica/core';\nimport type { IMediatorTypeJoinCoefficients } from '@comunica/mediatortype-join-coefficients';\nimport type {\n IQueryOperationResultBindings,\n MetadataBindings,\n IPhysicalQueryPlanLogger,\n Bindings,\n IActionContext,\n IJoinEntry,\n IJoinEntryWithMetadata,\n ComunicaDataFactory,\n MetadataVariable,\n} from '@comunica/types';\nimport { instrumentIterator } from '@comunica/utils-iterator';\nimport { cachifyMetadata, MetadataValidationState } from '@comunica/utils-metadata';\nimport type * as RDF from '@rdfjs/types';\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<TS extends IActorRdfJoinTestSideData = IActorRdfJoinTestSideData> extends Actor<\n IActionRdfJoin,\nIMediatorTypeJoinCoefficients,\nIQueryOperationResultBindings,\nTS\n> {\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 overlapping variable 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 * If this join operator must only be used for join entries with (at least partially) common variables.\n */\n protected readonly requiresVariableOverlap?: boolean;\n\n /* eslint-disable max-len */\n /**\n * @param args -\n * \\ @defaultNested {<default_bus> a <cc:components/Bus.jsonld#Bus>} bus\n * \\ @defaultNested {RDF joining failed: none of the configured actors were able to handle the join type ${action.type}} busFailMessage\n * @param options - Actor-specific join options.\n */\n /* eslint-enable max-len */\n public constructor(args: IActorRdfJoinArgs<TS>, 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 this.requiresVariableOverlap = options.requiresVariableOverlap ?? false;\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[]): MetadataVariable[] {\n const variablesIndexed: Record<string, { variable: RDF.Variable; canBeUndef: boolean; occurrences: number }> = {};\n for (const metadata of metadatas) {\n for (const variable of metadata.variables) {\n if (!variablesIndexed[variable.variable.value]) {\n variablesIndexed[variable.variable.value] = {\n variable: variable.variable,\n canBeUndef: variable.canBeUndef,\n occurrences: 0,\n };\n }\n const entry = variablesIndexed[variable.variable.value];\n entry.canBeUndef = entry.canBeUndef || variable.canBeUndef;\n entry.occurrences++;\n }\n }\n return Object.values(variablesIndexed)\n .filter(entry => entry.occurrences === metadatas.length)\n .map(entry => ({ variable: entry.variable, canBeUndef: entry.canBeUndef }));\n }\n\n /**\n * Returns the variables that will occur in the joined bindings.\n * @param dataFactory The data factory.\n * @param {MetadataBindings[]} metadatas An array of metadata objects for the entries.\n * @param optional If an optional join is being performed.\n * @returns {RDF.Variable[]} An array of joined variables.\n */\n public static joinVariables(\n dataFactory: ComunicaDataFactory,\n metadatas: MetadataBindings[],\n optional = false,\n ): MetadataVariable[] {\n const variablesIndexed: Record<string, boolean> = {};\n let first = true;\n for (const metadata of metadatas) {\n for (const variable of metadata.variables) {\n variablesIndexed[variable.variable.value] = variablesIndexed[variable.variable.value] || variable.canBeUndef ||\n (!first && optional && !(variable.variable.value in variablesIndexed));\n }\n first = false;\n }\n return Object.entries(variablesIndexed)\n .map(([ variableLabel, canBeUndef ]) => ({ variable: dataFactory.variable(variableLabel), canBeUndef }));\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 * @param optional If metadata for an optional operation must be calculated.\n */\n public async constructResultMetadata(\n entries: IJoinEntry[],\n metadatas: MetadataBindings[],\n context: IActionContext,\n partialMetadata: Partial<MetadataBindings> = {},\n optional = false,\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 * (optional ? Math.max(1, cardinalityThis.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 variables: ActorRdfJoin.joinVariables(context.getSafe(KeysInitQuery.dataFactory), metadatas, optional),\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<TestResult<IJoinEntryWithMetadata[]>> {\n // If there is a stream that can contain undefs, we don't modify the join order.\n const hasUndefVars = entries.some(entry => entry.metadata.variables.some(variable => variable.canBeUndef));\n if (hasUndefVars) {\n return passTest(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.variable.value];\n if (!counter) {\n counter = 0;\n }\n variableOccurrences[variable.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 return failTest(`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.variable.value)) {\n hasCommon = true;\n break;\n }\n }\n if (!hasCommon) {\n entriesWithoutCommonVariables.push(entry);\n }\n }\n\n return passTest((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(\n action: IActionRdfJoin,\n ): Promise<TestResult<IMediatorTypeJoinCoefficients, TS>> {\n // Validate logical join type\n if (action.type !== this.logicalType) {\n return failTest(`${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 return failTest(`${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 return failTest(`${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 return failTest(`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 (for overlapping variables)\n let overlappingVariables: MetadataVariable[] | undefined;\n if (!this.canHandleUndefs) {\n overlappingVariables = ActorRdfJoin.overlappingVariables(metadatas);\n if (overlappingVariables.some(variable => variable.canBeUndef)) {\n return failTest(`Actor ${this.name} can not join streams containing undefs`);\n }\n }\n\n // This actor only works with common variables\n if (this.requiresVariableOverlap &&\n (overlappingVariables ?? ActorRdfJoin.overlappingVariables(metadatas)).length === 0) {\n return failTest(`Actor ${this.name} can only join entries with at least one common variable`);\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 * @param sideData Side data from the test method\n * @returns {Promise<IQueryOperationResultBindings>} A bindings result.\n */\n public async run(\n action: IActionRdfJoin,\n sideData: IActorRdfJoinTestSideData,\n ): 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, sideData);\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 = sideData.metadatas.map(ActorRdfJoin.getCardinality);\n planMetadata.cardinalities = cardinalities;\n planMetadata.joinCoefficients = (await this.getJoinCoefficients(action, sideData)).getOrThrow();\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 * @param sideData Side data from the test method\n * @returns {Promise<IActorRdfJoinOutputInner>}\n */\n protected abstract getOutput(\n action: IActionRdfJoin,\n sideData: IActorRdfJoinTestSideData,\n ): Promise<IActorRdfJoinOutputInner>;\n\n /**\n * Calculate the join coefficients.\n * @param {IActionRdfJoin} action Join action\n * @param sideData The test side data.\n * @returns {IMediatorTypeJoinCoefficients} The join coefficient estimates.\n */\n protected abstract getJoinCoefficients(\n action: IActionRdfJoin,\n sideData: IActorRdfJoinTestSideData,\n ): Promise<TestResult<IMediatorTypeJoinCoefficients, TS>>;\n}\n\nexport interface IActorRdfJoinArgs<TS extends IActorRdfJoinTestSideData = IActorRdfJoinTestSideData> extends IActorArgs<\n IActionRdfJoin,\n IMediatorTypeJoinCoefficients,\n IQueryOperationResultBindings,\n TS\n> {\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 overlapping variable 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 * If this join operator must only be used for join entries with (at least partially) common variables.\n */\n requiresVariableOverlap?: 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 interface IActorRdfJoinTestSideData {\n metadatas: MetadataBindings[];\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, TestResult } from '@comunica/core';\nimport { passTest, failTest, Actor } from '@comunica/core';\nimport type { IMediatorTypeJoinCoefficients } from '@comunica/mediatortype-join-coefficients';\nimport type {\n IQueryOperationResultBindings,\n MetadataBindings,\n IPhysicalQueryPlanLogger,\n Bindings,\n IActionContext,\n IJoinEntry,\n IJoinEntryWithMetadata,\n ComunicaDataFactory,\n MetadataVariable,\n LogicalJoinType,\n} from '@comunica/types';\nimport { instrumentIterator } from '@comunica/utils-iterator';\nimport { cachifyMetadata, MetadataValidationState } from '@comunica/utils-metadata';\nimport type * as RDF from '@rdfjs/types';\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<TS extends IActorRdfJoinTestSideData = IActorRdfJoinTestSideData> extends Actor<\n IActionRdfJoin,\nIMediatorTypeJoinCoefficients,\nIQueryOperationResultBindings,\nTS\n> {\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 overlapping variable 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 * If this join operator must only be used for join entries with (at least partially) common variables.\n */\n protected readonly requiresVariableOverlap?: boolean;\n\n /* eslint-disable max-len */\n /**\n * @param args -\n * \\ @defaultNested {<default_bus> a <cc:components/Bus.jsonld#Bus>} bus\n * \\ @defaultNested {RDF joining failed: none of the configured actors were able to handle the join type ${action.type}} busFailMessage\n * @param options - Actor-specific join options.\n */\n /* eslint-enable max-len */\n public constructor(args: IActorRdfJoinArgs<TS>, 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 this.requiresVariableOverlap = options.requiresVariableOverlap ?? false;\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[]): MetadataVariable[] {\n const variablesIndexed: Record<string, { variable: RDF.Variable; canBeUndef: boolean; occurrences: number }> = {};\n for (const metadata of metadatas) {\n for (const variable of metadata.variables) {\n if (!variablesIndexed[variable.variable.value]) {\n variablesIndexed[variable.variable.value] = {\n variable: variable.variable,\n canBeUndef: variable.canBeUndef,\n occurrences: 0,\n };\n }\n const entry = variablesIndexed[variable.variable.value];\n entry.canBeUndef = entry.canBeUndef || variable.canBeUndef;\n entry.occurrences++;\n }\n }\n return Object.values(variablesIndexed)\n .filter(entry => entry.occurrences === metadatas.length)\n .map(entry => ({ variable: entry.variable, canBeUndef: entry.canBeUndef }));\n }\n\n /**\n * Returns the variables that will occur in the joined bindings.\n * @param dataFactory The data factory.\n * @param {MetadataBindings[]} metadatas An array of metadata objects for the entries.\n * @param optional If an optional join is being performed.\n * @returns {RDF.Variable[]} An array of joined variables.\n */\n public static joinVariables(\n dataFactory: ComunicaDataFactory,\n metadatas: MetadataBindings[],\n optional = false,\n ): MetadataVariable[] {\n const variablesIndexed: Record<string, boolean> = {};\n let first = true;\n for (const metadata of metadatas) {\n for (const variable of metadata.variables) {\n variablesIndexed[variable.variable.value] = variablesIndexed[variable.variable.value] || variable.canBeUndef ||\n (!first && optional && !(variable.variable.value in variablesIndexed));\n }\n first = false;\n }\n return Object.entries(variablesIndexed)\n .map(([ variableLabel, canBeUndef ]) => ({ variable: dataFactory.variable(variableLabel), canBeUndef }));\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 * @param optional If metadata for an optional operation must be calculated.\n */\n public async constructResultMetadata(\n entries: IJoinEntry[],\n metadatas: MetadataBindings[],\n context: IActionContext,\n partialMetadata: Partial<MetadataBindings> = {},\n optional = false,\n ): Promise<MetadataBindings> {\n let cardinalityJoined: RDF.QueryResultCardinality;\n if (partialMetadata.cardinality) {\n cardinalityJoined = partialMetadata.cardinality;\n } else {\n let hasZeroCardinality = false;\n cardinalityJoined = metadatas\n .reduce((acc: RDF.QueryResultCardinality, metadata) => {\n const cardinalityThis = ActorRdfJoin.getCardinality(metadata);\n if (cardinalityThis.value === 0) {\n hasZeroCardinality = true;\n }\n return {\n type: cardinalityThis.type === 'estimate' ? 'estimate' : acc.type,\n value: acc.value * (optional ? Math.max(1, cardinalityThis.value) : cardinalityThis.value),\n };\n }, { type: 'exact', value: 1 });\n // The cardinality should only be zero if one of the entries has zero cardinality, not due to float overflow\n if (!hasZeroCardinality || optional) {\n cardinalityJoined.value *= (await this.mediatorJoinSelectivity.mediate({ entries, context })).selectivity;\n if (cardinalityJoined.value === 0) {\n cardinalityJoined.value = Number.MIN_VALUE;\n }\n }\n }\n\n return {\n state: this.constructState(metadatas),\n ...partialMetadata,\n cardinality: {\n type: cardinalityJoined.type,\n value: cardinalityJoined.value,\n },\n variables: ActorRdfJoin.joinVariables(context.getSafe(KeysInitQuery.dataFactory), metadatas, optional),\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<TestResult<IJoinEntryWithMetadata[]>> {\n // If there is a stream that can contain undefs, we don't modify the join order.\n const hasUndefVars = entries.some(entry => entry.metadata.variables.some(variable => variable.canBeUndef));\n if (hasUndefVars) {\n return passTest(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.variable.value];\n if (!counter) {\n counter = 0;\n }\n variableOccurrences[variable.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 return failTest(`Bind join can only join entries with at least one common variable`);\n }\n\n return passTest((await mediatorJoinEntriesSort.mediate({ entries, context })).entries);\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(\n action: IActionRdfJoin,\n ): Promise<TestResult<IMediatorTypeJoinCoefficients, TS>> {\n // Validate logical join type\n if (action.type !== this.logicalType) {\n return failTest(`${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 return failTest(`${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 return failTest(`${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 return failTest(`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 (for overlapping variables)\n let overlappingVariables: MetadataVariable[] | undefined;\n if (!this.canHandleUndefs) {\n overlappingVariables = ActorRdfJoin.overlappingVariables(metadatas);\n if (overlappingVariables.some(variable => variable.canBeUndef)) {\n return failTest(`Actor ${this.name} can not join streams containing undefs`);\n }\n }\n\n // This actor only works with common variables\n if (this.requiresVariableOverlap &&\n (overlappingVariables ?? ActorRdfJoin.overlappingVariables(metadatas)).length === 0) {\n return failTest(`Actor ${this.name} can only join entries with at least one common variable`);\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 * @param sideData Side data from the test method\n * @returns {Promise<IQueryOperationResultBindings>} A bindings result.\n */\n public async run(\n action: IActionRdfJoin,\n sideData: IActorRdfJoinTestSideData,\n ): 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, sideData);\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 = sideData.metadatas.map(ActorRdfJoin.getCardinality);\n planMetadata.cardinalities = cardinalities;\n planMetadata.joinCoefficients = (await this.getJoinCoefficients(action, sideData)).getOrThrow();\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 * @param sideData Side data from the test method\n * @returns {Promise<IActorRdfJoinOutputInner>}\n */\n protected abstract getOutput(\n action: IActionRdfJoin,\n sideData: IActorRdfJoinTestSideData,\n ): Promise<IActorRdfJoinOutputInner>;\n\n /**\n * Calculate the join coefficients.\n * @param {IActionRdfJoin} action Join action\n * @param sideData The test side data.\n * @returns {IMediatorTypeJoinCoefficients} The join coefficient estimates.\n */\n protected abstract getJoinCoefficients(\n action: IActionRdfJoin,\n sideData: IActorRdfJoinTestSideData,\n ): Promise<TestResult<IMediatorTypeJoinCoefficients, TS>>;\n}\n\nexport interface IActorRdfJoinArgs<TS extends IActorRdfJoinTestSideData = IActorRdfJoinTestSideData> extends IActorArgs<\n IActionRdfJoin,\n IMediatorTypeJoinCoefficients,\n IQueryOperationResultBindings,\n TS\n> {\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 overlapping variable 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 * If this join operator must only be used for join entries with (at least partially) common variables.\n */\n requiresVariableOverlap?: boolean;\n}\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 interface IActorRdfJoinTestSideData {\n metadatas: MetadataBindings[];\n}\n\nexport type MediatorRdfJoin = Mediate<IActionRdfJoin, IQueryOperationResultBindings, IMediatorTypeJoinCoefficients>;\n\n// TODO remove this in next major version\nexport { LogicalJoinType } from '@comunica/types';\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@comunica/bus-rdf-join",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "A comunica bus for rdf-join events.",
|
|
5
5
|
"lsd:module": true,
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,15 +40,15 @@
|
|
|
40
40
|
"build:components": "componentsjs-generator"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@comunica/bus-rdf-join-entries-sort": "^4.0
|
|
44
|
-
"@comunica/bus-rdf-join-selectivity": "^4.0
|
|
45
|
-
"@comunica/context-entries": "^4.0
|
|
46
|
-
"@comunica/core": "^4.0
|
|
47
|
-
"@comunica/mediatortype-join-coefficients": "^4.0
|
|
48
|
-
"@comunica/types": "^4.0
|
|
43
|
+
"@comunica/bus-rdf-join-entries-sort": "^4.1.0",
|
|
44
|
+
"@comunica/bus-rdf-join-selectivity": "^4.1.0",
|
|
45
|
+
"@comunica/context-entries": "^4.1.0",
|
|
46
|
+
"@comunica/core": "^4.1.0",
|
|
47
|
+
"@comunica/mediatortype-join-coefficients": "^4.1.0",
|
|
48
|
+
"@comunica/types": "^4.1.0",
|
|
49
49
|
"@comunica/utils-iterator": "^4.0.1",
|
|
50
|
-
"@comunica/utils-metadata": "^4.0
|
|
50
|
+
"@comunica/utils-metadata": "^4.1.0",
|
|
51
51
|
"@rdfjs/types": "*"
|
|
52
52
|
},
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "711446473d18f5fd47aa1a67e6c23582234221ec"
|
|
54
54
|
}
|