@comunica/actor-rdf-join-inner-multi-bind 3.2.0 → 3.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -39,6 +39,20 @@
39
39
  "default": "0.0001",
40
40
  "comment": "Multiplier for selectivity values"
41
41
  },
42
+ {
43
+ "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_minMaxCardinalityRatio",
44
+ "range": {
45
+ "@type": "ParameterRangeUnion",
46
+ "parameterRangeElements": [
47
+ "xsd:double",
48
+ {
49
+ "@type": "ParameterRangeUndefined"
50
+ }
51
+ ]
52
+ },
53
+ "default": "60",
54
+ "comment": "The number of times the smallest cardinality should fit in the maximum cardinality."
55
+ },
42
56
  {
43
57
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_mediatorJoinEntriesSort",
44
58
  "range": "cc:components/Mediator.jsonld#Mediator",
@@ -167,6 +181,11 @@
167
181
  "memberFieldName": "selectivityModifier",
168
182
  "range": "xsd:number"
169
183
  },
184
+ {
185
+ "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind__member_minMaxCardinalityRatio",
186
+ "memberFieldName": "minMaxCardinalityRatio",
187
+ "range": "xsd:number"
188
+ },
170
189
  {
171
190
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind__member_mediatorJoinEntriesSort",
172
191
  "memberFieldName": "mediatorJoinEntriesSort",
@@ -226,6 +245,12 @@
226
245
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_selectivityModifier"
227
246
  }
228
247
  },
248
+ {
249
+ "keyRaw": "minMaxCardinalityRatio",
250
+ "value": {
251
+ "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_minMaxCardinalityRatio"
252
+ }
253
+ },
229
254
  {
230
255
  "keyRaw": "mediatorJoinEntriesSort",
231
256
  "value": {
@@ -289,6 +314,10 @@
289
314
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#IActorRdfJoinMultiBindArgs__member_selectivityModifier",
290
315
  "memberFieldName": "selectivityModifier"
291
316
  },
317
+ {
318
+ "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#IActorRdfJoinMultiBindArgs__member_minMaxCardinalityRatio",
319
+ "memberFieldName": "minMaxCardinalityRatio"
320
+ },
292
321
  {
293
322
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#IActorRdfJoinMultiBindArgs__member_mediatorJoinEntriesSort",
294
323
  "memberFieldName": "mediatorJoinEntriesSort"
@@ -14,6 +14,9 @@
14
14
  "args_selectivityModifier": {
15
15
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_selectivityModifier"
16
16
  },
17
+ "args_minMaxCardinalityRatio": {
18
+ "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_minMaxCardinalityRatio"
19
+ },
17
20
  "args_mediatorJoinEntriesSort": {
18
21
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_mediatorJoinEntriesSort"
19
22
  },
@@ -42,6 +45,9 @@
42
45
  "selectivityModifier": {
43
46
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_selectivityModifier"
44
47
  },
48
+ "minMaxCardinalityRatio": {
49
+ "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_minMaxCardinalityRatio"
50
+ },
45
51
  "mediatorJoinEntriesSort": {
46
52
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_mediatorJoinEntriesSort"
47
53
  },
@@ -13,6 +13,7 @@ import { Factory, Algebra } from 'sparqlalgebrajs';
13
13
  export declare class ActorRdfJoinMultiBind extends ActorRdfJoin {
14
14
  readonly bindOrder: BindOrder;
15
15
  readonly selectivityModifier: number;
16
+ readonly minMaxCardinalityRatio: number;
16
17
  readonly mediatorJoinEntriesSort: MediatorRdfJoinEntriesSort;
17
18
  readonly mediatorQueryOperation: MediatorQueryOperation;
18
19
  readonly mediatorMergeBindingsContext: MediatorMergeBindingsContext;
@@ -46,6 +47,12 @@ export interface IActorRdfJoinMultiBindArgs extends IActorRdfJoinArgs {
46
47
  * @default {0.0001}
47
48
  */
48
49
  selectivityModifier: number;
50
+ /**
51
+ * The number of times the smallest cardinality should fit in the maximum cardinality.
52
+ * @range {double}
53
+ * @default {60}
54
+ */
55
+ minMaxCardinalityRatio?: number;
49
56
  /**
50
57
  * The join entries sort mediator
51
58
  */
@@ -12,6 +12,10 @@ const sparqlalgebrajs_1 = require("sparqlalgebrajs");
12
12
  */
13
13
  class ActorRdfJoinMultiBind extends bus_rdf_join_1.ActorRdfJoin {
14
14
  constructor(args) {
15
+ // TODO: remove this fallback in the next major update
16
+ if (args.minMaxCardinalityRatio === undefined) {
17
+ args.minMaxCardinalityRatio = 60;
18
+ }
15
19
  super(args, {
16
20
  logicalType: 'inner',
17
21
  physicalName: 'bind',
@@ -110,7 +114,6 @@ class ActorRdfJoinMultiBind extends bus_rdf_join_1.ActorRdfJoin {
110
114
  valid = false;
111
115
  return false;
112
116
  },
113
- // [Algebr
114
117
  });
115
118
  return valid;
116
119
  }
@@ -137,6 +140,12 @@ class ActorRdfJoinMultiBind extends bus_rdf_join_1.ActorRdfJoin {
137
140
  if (remainingEntries.some(entry => entry.operationModified)) {
138
141
  throw new Error(`Actor ${this.name} can not be used over remaining entries with modified operations`);
139
142
  }
143
+ // Only run this actor if the smallest stream is significantly smaller than the largest stream.
144
+ // We must use Math.max, because the last metadata is not necessarily the biggest, but it's the least preferred.
145
+ if (metadatas[0].cardinality.value * this.minMaxCardinalityRatio >
146
+ Math.max(...metadatas.map(metadata => metadata.cardinality.value))) {
147
+ throw new Error(`Actor ${this.name} can only run if the smallest stream is much smaller than largest stream`);
148
+ }
140
149
  // Determine selectivities of smallest entry with all other entries
141
150
  const selectivities = await Promise.all(remainingEntries
142
151
  .map(async (entry) => (await this.mediatorJoinSelectivity.mediate({
@@ -1 +1 @@
1
- {"version":3,"file":"ActorRdfJoinMultiBind.js","sourceRoot":"","sources":["ActorRdfJoinMultiBind.ts"],"names":[],"mappings":"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","sourcesContent":["import { BindingsFactory } from '@comunica/bindings-factory';\nimport type { MediatorMergeBindingsContext } from '@comunica/bus-merge-bindings-context';\nimport type { MediatorQueryOperation } from '@comunica/bus-query-operation';\nimport { ActorQueryOperation, materializeOperation } from '@comunica/bus-query-operation';\nimport type {\n IActionRdfJoin,\n IActorRdfJoinOutputInner,\n IActorRdfJoinArgs,\n} from '@comunica/bus-rdf-join';\nimport { ActorRdfJoin } from '@comunica/bus-rdf-join';\nimport type { MediatorRdfJoinEntriesSort } from '@comunica/bus-rdf-join-entries-sort';\nimport { KeysQueryOperation } from '@comunica/context-entries';\nimport type { IMediatorTypeJoinCoefficients } from '@comunica/mediatortype-join-coefficients';\nimport type { Bindings, BindingsStream, IQueryOperationResultBindings, MetadataBindings } from '@comunica/types';\nimport { MultiTransformIterator, TransformIterator, UnionIterator } from 'asynciterator';\nimport { Factory, Algebra, Util } from 'sparqlalgebrajs';\n\n/**\n * A comunica Multi-way Bind RDF Join Actor.\n */\nexport class ActorRdfJoinMultiBind extends ActorRdfJoin {\n public readonly bindOrder: BindOrder;\n public readonly selectivityModifier: number;\n public readonly mediatorJoinEntriesSort: MediatorRdfJoinEntriesSort;\n public readonly mediatorQueryOperation: MediatorQueryOperation;\n public readonly mediatorMergeBindingsContext: MediatorMergeBindingsContext;\n\n public static readonly FACTORY = new Factory();\n\n public constructor(args: IActorRdfJoinMultiBindArgs) {\n super(args, {\n logicalType: 'inner',\n physicalName: 'bind',\n canHandleUndefs: true,\n isLeaf: false,\n });\n }\n\n /**\n * Create a new bindings stream that takes every binding of the base stream\n * and binds it to the remaining patterns, evaluates those patterns, and emits all their bindings.\n *\n * @param bindOrder The order in which elements should be bound.\n * @param baseStream The base stream.\n * @param operations The operations to bind with each binding of the base stream.\n * @param operationBinder A callback to retrieve the bindings stream of bound operations.\n * @param optional If the original bindings should be emitted when the resulting bindings stream is empty.\n * @return {BindingsStream}\n */\n public static createBindStream(\n bindOrder: BindOrder,\n baseStream: BindingsStream,\n operations: Algebra.Operation[],\n operationBinder: (boundOperations: Algebra.Operation[], operationBindings: Bindings)\n => Promise<BindingsStream>,\n optional: boolean,\n bindingsFactory: BindingsFactory,\n ): BindingsStream {\n // Enable auto-start on sub-bindings during depth-first binding for best performance.\n const autoStartSubBindings = bindOrder === 'depth-first';\n\n // Create bindings function\n const binder = (bindings: Bindings): BindingsStream => {\n // We don't bind the filter because filters are always handled last,\n // and we need to avoid binding filters of sub-queries, which are to be handled first. (see spec test bind10)\n const subOperations = operations\n .map(operation => materializeOperation(operation, bindings, bindingsFactory, { bindFilter: true }));\n const bindingsMerger = (subBindings: Bindings): Bindings | undefined => subBindings.merge(bindings);\n return new TransformIterator(async() => (await operationBinder(subOperations, bindings))\n .transform({ map: bindingsMerger }), { maxBufferSize: 128, autoStart: autoStartSubBindings });\n };\n\n // Create an iterator that binds elements from the base stream in different orders\n switch (bindOrder) {\n case 'depth-first':\n return new MultiTransformIterator(baseStream, { autoStart: false, multiTransform: binder, optional });\n case 'breadth-first':\n return new UnionIterator(baseStream.transform({\n map: binder,\n optional,\n }), { autoStart: false });\n default:\n // eslint-disable-next-line ts/restrict-template-expressions\n throw new Error(`Received request for unknown bind order: ${bindOrder}`);\n }\n }\n\n public async getOutput(action: IActionRdfJoin): Promise<IActorRdfJoinOutputInner> {\n const bindingsFactory = await BindingsFactory.create(this.mediatorMergeBindingsContext, action.context);\n\n // Order the entries so we can pick the first one (usually the one with the lowest cardinality)\n const entriesUnsorted = await ActorRdfJoin.getEntriesWithMetadatas(action.entries);\n const entries = await ActorRdfJoin.sortJoinEntries(this.mediatorJoinEntriesSort, entriesUnsorted, action.context);\n\n this.logDebug(\n action.context,\n 'First entry for Bind Join: ',\n () => ({ entry: entries[0].operation, metadata: entries[0].metadata }),\n );\n\n // Close the non-smallest streams\n for (const [ i, element ] of entries.entries()) {\n if (i !== 0) {\n element.output.bindingsStream.close();\n }\n }\n\n // Take the stream with the lowest cardinality\n const smallestStream: IQueryOperationResultBindings = entries[0].output;\n const remainingEntries = [ ...entries ];\n remainingEntries.splice(0, 1);\n\n // Bind the remaining patterns for each binding in the stream\n const subContext = action.context\n .set(KeysQueryOperation.joinLeftMetadata, entries[0].metadata)\n .set(KeysQueryOperation.joinRightMetadatas, remainingEntries.map(entry => entry.metadata));\n const bindingsStream: BindingsStream = ActorRdfJoinMultiBind.createBindStream(\n this.bindOrder,\n smallestStream.bindingsStream,\n remainingEntries.map(entry => entry.operation),\n async(operations: Algebra.Operation[], operationBindings: Bindings) => {\n // Send the materialized patterns to the mediator for recursive join evaluation.\n const operation = operations.length === 1 ?\n operations[0] :\n ActorRdfJoinMultiBind.FACTORY.createJoin(operations);\n const output = ActorQueryOperation.getSafeBindings(await this.mediatorQueryOperation.mediate(\n { operation, context: subContext?.set(KeysQueryOperation.joinBindings, operationBindings) },\n ));\n return output.bindingsStream;\n },\n false,\n bindingsFactory,\n );\n\n return {\n result: {\n type: 'bindings',\n bindingsStream,\n metadata: () => this.constructResultMetadata(entries, entries.map(entry => entry.metadata), action.context),\n },\n physicalPlanMetadata: {\n bindIndex: entriesUnsorted.indexOf(entries[0]),\n bindOperation: entries[0].operation,\n bindOperationCardinality: entries[0].metadata.cardinality,\n bindOrder: this.bindOrder,\n },\n };\n }\n\n public canBindWithOperation(operation: Algebra.Operation): boolean {\n let valid = true;\n Util.recurseOperation(operation, {\n [Algebra.types.EXTEND](): boolean {\n valid = false;\n return false;\n },\n [Algebra.types.GROUP](): boolean {\n valid = false;\n return false;\n },\n // [Algebr\n });\n\n return valid;\n }\n\n public async getJoinCoefficients(\n action: IActionRdfJoin,\n metadatas: MetadataBindings[],\n ): Promise<IMediatorTypeJoinCoefficients> {\n // Order the entries so we can pick the first one (usually the one with the lowest cardinality)\n const entries = await ActorRdfJoin.sortJoinEntries(this.mediatorJoinEntriesSort, action.entries\n .map((entry, i) => ({ ...entry, metadata: metadatas[i] })), action.context);\n metadatas = entries.map(entry => entry.metadata);\n\n const requestInitialTimes = ActorRdfJoin.getRequestInitialTimes(metadatas);\n const requestItemTimes = ActorRdfJoin.getRequestItemTimes(metadatas);\n\n // Determine first stream and remaining ones\n const remainingEntries = [ ...entries ];\n const remainingRequestInitialTimes = [ ...requestInitialTimes ];\n const remainingRequestItemTimes = [ ...requestItemTimes ];\n remainingEntries.splice(0, 1);\n remainingRequestInitialTimes.splice(0, 1);\n remainingRequestItemTimes.splice(0, 1);\n\n // Reject binding on some operation types\n if (remainingEntries\n .some(entry => !this.canBindWithOperation(entry.operation))) {\n throw new Error(`Actor ${this.name} can not bind on Extend and Group operations`);\n }\n\n // Reject binding on modified operations, since using the output directly would be significantly more efficient.\n if (remainingEntries.some(entry => entry.operationModified)) {\n throw new Error(`Actor ${this.name} can not be used over remaining entries with modified operations`);\n }\n\n // Determine selectivities of smallest entry with all other entries\n const selectivities = await Promise.all(remainingEntries\n .map(async entry => (await this.mediatorJoinSelectivity.mediate({\n entries: [ entries[0], entry ],\n context: action.context,\n })).selectivity * this.selectivityModifier));\n\n // Determine coefficients for remaining entries\n const cardinalityRemaining = remainingEntries\n .map((entry, i) => entry.metadata.cardinality.value * selectivities[i])\n .reduce((sum, element) => sum + element, 0);\n const receiveInitialCostRemaining = remainingRequestInitialTimes\n .reduce((sum, element) => sum + element, 0);\n const receiveItemCostRemaining = remainingRequestItemTimes\n .reduce((sum, element) => sum + element, 0);\n\n return {\n iterations: metadatas[0].cardinality.value * cardinalityRemaining,\n persistedItems: 0,\n blockingItems: 0,\n requestTime: requestInitialTimes[0] +\n metadatas[0].cardinality.value * (\n requestItemTimes[0] +\n receiveInitialCostRemaining +\n cardinalityRemaining * receiveItemCostRemaining\n ),\n };\n }\n}\n\nexport interface IActorRdfJoinMultiBindArgs extends IActorRdfJoinArgs {\n /**\n * The order in which elements should be bound\n * @default {depth-first}\n */\n bindOrder: BindOrder;\n /**\n * Multiplier for selectivity values\n * @range {double}\n * @default {0.0001}\n */\n selectivityModifier: number;\n /**\n * The join entries sort mediator\n */\n mediatorJoinEntriesSort: MediatorRdfJoinEntriesSort;\n /**\n * The query operation mediator\n */\n mediatorQueryOperation: MediatorQueryOperation;\n /**\n * A mediator for creating binding context merge handlers\n */\n mediatorMergeBindingsContext: MediatorMergeBindingsContext;\n}\n\nexport type BindOrder = 'depth-first' | 'breadth-first';\n"]}
1
+ {"version":3,"file":"ActorRdfJoinMultiBind.js","sourceRoot":"","sources":["ActorRdfJoinMultiBind.ts"],"names":[],"mappings":"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","sourcesContent":["import { BindingsFactory } from '@comunica/bindings-factory';\nimport type { MediatorMergeBindingsContext } from '@comunica/bus-merge-bindings-context';\nimport type { MediatorQueryOperation } from '@comunica/bus-query-operation';\nimport { ActorQueryOperation, materializeOperation } from '@comunica/bus-query-operation';\nimport type {\n IActionRdfJoin,\n IActorRdfJoinOutputInner,\n IActorRdfJoinArgs,\n} from '@comunica/bus-rdf-join';\nimport { ActorRdfJoin } from '@comunica/bus-rdf-join';\nimport type { MediatorRdfJoinEntriesSort } from '@comunica/bus-rdf-join-entries-sort';\nimport { KeysQueryOperation } from '@comunica/context-entries';\nimport type { IMediatorTypeJoinCoefficients } from '@comunica/mediatortype-join-coefficients';\nimport type { Bindings, BindingsStream, IQueryOperationResultBindings, MetadataBindings } from '@comunica/types';\nimport { MultiTransformIterator, TransformIterator, UnionIterator } from 'asynciterator';\nimport { Factory, Algebra, Util } from 'sparqlalgebrajs';\n\n/**\n * A comunica Multi-way Bind RDF Join Actor.\n */\nexport class ActorRdfJoinMultiBind extends ActorRdfJoin {\n public readonly bindOrder: BindOrder;\n public readonly selectivityModifier: number;\n public readonly minMaxCardinalityRatio: number;\n public readonly mediatorJoinEntriesSort: MediatorRdfJoinEntriesSort;\n public readonly mediatorQueryOperation: MediatorQueryOperation;\n public readonly mediatorMergeBindingsContext: MediatorMergeBindingsContext;\n\n public static readonly FACTORY = new Factory();\n\n public constructor(args: IActorRdfJoinMultiBindArgs) {\n // TODO: remove this fallback in the next major update\n if (args.minMaxCardinalityRatio === undefined) {\n args.minMaxCardinalityRatio = 60;\n }\n super(args, {\n logicalType: 'inner',\n physicalName: 'bind',\n canHandleUndefs: true,\n isLeaf: false,\n });\n }\n\n /**\n * Create a new bindings stream that takes every binding of the base stream\n * and binds it to the remaining patterns, evaluates those patterns, and emits all their bindings.\n *\n * @param bindOrder The order in which elements should be bound.\n * @param baseStream The base stream.\n * @param operations The operations to bind with each binding of the base stream.\n * @param operationBinder A callback to retrieve the bindings stream of bound operations.\n * @param optional If the original bindings should be emitted when the resulting bindings stream is empty.\n * @return {BindingsStream}\n */\n public static createBindStream(\n bindOrder: BindOrder,\n baseStream: BindingsStream,\n operations: Algebra.Operation[],\n operationBinder: (boundOperations: Algebra.Operation[], operationBindings: Bindings)\n => Promise<BindingsStream>,\n optional: boolean,\n bindingsFactory: BindingsFactory,\n ): BindingsStream {\n // Enable auto-start on sub-bindings during depth-first binding for best performance.\n const autoStartSubBindings = bindOrder === 'depth-first';\n\n // Create bindings function\n const binder = (bindings: Bindings): BindingsStream => {\n // We don't bind the filter because filters are always handled last,\n // and we need to avoid binding filters of sub-queries, which are to be handled first. (see spec test bind10)\n const subOperations = operations\n .map(operation => materializeOperation(operation, bindings, bindingsFactory, { bindFilter: true }));\n const bindingsMerger = (subBindings: Bindings): Bindings | undefined => subBindings.merge(bindings);\n return new TransformIterator(async() => (await operationBinder(subOperations, bindings))\n .transform({ map: bindingsMerger }), { maxBufferSize: 128, autoStart: autoStartSubBindings });\n };\n\n // Create an iterator that binds elements from the base stream in different orders\n switch (bindOrder) {\n case 'depth-first':\n return new MultiTransformIterator(baseStream, { autoStart: false, multiTransform: binder, optional });\n case 'breadth-first':\n return new UnionIterator(baseStream.transform({\n map: binder,\n optional,\n }), { autoStart: false });\n default:\n // eslint-disable-next-line ts/restrict-template-expressions\n throw new Error(`Received request for unknown bind order: ${bindOrder}`);\n }\n }\n\n public async getOutput(action: IActionRdfJoin): Promise<IActorRdfJoinOutputInner> {\n const bindingsFactory = await BindingsFactory.create(this.mediatorMergeBindingsContext, action.context);\n\n // Order the entries so we can pick the first one (usually the one with the lowest cardinality)\n const entriesUnsorted = await ActorRdfJoin.getEntriesWithMetadatas(action.entries);\n const entries = await ActorRdfJoin.sortJoinEntries(this.mediatorJoinEntriesSort, entriesUnsorted, action.context);\n\n this.logDebug(\n action.context,\n 'First entry for Bind Join: ',\n () => ({ entry: entries[0].operation, metadata: entries[0].metadata }),\n );\n\n // Close the non-smallest streams\n for (const [ i, element ] of entries.entries()) {\n if (i !== 0) {\n element.output.bindingsStream.close();\n }\n }\n\n // Take the stream with the lowest cardinality\n const smallestStream: IQueryOperationResultBindings = entries[0].output;\n const remainingEntries = [ ...entries ];\n remainingEntries.splice(0, 1);\n\n // Bind the remaining patterns for each binding in the stream\n const subContext = action.context\n .set(KeysQueryOperation.joinLeftMetadata, entries[0].metadata)\n .set(KeysQueryOperation.joinRightMetadatas, remainingEntries.map(entry => entry.metadata));\n const bindingsStream: BindingsStream = ActorRdfJoinMultiBind.createBindStream(\n this.bindOrder,\n smallestStream.bindingsStream,\n remainingEntries.map(entry => entry.operation),\n async(operations: Algebra.Operation[], operationBindings: Bindings) => {\n // Send the materialized patterns to the mediator for recursive join evaluation.\n const operation = operations.length === 1 ?\n operations[0] :\n ActorRdfJoinMultiBind.FACTORY.createJoin(operations);\n const output = ActorQueryOperation.getSafeBindings(await this.mediatorQueryOperation.mediate(\n { operation, context: subContext?.set(KeysQueryOperation.joinBindings, operationBindings) },\n ));\n return output.bindingsStream;\n },\n false,\n bindingsFactory,\n );\n\n return {\n result: {\n type: 'bindings',\n bindingsStream,\n metadata: () => this.constructResultMetadata(entries, entries.map(entry => entry.metadata), action.context),\n },\n physicalPlanMetadata: {\n bindIndex: entriesUnsorted.indexOf(entries[0]),\n bindOperation: entries[0].operation,\n bindOperationCardinality: entries[0].metadata.cardinality,\n bindOrder: this.bindOrder,\n },\n };\n }\n\n public canBindWithOperation(operation: Algebra.Operation): boolean {\n let valid = true;\n Util.recurseOperation(operation, {\n [Algebra.types.EXTEND](): boolean {\n valid = false;\n return false;\n },\n [Algebra.types.GROUP](): boolean {\n valid = false;\n return false;\n },\n });\n\n return valid;\n }\n\n public async getJoinCoefficients(\n action: IActionRdfJoin,\n metadatas: MetadataBindings[],\n ): Promise<IMediatorTypeJoinCoefficients> {\n // Order the entries so we can pick the first one (usually the one with the lowest cardinality)\n const entries = await ActorRdfJoin.sortJoinEntries(this.mediatorJoinEntriesSort, action.entries\n .map((entry, i) => ({ ...entry, metadata: metadatas[i] })), action.context);\n metadatas = entries.map(entry => entry.metadata);\n\n const requestInitialTimes = ActorRdfJoin.getRequestInitialTimes(metadatas);\n const requestItemTimes = ActorRdfJoin.getRequestItemTimes(metadatas);\n\n // Determine first stream and remaining ones\n const remainingEntries = [ ...entries ];\n const remainingRequestInitialTimes = [ ...requestInitialTimes ];\n const remainingRequestItemTimes = [ ...requestItemTimes ];\n remainingEntries.splice(0, 1);\n remainingRequestInitialTimes.splice(0, 1);\n remainingRequestItemTimes.splice(0, 1);\n\n // Reject binding on some operation types\n if (remainingEntries\n .some(entry => !this.canBindWithOperation(entry.operation))) {\n throw new Error(`Actor ${this.name} can not bind on Extend and Group operations`);\n }\n\n // Reject binding on modified operations, since using the output directly would be significantly more efficient.\n if (remainingEntries.some(entry => entry.operationModified)) {\n throw new Error(`Actor ${this.name} can not be used over remaining entries with modified operations`);\n }\n\n // Only run this actor if the smallest stream is significantly smaller than the largest stream.\n // We must use Math.max, because the last metadata is not necessarily the biggest, but it's the least preferred.\n if (metadatas[0].cardinality.value * this.minMaxCardinalityRatio >\n Math.max(...metadatas.map(metadata => metadata.cardinality.value))) {\n throw new Error(`Actor ${this.name} can only run if the smallest stream is much smaller than largest stream`);\n }\n\n // Determine selectivities of smallest entry with all other entries\n const selectivities = await Promise.all(remainingEntries\n .map(async entry => (await this.mediatorJoinSelectivity.mediate({\n entries: [ entries[0], entry ],\n context: action.context,\n })).selectivity * this.selectivityModifier));\n\n // Determine coefficients for remaining entries\n const cardinalityRemaining = remainingEntries\n .map((entry, i) => entry.metadata.cardinality.value * selectivities[i])\n .reduce((sum, element) => sum + element, 0);\n const receiveInitialCostRemaining = remainingRequestInitialTimes\n .reduce((sum, element) => sum + element, 0);\n const receiveItemCostRemaining = remainingRequestItemTimes\n .reduce((sum, element) => sum + element, 0);\n\n return {\n iterations: metadatas[0].cardinality.value * cardinalityRemaining,\n persistedItems: 0,\n blockingItems: 0,\n requestTime: requestInitialTimes[0] +\n metadatas[0].cardinality.value * (\n requestItemTimes[0] +\n receiveInitialCostRemaining +\n cardinalityRemaining * receiveItemCostRemaining\n ),\n };\n }\n}\n\nexport interface IActorRdfJoinMultiBindArgs extends IActorRdfJoinArgs {\n /**\n * The order in which elements should be bound\n * @default {depth-first}\n */\n bindOrder: BindOrder;\n /**\n * Multiplier for selectivity values\n * @range {double}\n * @default {0.0001}\n */\n selectivityModifier: number;\n /**\n * The number of times the smallest cardinality should fit in the maximum cardinality.\n * @range {double}\n * @default {60}\n */\n minMaxCardinalityRatio?: number;\n /**\n * The join entries sort mediator\n */\n mediatorJoinEntriesSort: MediatorRdfJoinEntriesSort;\n /**\n * The query operation mediator\n */\n mediatorQueryOperation: MediatorQueryOperation;\n /**\n * A mediator for creating binding context merge handlers\n */\n mediatorMergeBindingsContext: MediatorMergeBindingsContext;\n}\n\nexport type BindOrder = 'depth-first' | 'breadth-first';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comunica/actor-rdf-join-inner-multi-bind",
3
- "version": "3.2.0",
3
+ "version": "3.2.2",
4
4
  "description": "A multi-bind rdf-join actor",
5
5
  "lsd:module": true,
6
6
  "license": "MIT",
@@ -37,16 +37,16 @@
37
37
  "build:components": "componentsjs-generator"
38
38
  },
39
39
  "dependencies": {
40
- "@comunica/bindings-factory": "^3.2.0",
41
- "@comunica/bus-merge-bindings-context": "^3.2.0",
42
- "@comunica/bus-query-operation": "^3.2.0",
43
- "@comunica/bus-rdf-join": "^3.2.0",
44
- "@comunica/bus-rdf-join-entries-sort": "^3.2.0",
45
- "@comunica/context-entries": "^3.2.0",
46
- "@comunica/mediatortype-join-coefficients": "^3.2.0",
47
- "@comunica/types": "^3.2.0",
40
+ "@comunica/bindings-factory": "^3.2.1",
41
+ "@comunica/bus-merge-bindings-context": "^3.2.1",
42
+ "@comunica/bus-query-operation": "^3.2.2",
43
+ "@comunica/bus-rdf-join": "^3.2.1",
44
+ "@comunica/bus-rdf-join-entries-sort": "^3.2.1",
45
+ "@comunica/context-entries": "^3.2.1",
46
+ "@comunica/mediatortype-join-coefficients": "^3.2.1",
47
+ "@comunica/types": "^3.2.1",
48
48
  "asynciterator": "^3.9.0",
49
- "sparqlalgebrajs": "^4.3.3"
49
+ "sparqlalgebrajs": "^4.3.7"
50
50
  },
51
- "gitHead": "87baf2afed021a254859e64b92f34d9b51c6a7db"
51
+ "gitHead": "fbcc3a81f87738633ddf69ede5ca504236f7edd9"
52
52
  }