@comunica/actor-rdf-join-optional-hash 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.
package/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright © 2017–now Ruben Taelman, Joachim Van Herwegen
4
+ Comunica Association and Ghent University – imec, Belgium
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # Comunica Optional Hash RDF Join Actor
2
+
3
+ [![npm version](https://badge.fury.io/js/%40comunica%2Factor-rdf-join-optional-hash.svg)](https://www.npmjs.com/package/@comunica/actor-rdf-join-optional-hash)
4
+
5
+ A comunica Optional Hash RDF Join Actor.
6
+
7
+ This module is part of the [Comunica framework](https://github.com/comunica/comunica),
8
+ and should only be used by [developers that want to build their own query engine](https://comunica.dev/docs/modify/).
9
+
10
+ [Click here if you just want to query with Comunica](https://comunica.dev/docs/query/).
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ $ yarn add @comunica/actor-rdf-join-optional-hash
16
+ ```
17
+
18
+ ## Configure
19
+
20
+ After installing, this package can be added to your engine's configuration as follows:
21
+ ```text
22
+ {
23
+ "@context": [
24
+ ...
25
+ "https://linkedsoftwaredependencies.org/bundles/npm/@comunica/actor-rdf-join-optional-hash/^1.0.0/components/context.jsonld"
26
+ ],
27
+ "actors": [
28
+ ...
29
+ {
30
+ "@id": "urn:comunica:default:rdf-join/actors#optional-hash",
31
+ "@type": "ActorRdfJoinOptionalHash",
32
+ "mediatorJoinSelectivity": { "@id": "urn:comunica:default:rdf-join-selectivity/mediators#main" },
33
+ "canHandleUndefs": true,
34
+ "blocking": true
35
+ }
36
+ ]
37
+ }
38
+ ```
39
+
40
+ ### Config Parameters
41
+
42
+ * `mediatorJoinSelectivity`: A mediator over the [RDF Join Selectivity bus](https://github.com/comunica/comunica/tree/master/packages/bus-rdf-join-selectivity).
43
+ * `canHandleUndefs`: If this actor can handle undefined values. If false, performance will be slightly better.
44
+ * `blocking`: If the join will block when collecting the optional stream. If true, performance will be better.
@@ -0,0 +1,205 @@
1
+ {
2
+ "@context": [
3
+ "https://linkedsoftwaredependencies.org/bundles/npm/@comunica/actor-rdf-join-optional-hash/^3.0.0/components/context.jsonld",
4
+ "https://linkedsoftwaredependencies.org/bundles/npm/@comunica/core/^3.0.0/components/context.jsonld",
5
+ "https://linkedsoftwaredependencies.org/bundles/npm/@comunica/bus-rdf-join/^3.0.0/components/context.jsonld"
6
+ ],
7
+ "@id": "npmd:@comunica/actor-rdf-join-optional-hash",
8
+ "components": [
9
+ {
10
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash",
11
+ "@type": "Class",
12
+ "requireElement": "ActorRdfJoinOptionalHash",
13
+ "extends": [
14
+ "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin"
15
+ ],
16
+ "comment": "A comunica Optional Hash RDF Join Actor.",
17
+ "parameters": [
18
+ {
19
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_canHandleUndefs",
20
+ "range": "xsd:boolean",
21
+ "comment": "If this actor can handle undefined values. If false, performance will be slightly better."
22
+ },
23
+ {
24
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_blocking",
25
+ "range": "xsd:boolean",
26
+ "comment": "If the join will block when collecting the optional stream. If true, performance will be better."
27
+ },
28
+ {
29
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_mediatorJoinSelectivity",
30
+ "range": "cc:components/Mediator.jsonld#Mediator"
31
+ },
32
+ {
33
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_name",
34
+ "range": "xsd:string",
35
+ "default": {
36
+ "@id": "rdf:subject"
37
+ },
38
+ "comment": "The name for this actor."
39
+ },
40
+ {
41
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_bus",
42
+ "range": {
43
+ "@type": "ParameterRangeGenericComponent",
44
+ "component": "cc:components/Bus.jsonld#Bus",
45
+ "genericTypeInstances": [
46
+ {
47
+ "@type": "ParameterRangeGenericComponent",
48
+ "component": "cc:components/Actor.jsonld#Actor",
49
+ "genericTypeInstances": [
50
+ {
51
+ "@type": "ParameterRangeGenericTypeReference",
52
+ "parameterRangeGenericType": "npmd:@comunica/actor-abstract-mediatyped/^3.0.0/components/ActorAbstractMediaTyped.jsonld#ActorAbstractMediaTyped__generic_I"
53
+ },
54
+ {
55
+ "@type": "ParameterRangeGenericTypeReference",
56
+ "parameterRangeGenericType": "npmd:@comunica/actor-abstract-mediatyped/^3.0.0/components/ActorAbstractMediaTyped.jsonld#ActorAbstractMediaTyped__generic_T"
57
+ },
58
+ {
59
+ "@type": "ParameterRangeGenericTypeReference",
60
+ "parameterRangeGenericType": "npmd:@comunica/actor-abstract-mediatyped/^3.0.0/components/ActorAbstractMediaTyped.jsonld#ActorAbstractMediaTyped__generic_O"
61
+ }
62
+ ]
63
+ },
64
+ {
65
+ "@type": "ParameterRangeGenericTypeReference",
66
+ "parameterRangeGenericType": "npmd:@comunica/actor-abstract-mediatyped/^3.0.0/components/ActorAbstractMediaTyped.jsonld#ActorAbstractMediaTyped__generic_I"
67
+ },
68
+ {
69
+ "@type": "ParameterRangeGenericTypeReference",
70
+ "parameterRangeGenericType": "npmd:@comunica/actor-abstract-mediatyped/^3.0.0/components/ActorAbstractMediaTyped.jsonld#ActorAbstractMediaTyped__generic_T"
71
+ },
72
+ {
73
+ "@type": "ParameterRangeGenericTypeReference",
74
+ "parameterRangeGenericType": "npmd:@comunica/actor-abstract-mediatyped/^3.0.0/components/ActorAbstractMediaTyped.jsonld#ActorAbstractMediaTyped__generic_O"
75
+ }
76
+ ]
77
+ },
78
+ "default": {
79
+ "@id": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin_default_bus",
80
+ "@type": "cc:components/Bus.jsonld#Bus"
81
+ },
82
+ "comment": "The bus this actor subscribes to."
83
+ },
84
+ {
85
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_beforeActors",
86
+ "range": {
87
+ "@type": "ParameterRangeUnion",
88
+ "parameterRangeElements": [
89
+ {
90
+ "@type": "ParameterRangeArray",
91
+ "parameterRangeValue": {
92
+ "@type": "ParameterRangeGenericComponent",
93
+ "component": "cc:components/Actor.jsonld#Actor",
94
+ "genericTypeInstances": [
95
+ {
96
+ "@type": "ParameterRangeGenericTypeReference",
97
+ "parameterRangeGenericType": "npmd:@comunica/actor-abstract-mediatyped/^3.0.0/components/ActorAbstractMediaTyped.jsonld#ActorAbstractMediaTyped__generic_I"
98
+ },
99
+ {
100
+ "@type": "ParameterRangeGenericTypeReference",
101
+ "parameterRangeGenericType": "npmd:@comunica/actor-abstract-mediatyped/^3.0.0/components/ActorAbstractMediaTyped.jsonld#ActorAbstractMediaTyped__generic_T"
102
+ },
103
+ {
104
+ "@type": "ParameterRangeGenericTypeReference",
105
+ "parameterRangeGenericType": "npmd:@comunica/actor-abstract-mediatyped/^3.0.0/components/ActorAbstractMediaTyped.jsonld#ActorAbstractMediaTyped__generic_O"
106
+ }
107
+ ]
108
+ }
109
+ },
110
+ {
111
+ "@type": "ParameterRangeUndefined"
112
+ }
113
+ ]
114
+ },
115
+ "comment": "Actor that must be registered in the bus before this actor."
116
+ }
117
+ ],
118
+ "memberFields": [
119
+ {
120
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash__member_blocking",
121
+ "memberFieldName": "blocking"
122
+ },
123
+ {
124
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash__member_constructor",
125
+ "memberFieldName": "constructor"
126
+ },
127
+ {
128
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash__member_constructIndex",
129
+ "memberFieldName": "constructIndex"
130
+ },
131
+ {
132
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash__member_getOutput",
133
+ "memberFieldName": "getOutput"
134
+ },
135
+ {
136
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash__member_getJoinCoefficients",
137
+ "memberFieldName": "getJoinCoefficients"
138
+ }
139
+ ],
140
+ "constructorArguments": [
141
+ {
142
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args__constructorArgument",
143
+ "fields": [
144
+ {
145
+ "keyRaw": "canHandleUndefs",
146
+ "value": {
147
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_canHandleUndefs"
148
+ }
149
+ },
150
+ {
151
+ "keyRaw": "blocking",
152
+ "value": {
153
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_blocking"
154
+ }
155
+ },
156
+ {
157
+ "keyRaw": "mediatorJoinSelectivity",
158
+ "value": {
159
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_mediatorJoinSelectivity"
160
+ }
161
+ },
162
+ {
163
+ "keyRaw": "name",
164
+ "value": {
165
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_name"
166
+ }
167
+ },
168
+ {
169
+ "keyRaw": "bus",
170
+ "value": {
171
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_bus"
172
+ }
173
+ },
174
+ {
175
+ "keyRaw": "beforeActors",
176
+ "value": {
177
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_beforeActors"
178
+ }
179
+ }
180
+ ]
181
+ }
182
+ ]
183
+ },
184
+ {
185
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#IActorRdfJoinOptionalHashArgs",
186
+ "@type": "AbstractClass",
187
+ "requireElement": "IActorRdfJoinOptionalHashArgs",
188
+ "extends": [
189
+ "cbrj:components/ActorRdfJoin.jsonld#IActorRdfJoinArgs"
190
+ ],
191
+ "parameters": [],
192
+ "memberFields": [
193
+ {
194
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#IActorRdfJoinOptionalHashArgs__member_canHandleUndefs",
195
+ "memberFieldName": "canHandleUndefs"
196
+ },
197
+ {
198
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#IActorRdfJoinOptionalHashArgs__member_blocking",
199
+ "memberFieldName": "blocking"
200
+ }
201
+ ],
202
+ "constructorArguments": []
203
+ }
204
+ ]
205
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "@context": [
3
+ "https://linkedsoftwaredependencies.org/bundles/npm/@comunica/actor-rdf-join-optional-hash/^3.0.0/components/context.jsonld"
4
+ ],
5
+ "@id": "npmd:@comunica/actor-rdf-join-optional-hash",
6
+ "@type": "Module",
7
+ "requireName": "@comunica/actor-rdf-join-optional-hash",
8
+ "import": [
9
+ "carjoh:components/ActorRdfJoinOptionalHash.jsonld"
10
+ ]
11
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "@context": [
3
+ "https://linkedsoftwaredependencies.org/bundles/npm/componentsjs/^6.0.0/components/context.jsonld",
4
+ {
5
+ "npmd": "https://linkedsoftwaredependencies.org/bundles/npm/",
6
+ "carjoh": "npmd:@comunica/actor-rdf-join-optional-hash/^3.0.0/",
7
+ "ActorRdfJoinOptionalHash": {
8
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash",
9
+ "@prefix": true,
10
+ "@context": {
11
+ "args_canHandleUndefs": {
12
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_canHandleUndefs"
13
+ },
14
+ "args_blocking": {
15
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_blocking"
16
+ },
17
+ "args_mediatorJoinSelectivity": {
18
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_mediatorJoinSelectivity"
19
+ },
20
+ "args_name": {
21
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_name"
22
+ },
23
+ "args_bus": {
24
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_bus"
25
+ },
26
+ "args_beforeActors": {
27
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_beforeActors",
28
+ "@container": "@list"
29
+ },
30
+ "canHandleUndefs": {
31
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_canHandleUndefs"
32
+ },
33
+ "blocking": {
34
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_blocking"
35
+ },
36
+ "mediatorJoinSelectivity": {
37
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_mediatorJoinSelectivity"
38
+ },
39
+ "name": {
40
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_name"
41
+ },
42
+ "bus": {
43
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_bus"
44
+ },
45
+ "beforeActors": {
46
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#ActorRdfJoinOptionalHash_args_beforeActors",
47
+ "@container": "@list"
48
+ }
49
+ }
50
+ },
51
+ "IActorRdfJoinOptionalHashArgs": {
52
+ "@id": "carjoh:components/ActorRdfJoinOptionalHash.jsonld#IActorRdfJoinOptionalHashArgs",
53
+ "@prefix": true,
54
+ "@context": {}
55
+ }
56
+ }
57
+ ]
58
+ }
@@ -0,0 +1,28 @@
1
+ import { ActorRdfJoin } from '@comunica/bus-rdf-join';
2
+ import type { IActionRdfJoin, IActorRdfJoinArgs, IActorRdfJoinOutputInner } from '@comunica/bus-rdf-join';
3
+ import type { IMediatorTypeJoinCoefficients } from '@comunica/mediatortype-join-coefficients';
4
+ import type { MetadataBindings } from '@comunica/types';
5
+ import type * as RDF from '@rdfjs/types';
6
+ import type { IBindingsIndex } from './IBindingsIndex';
7
+ /**
8
+ * A comunica Optional Hash RDF Join Actor.
9
+ */
10
+ export declare class ActorRdfJoinOptionalHash extends ActorRdfJoin {
11
+ private readonly blocking;
12
+ constructor(args: IActorRdfJoinOptionalHashArgs);
13
+ static constructIndex<V>(undef: boolean, commonVariables: RDF.Variable[]): IBindingsIndex<V>;
14
+ getOutput(action: IActionRdfJoin): Promise<IActorRdfJoinOutputInner>;
15
+ protected getJoinCoefficients(action: IActionRdfJoin, metadatas: MetadataBindings[]): Promise<IMediatorTypeJoinCoefficients>;
16
+ }
17
+ export interface IActorRdfJoinOptionalHashArgs extends IActorRdfJoinArgs {
18
+ /**
19
+ * If this actor can handle undefined values.
20
+ * If false, performance will be slightly better.
21
+ */
22
+ canHandleUndefs: boolean;
23
+ /**
24
+ * If the join will block when collecting the optional stream.
25
+ * If true, performance will be better.
26
+ */
27
+ blocking: boolean;
28
+ }
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActorRdfJoinOptionalHash = void 0;
4
+ const bus_query_operation_1 = require("@comunica/bus-query-operation");
5
+ const bus_rdf_join_1 = require("@comunica/bus-rdf-join");
6
+ const asynciterator_1 = require("asynciterator");
7
+ const rdf_string_1 = require("rdf-string");
8
+ const BindingsIndexDef_1 = require("./BindingsIndexDef");
9
+ const BindingsIndexUndef_1 = require("./BindingsIndexUndef");
10
+ /**
11
+ * A comunica Optional Hash RDF Join Actor.
12
+ */
13
+ class ActorRdfJoinOptionalHash extends bus_rdf_join_1.ActorRdfJoin {
14
+ constructor(args) {
15
+ super(args, {
16
+ logicalType: 'optional',
17
+ physicalName: `hash-${args.canHandleUndefs ? 'undef' : 'def'}-${args.blocking ? 'blocking' : 'nonblocking'}`,
18
+ limitEntries: 2,
19
+ canHandleUndefs: args.canHandleUndefs,
20
+ });
21
+ }
22
+ static constructIndex(undef, commonVariables) {
23
+ return undef ?
24
+ new BindingsIndexUndef_1.BindingsIndexUndef(commonVariables, (term) => term && term.termType !== 'Variable' ? (0, rdf_string_1.termToString)(term) : '') :
25
+ new BindingsIndexDef_1.BindingsIndexDef(commonVariables, bus_rdf_join_1.ActorRdfJoin.hashNonClashing);
26
+ }
27
+ async getOutput(action) {
28
+ const buffer = action.entries[1].output;
29
+ const output = action.entries[0].output;
30
+ const metadatas = await bus_rdf_join_1.ActorRdfJoin.getMetadatas(action.entries);
31
+ const commonVariables = bus_rdf_join_1.ActorRdfJoin.overlappingVariables(metadatas);
32
+ let bindingsStream;
33
+ if (this.blocking) {
34
+ // -- Blocking optional ---
35
+ bindingsStream = new bus_query_operation_1.ClosableTransformIterator(async () => {
36
+ // We index all bindings from the right-hand OPTIONAL iterator first in a blocking manner.
37
+ const index = ActorRdfJoinOptionalHash
38
+ .constructIndex(this.canHandleUndefs, commonVariables);
39
+ await new Promise((resolve) => {
40
+ buffer.bindingsStream.on('data', (bindings) => {
41
+ const iterator = index.getFirst(bindings) ?? index.put(bindings, []);
42
+ iterator.push(bindings);
43
+ });
44
+ buffer.bindingsStream.on('end', resolve);
45
+ buffer.bindingsStream.on('error', (error) => {
46
+ bindingsStream.emit('error', error);
47
+ });
48
+ });
49
+ // Start our left-hand iterator and try to join with the index
50
+ return new asynciterator_1.MultiTransformIterator(output.bindingsStream, {
51
+ multiTransform: (bindings) => new asynciterator_1.ArrayIterator((index.get(bindings).flat())
52
+ .map(indexBindings => bus_rdf_join_1.ActorRdfJoin.joinBindings(bindings, indexBindings))
53
+ .filter(b => b !== null), { autoStart: false }),
54
+ optional: true,
55
+ autoStart: false,
56
+ });
57
+ }, {
58
+ autoStart: false,
59
+ onClose() {
60
+ buffer.bindingsStream.destroy();
61
+ output.bindingsStream.destroy();
62
+ },
63
+ });
64
+ }
65
+ else {
66
+ // -- Non-blocking optional ---
67
+ // This can be slightly slower than the blocking one above, due to the streaming overhead.
68
+ bindingsStream = new bus_query_operation_1.ClosableTransformIterator(async () => {
69
+ // We index all bindings from the right-hand OPTIONAL iterator.
70
+ // They are indexed with iterator values, so our main stream can already get started.
71
+ const index = ActorRdfJoinOptionalHash
72
+ .constructIndex(this.canHandleUndefs, commonVariables);
73
+ let indexActive = true;
74
+ buffer.bindingsStream.on('data', (bindings) => {
75
+ const iterator = index.getFirst(bindings) ??
76
+ index.put(bindings, new asynciterator_1.BufferedIterator({ autoStart: false }));
77
+ iterator._push(bindings);
78
+ });
79
+ buffer.bindingsStream.on('end', () => {
80
+ for (const iterator of index.values()) {
81
+ iterator.close();
82
+ }
83
+ indexActive = false;
84
+ });
85
+ buffer.bindingsStream.on('error', (error) => {
86
+ bindingsStream.emit('error', error);
87
+ });
88
+ // Start our left-hand iterator and try to join with the index
89
+ return new asynciterator_1.MultiTransformIterator(output.bindingsStream, {
90
+ multiTransform: (bindings) => {
91
+ // Find iterators from the index
92
+ let iterators = index.get(bindings);
93
+ // If no index entry was found, set an empty iterator.
94
+ // If we index has been closed already, don't modify the index, but just use an empty dummy iterator.
95
+ if (iterators.length === 0) {
96
+ if (indexActive) {
97
+ iterators = [index.put(bindings, new asynciterator_1.BufferedIterator({ autoStart: false }))];
98
+ }
99
+ else {
100
+ iterators = [];
101
+ }
102
+ }
103
+ // Merge all iterators in a single one,
104
+ // and clone each one to make sure we can still use them in the future.
105
+ const iterator = new asynciterator_1.UnionIterator(iterators.map(it => it.clone()), { autoStart: false });
106
+ return iterator.map(indexBindings => bus_rdf_join_1.ActorRdfJoin.joinBindings(bindings, indexBindings));
107
+ },
108
+ optional: true,
109
+ autoStart: false,
110
+ });
111
+ }, {
112
+ autoStart: false,
113
+ onClose() {
114
+ buffer.bindingsStream.destroy();
115
+ output.bindingsStream.destroy();
116
+ },
117
+ });
118
+ }
119
+ return {
120
+ result: {
121
+ type: 'bindings',
122
+ bindingsStream,
123
+ metadata: async () => await this.constructResultMetadata(action.entries, await bus_rdf_join_1.ActorRdfJoin.getMetadatas(action.entries), action.context, { canContainUndefs: true }),
124
+ },
125
+ };
126
+ }
127
+ async getJoinCoefficients(action, metadatas) {
128
+ // This actor only works with common variables
129
+ if (bus_rdf_join_1.ActorRdfJoin.overlappingVariables(metadatas).length === 0) {
130
+ throw new Error(`Actor ${this.name} only join entries with at least one common variable`);
131
+ }
132
+ const requestInitialTimes = bus_rdf_join_1.ActorRdfJoin.getRequestInitialTimes(metadatas);
133
+ const requestItemTimes = bus_rdf_join_1.ActorRdfJoin.getRequestItemTimes(metadatas);
134
+ let iterations = metadatas[0].cardinality.value + metadatas[1].cardinality.value;
135
+ if (!this.canHandleUndefs) {
136
+ // Our non-undef implementation is slightly more performant.
137
+ iterations *= 0.8;
138
+ }
139
+ if (this.blocking) {
140
+ // Our blocking implementation is slightly more performant.
141
+ iterations *= 0.9;
142
+ }
143
+ return {
144
+ iterations,
145
+ persistedItems: metadatas[0].cardinality.value,
146
+ blockingItems: this.blocking ? metadatas[0].cardinality.value : 0,
147
+ requestTime: requestInitialTimes[0] + metadatas[0].cardinality.value * requestItemTimes[0] +
148
+ requestInitialTimes[1] + metadatas[1].cardinality.value * requestItemTimes[1],
149
+ };
150
+ }
151
+ }
152
+ exports.ActorRdfJoinOptionalHash = ActorRdfJoinOptionalHash;
153
+ //# sourceMappingURL=ActorRdfJoinOptionalHash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActorRdfJoinOptionalHash.js","sourceRoot":"","sources":["ActorRdfJoinOptionalHash.ts"],"names":[],"mappings":"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","sourcesContent":["import { ClosableTransformIterator } from '@comunica/bus-query-operation';\nimport { ActorRdfJoin } from '@comunica/bus-rdf-join';\nimport type {\n IActionRdfJoin,\n IActorRdfJoinArgs,\n IActorRdfJoinOutputInner,\n} from '@comunica/bus-rdf-join';\nimport type { IMediatorTypeJoinCoefficients } from '@comunica/mediatortype-join-coefficients';\nimport type { BindingsStream, MetadataBindings } from '@comunica/types';\nimport type * as RDF from '@rdfjs/types';\nimport type { AsyncIterator } from 'asynciterator';\nimport { UnionIterator, ArrayIterator, MultiTransformIterator, BufferedIterator } from 'asynciterator';\nimport { termToString } from 'rdf-string';\nimport { BindingsIndexDef } from './BindingsIndexDef';\nimport { BindingsIndexUndef } from './BindingsIndexUndef';\nimport type { IBindingsIndex } from './IBindingsIndex';\n\n/**\n * A comunica Optional Hash RDF Join Actor.\n */\nexport class ActorRdfJoinOptionalHash extends ActorRdfJoin {\n private readonly blocking: boolean;\n\n public constructor(args: IActorRdfJoinOptionalHashArgs) {\n super(args, {\n logicalType: 'optional',\n physicalName: `hash-${args.canHandleUndefs ? 'undef' : 'def'}-${args.blocking ? 'blocking' : 'nonblocking'}`,\n limitEntries: 2,\n canHandleUndefs: args.canHandleUndefs,\n });\n }\n\n public static constructIndex<V>(undef: boolean, commonVariables: RDF.Variable[]): IBindingsIndex<V> {\n return undef ?\n new BindingsIndexUndef(\n commonVariables,\n (term: RDF.Term | undefined) => term && term.termType !== 'Variable' ? termToString(term) : '',\n ) :\n new BindingsIndexDef(commonVariables, ActorRdfJoin.hashNonClashing);\n }\n\n public async getOutput(action: IActionRdfJoin): Promise<IActorRdfJoinOutputInner> {\n const buffer = action.entries[1].output;\n const output = action.entries[0].output;\n\n const metadatas = await ActorRdfJoin.getMetadatas(action.entries);\n const commonVariables: RDF.Variable[] = ActorRdfJoin.overlappingVariables(metadatas);\n\n let bindingsStream: BindingsStream;\n if (this.blocking) {\n // -- Blocking optional ---\n\n bindingsStream = new ClosableTransformIterator(async() => {\n // We index all bindings from the right-hand OPTIONAL iterator first in a blocking manner.\n const index: IBindingsIndex<RDF.Bindings[]> = ActorRdfJoinOptionalHash\n .constructIndex(this.canHandleUndefs, commonVariables);\n await new Promise((resolve) => {\n buffer.bindingsStream.on('data', (bindings) => {\n const iterator = index.getFirst(bindings) ?? index.put(bindings, []);\n iterator.push(bindings);\n });\n buffer.bindingsStream.on('end', resolve);\n buffer.bindingsStream.on('error', (error) => {\n bindingsStream.emit('error', error);\n });\n });\n\n // Start our left-hand iterator and try to join with the index\n return new MultiTransformIterator(\n output.bindingsStream,\n {\n multiTransform: (bindings: RDF.Bindings): AsyncIterator<RDF.Bindings> => new ArrayIterator<RDF.Bindings>(\n <RDF.Bindings[]>(index.get(bindings).flat())\n .map(indexBindings => ActorRdfJoin.joinBindings(bindings, indexBindings))\n .filter(b => b !== null),\n { autoStart: false },\n ),\n optional: true,\n autoStart: false,\n },\n );\n }, {\n autoStart: false,\n onClose() {\n buffer.bindingsStream.destroy();\n output.bindingsStream.destroy();\n },\n });\n } else {\n // -- Non-blocking optional ---\n // This can be slightly slower than the blocking one above, due to the streaming overhead.\n\n bindingsStream = new ClosableTransformIterator(async() => {\n // We index all bindings from the right-hand OPTIONAL iterator.\n // They are indexed with iterator values, so our main stream can already get started.\n const index: IBindingsIndex<BufferedIterator<RDF.Bindings>> = ActorRdfJoinOptionalHash\n .constructIndex(this.canHandleUndefs, commonVariables);\n let indexActive = true;\n buffer.bindingsStream.on('data', (bindings) => {\n const iterator = index.getFirst(bindings) ??\n index.put(bindings, new BufferedIterator<RDF.Bindings>({ autoStart: false }));\n (<any> iterator)._push(bindings);\n });\n buffer.bindingsStream.on('end', () => {\n for (const iterator of index.values()) {\n iterator.close();\n }\n indexActive = false;\n });\n buffer.bindingsStream.on('error', (error) => {\n bindingsStream.emit('error', error);\n });\n\n // Start our left-hand iterator and try to join with the index\n return new MultiTransformIterator(\n output.bindingsStream,\n {\n multiTransform: (bindings: RDF.Bindings): AsyncIterator<RDF.Bindings> => {\n // Find iterators from the index\n let iterators: AsyncIterator<RDF.Bindings>[] = index.get(bindings);\n\n // If no index entry was found, set an empty iterator.\n // If we index has been closed already, don't modify the index, but just use an empty dummy iterator.\n if (iterators.length === 0) {\n if (indexActive) {\n iterators = [ index.put(bindings, new BufferedIterator<RDF.Bindings>({ autoStart: false })) ];\n } else {\n iterators = [];\n }\n }\n\n // Merge all iterators in a single one,\n // and clone each one to make sure we can still use them in the future.\n const iterator = new UnionIterator<RDF.Bindings>(iterators.map(it => it.clone()), { autoStart: false });\n return iterator.map(indexBindings => ActorRdfJoin.joinBindings(bindings, indexBindings));\n },\n optional: true,\n autoStart: false,\n },\n );\n }, {\n autoStart: false,\n onClose() {\n buffer.bindingsStream.destroy();\n output.bindingsStream.destroy();\n },\n });\n }\n\n return {\n result: {\n type: 'bindings',\n bindingsStream,\n metadata: async() => await this.constructResultMetadata(\n action.entries,\n await ActorRdfJoin.getMetadatas(action.entries),\n action.context,\n { canContainUndefs: true },\n ),\n },\n };\n }\n\n protected async getJoinCoefficients(\n action: IActionRdfJoin,\n metadatas: MetadataBindings[],\n ): Promise<IMediatorTypeJoinCoefficients> {\n // This actor only works with common variables\n if (ActorRdfJoin.overlappingVariables(metadatas).length === 0) {\n throw new Error(`Actor ${this.name} only join entries with at least one common variable`);\n }\n\n const requestInitialTimes = ActorRdfJoin.getRequestInitialTimes(metadatas);\n const requestItemTimes = ActorRdfJoin.getRequestItemTimes(metadatas);\n let iterations = metadatas[0].cardinality.value + metadatas[1].cardinality.value;\n if (!this.canHandleUndefs) {\n // Our non-undef implementation is slightly more performant.\n iterations *= 0.8;\n }\n if (this.blocking) {\n // Our blocking implementation is slightly more performant.\n iterations *= 0.9;\n }\n return {\n iterations,\n persistedItems: metadatas[0].cardinality.value,\n blockingItems: this.blocking ? metadatas[0].cardinality.value : 0,\n requestTime: requestInitialTimes[0] + metadatas[0].cardinality.value * requestItemTimes[0] +\n requestInitialTimes[1] + metadatas[1].cardinality.value * requestItemTimes[1],\n };\n }\n}\n\nexport interface IActorRdfJoinOptionalHashArgs extends IActorRdfJoinArgs {\n /**\n * If this actor can handle undefined values.\n * If false, performance will be slightly better.\n */\n canHandleUndefs: boolean;\n /**\n * If the join will block when collecting the optional stream.\n * If true, performance will be better.\n */\n blocking: boolean;\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import type * as RDF from '@rdfjs/types';
2
+ import type { IBindingsIndex } from './IBindingsIndex';
3
+ /**
4
+ * A simple efficient hash-based index for maintaining bindings,
5
+ * and checking whether or not a bindings is contained in this index.
6
+ *
7
+ * This can not handle bindings with undefined values.
8
+ */
9
+ export declare class BindingsIndexDef<V> implements IBindingsIndex<V> {
10
+ private readonly keys;
11
+ private readonly hashFn;
12
+ private readonly index;
13
+ constructor(keys: RDF.Variable[], hashFn: (term: RDF.Bindings, keys: RDF.Variable[]) => string);
14
+ put(bindings: RDF.Bindings, value: V): V;
15
+ get(bindings: RDF.Bindings): V[];
16
+ getFirst(bindings: RDF.Bindings): V | undefined;
17
+ values(): V[];
18
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BindingsIndexDef = void 0;
4
+ /**
5
+ * A simple efficient hash-based index for maintaining bindings,
6
+ * and checking whether or not a bindings is contained in this index.
7
+ *
8
+ * This can not handle bindings with undefined values.
9
+ */
10
+ class BindingsIndexDef {
11
+ constructor(keys, hashFn) {
12
+ this.keys = keys;
13
+ this.hashFn = hashFn;
14
+ this.index = {};
15
+ }
16
+ put(bindings, value) {
17
+ return this.index[this.hashFn(bindings, this.keys)] = value;
18
+ }
19
+ get(bindings) {
20
+ const v = this.getFirst(bindings);
21
+ return v ? [v] : [];
22
+ }
23
+ getFirst(bindings) {
24
+ return this.index[this.hashFn(bindings, this.keys)];
25
+ }
26
+ values() {
27
+ return Object.values(this.index);
28
+ }
29
+ }
30
+ exports.BindingsIndexDef = BindingsIndexDef;
31
+ //# sourceMappingURL=BindingsIndexDef.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BindingsIndexDef.js","sourceRoot":"","sources":["BindingsIndexDef.ts"],"names":[],"mappings":";;;AAGA;;;;;GAKG;AACH,MAAa,gBAAgB;IAK3B,YAAmB,IAAoB,EAAE,MAA4D;QACnG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;IAEM,GAAG,CAAC,QAAsB,EAAE,KAAQ;QACzC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC;IAC9D,CAAC;IAEM,GAAG,CAAC,QAAsB;QAC/B,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxB,CAAC;IAEM,QAAQ,CAAC,QAAsB;QACpC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACtD,CAAC;IAEM,MAAM;QACX,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;CACF;AA3BD,4CA2BC","sourcesContent":["import type * as RDF from '@rdfjs/types';\nimport type { IBindingsIndex } from './IBindingsIndex';\n\n/**\n * A simple efficient hash-based index for maintaining bindings,\n * and checking whether or not a bindings is contained in this index.\n *\n * This can not handle bindings with undefined values.\n */\nexport class BindingsIndexDef<V> implements IBindingsIndex<V> {\n private readonly keys: RDF.Variable[];\n private readonly hashFn: (term: RDF.Bindings, keys: RDF.Variable[]) => string;\n private readonly index: Record<string, V>;\n\n public constructor(keys: RDF.Variable[], hashFn: (term: RDF.Bindings, keys: RDF.Variable[]) => string) {\n this.keys = keys;\n this.hashFn = hashFn;\n this.index = {};\n }\n\n public put(bindings: RDF.Bindings, value: V): V {\n return this.index[this.hashFn(bindings, this.keys)] = value;\n }\n\n public get(bindings: RDF.Bindings): V[] {\n const v = this.getFirst(bindings);\n return v ? [ v ] : [];\n }\n\n public getFirst(bindings: RDF.Bindings): V | undefined {\n return this.index[this.hashFn(bindings, this.keys)];\n }\n\n public values(): V[] {\n return Object.values(this.index);\n }\n}\n"]}
@@ -0,0 +1,41 @@
1
+ import type { Bindings } from '@comunica/types';
2
+ import type * as RDF from '@rdfjs/types';
3
+ import type { IBindingsIndex } from './IBindingsIndex';
4
+ /**
5
+ * A simple efficient tree-based index for maintaining bindings,
6
+ * and checking whether or not a bindings is contained in this index.
7
+ *
8
+ * This will consider bindings with a variable term or an undefined term
9
+ * as a 'match-all' with other terms.
10
+ */
11
+ export declare class BindingsIndexUndef<V> implements IBindingsIndex<V> {
12
+ private readonly keys;
13
+ private readonly data;
14
+ private readonly hashFn;
15
+ constructor(keys: RDF.Variable[], hashFn: (term: RDF.Term | undefined) => string);
16
+ /**
17
+ * Add the given bindings to the index.
18
+ * @param {Bindings} bindings A bindings.
19
+ * @param {V} value The value to put.
20
+ */
21
+ put(bindings: Bindings, value: V): V;
22
+ protected isBindingsValid(bindings: Bindings): boolean;
23
+ /**
24
+ * Get the value of the given bindings is contained in this index.
25
+ * @param {Bindings} bindings A bindings.
26
+ * @return {V[]} The values.
27
+ */
28
+ get(bindings: Bindings): V[];
29
+ protected getRecursive(bindings: Bindings | undefined, keys: RDF.Variable[], dataIndexes: IDataIndex<V>[]): V[];
30
+ /**
31
+ * Get the first value of the given bindings is contained in this index.
32
+ * @param {Bindings} bindings A bindings.
33
+ * @return {V | undefined} The value.
34
+ */
35
+ getFirst(bindings: Bindings): V | undefined;
36
+ protected getRecursiveFirst(bindings: Bindings, keys: RDF.Variable[], dataIndexes: IDataIndex<V>[]): V | undefined;
37
+ values(): V[];
38
+ }
39
+ export interface IDataIndex<V> {
40
+ [key: string]: IDataIndex<V> | V;
41
+ }
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BindingsIndexUndef = void 0;
4
+ /**
5
+ * A simple efficient tree-based index for maintaining bindings,
6
+ * and checking whether or not a bindings is contained in this index.
7
+ *
8
+ * This will consider bindings with a variable term or an undefined term
9
+ * as a 'match-all' with other terms.
10
+ */
11
+ class BindingsIndexUndef {
12
+ constructor(keys, hashFn) {
13
+ this.data = {};
14
+ this.keys = keys;
15
+ this.hashFn = hashFn;
16
+ }
17
+ /**
18
+ * Add the given bindings to the index.
19
+ * @param {Bindings} bindings A bindings.
20
+ * @param {V} value The value to put.
21
+ */
22
+ put(bindings, value) {
23
+ if (this.isBindingsValid(bindings)) {
24
+ let dataIt = this.data;
25
+ for (let i = 0; i < this.keys.length; i++) {
26
+ const key = this.keys[i];
27
+ const dataKey = this.hashFn(bindings.get(key));
28
+ let subDataIt = dataIt[dataKey];
29
+ if (!subDataIt) {
30
+ subDataIt = dataIt[dataKey] = i === this.keys.length - 1 ? value : {};
31
+ }
32
+ dataIt = subDataIt;
33
+ }
34
+ }
35
+ return value;
36
+ }
37
+ isBindingsValid(bindings) {
38
+ let validKeys = false;
39
+ for (const key of this.keys) {
40
+ if (bindings.has(key)) {
41
+ validKeys = true;
42
+ break;
43
+ }
44
+ }
45
+ return validKeys;
46
+ }
47
+ /**
48
+ * Get the value of the given bindings is contained in this index.
49
+ * @param {Bindings} bindings A bindings.
50
+ * @return {V[]} The values.
51
+ */
52
+ get(bindings) {
53
+ // Always return undefined if the bindings contain none of the expected keys
54
+ if (!this.isBindingsValid(bindings)) {
55
+ return [];
56
+ }
57
+ return this.getRecursive(bindings, this.keys, [this.data]);
58
+ }
59
+ getRecursive(bindings, keys, dataIndexes) {
60
+ if (keys.length === 0) {
61
+ return dataIndexes;
62
+ }
63
+ let key;
64
+ // eslint-disable-next-line prefer-const
65
+ [key, ...keys] = keys;
66
+ const matchingRecursive = [];
67
+ for (const data of dataIndexes) {
68
+ // If the index contained a variable, all terms will match.
69
+ const dataKey = this.hashFn(bindings?.get(key));
70
+ if (dataKey) {
71
+ // Check the entry for the term, and the variable term.
72
+ const subDatas = [data[dataKey], data['']].filter(Boolean);
73
+ if (subDatas.length === 0) {
74
+ continue;
75
+ }
76
+ matchingRecursive.push(this.getRecursive(bindings, keys, subDatas));
77
+ }
78
+ else {
79
+ // Iterate over all entries
80
+ const subDatas = Object.values(data);
81
+ if (subDatas.length === 0) {
82
+ continue;
83
+ }
84
+ matchingRecursive.push(this.getRecursive(bindings, keys, subDatas));
85
+ }
86
+ }
87
+ return matchingRecursive.flat();
88
+ }
89
+ /**
90
+ * Get the first value of the given bindings is contained in this index.
91
+ * @param {Bindings} bindings A bindings.
92
+ * @return {V | undefined} The value.
93
+ */
94
+ getFirst(bindings) {
95
+ // Always return undefined if the bindings contain none of the expected keys
96
+ if (!this.isBindingsValid(bindings)) {
97
+ return undefined;
98
+ }
99
+ return this.getRecursiveFirst(bindings, this.keys, [this.data]);
100
+ }
101
+ getRecursiveFirst(bindings, keys, dataIndexes) {
102
+ if (keys.length === 0) {
103
+ return dataIndexes[0];
104
+ }
105
+ let key;
106
+ // eslint-disable-next-line prefer-const
107
+ [key, ...keys] = keys;
108
+ for (const data of dataIndexes) {
109
+ // If the index contained a variable, all terms will match.
110
+ const dataKey = this.hashFn(bindings.get(key));
111
+ if (dataKey) {
112
+ // Check the entry for the term, and the variable term.
113
+ const subDatas = [data[dataKey], data['']].filter(Boolean);
114
+ if (subDatas.length === 0) {
115
+ continue;
116
+ }
117
+ const ret = this.getRecursiveFirst(bindings, keys, subDatas);
118
+ if (ret) {
119
+ return ret;
120
+ }
121
+ }
122
+ else {
123
+ // Iterate over all entries
124
+ const subDatas = Object.values(data);
125
+ if (subDatas.length === 0) {
126
+ continue;
127
+ }
128
+ const ret = this.getRecursiveFirst(bindings, keys, subDatas);
129
+ if (ret) {
130
+ return ret;
131
+ }
132
+ }
133
+ }
134
+ return undefined;
135
+ }
136
+ values() {
137
+ return this.keys.length === 0 ? [] : this.getRecursive(undefined, this.keys, [this.data]);
138
+ }
139
+ }
140
+ exports.BindingsIndexUndef = BindingsIndexUndef;
141
+ //# sourceMappingURL=BindingsIndexUndef.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BindingsIndexUndef.js","sourceRoot":"","sources":["BindingsIndexUndef.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Bindings } from '@comunica/types';\nimport type * as RDF from '@rdfjs/types';\nimport type { IBindingsIndex } from './IBindingsIndex';\n\n/**\n * A simple efficient tree-based index for maintaining bindings,\n * and checking whether or not a bindings is contained in this index.\n *\n * This will consider bindings with a variable term or an undefined term\n * as a 'match-all' with other terms.\n */\nexport class BindingsIndexUndef<V> implements IBindingsIndex<V> {\n private readonly keys: RDF.Variable[];\n private readonly data: IDataIndex<V> = {};\n private readonly hashFn: (term: RDF.Term | undefined) => string;\n\n public constructor(keys: RDF.Variable[], hashFn: (term: RDF.Term | undefined) => string) {\n this.keys = keys;\n this.hashFn = hashFn;\n }\n\n /**\n * Add the given bindings to the index.\n * @param {Bindings} bindings A bindings.\n * @param {V} value The value to put.\n */\n public put(bindings: Bindings, value: V): V {\n if (this.isBindingsValid(bindings)) {\n let dataIt: IDataIndex<V> | V = this.data;\n for (let i = 0; i < this.keys.length; i++) {\n const key = this.keys[i];\n const dataKey = this.hashFn(bindings.get(key));\n let subDataIt: IDataIndex<V> | V | undefined = (<IDataIndex<V>> dataIt)[dataKey];\n if (!subDataIt) {\n subDataIt = ((<IDataIndex<V>> dataIt))[dataKey] = i === this.keys.length - 1 ? value : {};\n }\n dataIt = subDataIt;\n }\n }\n return value;\n }\n\n protected isBindingsValid(bindings: Bindings): boolean {\n let validKeys = false;\n for (const key of this.keys) {\n if (bindings.has(key)) {\n validKeys = true;\n break;\n }\n }\n return validKeys;\n }\n\n /**\n * Get the value of the given bindings is contained in this index.\n * @param {Bindings} bindings A bindings.\n * @return {V[]} The values.\n */\n public get(bindings: Bindings): V[] {\n // Always return undefined if the bindings contain none of the expected keys\n if (!this.isBindingsValid(bindings)) {\n return [];\n }\n\n return this.getRecursive(bindings, this.keys, [ this.data ]);\n }\n\n protected getRecursive(bindings: Bindings | undefined, keys: RDF.Variable[], dataIndexes: IDataIndex<V>[]): V[] {\n if (keys.length === 0) {\n return <V[]> dataIndexes;\n }\n\n let key: RDF.Variable;\n // eslint-disable-next-line prefer-const\n [ key, ...keys ] = keys;\n const matchingRecursive: V[][] = [];\n for (const data of dataIndexes) {\n // If the index contained a variable, all terms will match.\n const dataKey = this.hashFn(bindings?.get(key));\n if (dataKey) {\n // Check the entry for the term, and the variable term.\n const subDatas = <IDataIndex<V>[]> [ data[dataKey], data[''] ].filter(Boolean);\n if (subDatas.length === 0) {\n continue;\n }\n matchingRecursive.push(this.getRecursive(bindings, keys, subDatas));\n } else {\n // Iterate over all entries\n const subDatas = <IDataIndex<V>[]> Object.values(data);\n if (subDatas.length === 0) {\n continue;\n }\n matchingRecursive.push(this.getRecursive(bindings, keys, subDatas));\n }\n }\n return matchingRecursive.flat();\n }\n\n /**\n * Get the first value of the given bindings is contained in this index.\n * @param {Bindings} bindings A bindings.\n * @return {V | undefined} The value.\n */\n public getFirst(bindings: Bindings): V | undefined {\n // Always return undefined if the bindings contain none of the expected keys\n if (!this.isBindingsValid(bindings)) {\n return undefined;\n }\n\n return this.getRecursiveFirst(bindings, this.keys, [ this.data ]);\n }\n\n protected getRecursiveFirst(bindings: Bindings, keys: RDF.Variable[], dataIndexes: IDataIndex<V>[]): V | undefined {\n if (keys.length === 0) {\n return <V> dataIndexes[0];\n }\n\n let key: RDF.Variable;\n // eslint-disable-next-line prefer-const\n [ key, ...keys ] = keys;\n for (const data of dataIndexes) {\n // If the index contained a variable, all terms will match.\n const dataKey = this.hashFn(bindings.get(key));\n if (dataKey) {\n // Check the entry for the term, and the variable term.\n const subDatas = <IDataIndex<V>[]> [ data[dataKey], data[''] ].filter(Boolean);\n if (subDatas.length === 0) {\n continue;\n }\n const ret = this.getRecursiveFirst(bindings, keys, subDatas);\n if (ret) {\n return ret;\n }\n } else {\n // Iterate over all entries\n const subDatas = <IDataIndex<V>[]> Object.values(data);\n if (subDatas.length === 0) {\n continue;\n }\n const ret = this.getRecursiveFirst(bindings, keys, subDatas);\n if (ret) {\n return ret;\n }\n }\n }\n return undefined;\n }\n\n public values(): V[] {\n return this.keys.length === 0 ? [] : this.getRecursive(undefined, this.keys, [ this.data ]);\n }\n}\n\nexport interface IDataIndex<V> {\n [key: string]: IDataIndex<V> | V;\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import type { Bindings } from '@comunica/types';
2
+ /**
3
+ * An index for mapping bindings to values.
4
+ */
5
+ export interface IBindingsIndex<V> {
6
+ put: (bindings: Bindings, value: V) => V;
7
+ get: (bindings: Bindings) => V[];
8
+ getFirst: (bindings: Bindings) => V | undefined;
9
+ values: () => V[];
10
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=IBindingsIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IBindingsIndex.js","sourceRoot":"","sources":["IBindingsIndex.ts"],"names":[],"mappings":"","sourcesContent":["import type { Bindings } from '@comunica/types';\n\n/**\n * An index for mapping bindings to values.\n */\nexport interface IBindingsIndex<V> {\n put: (bindings: Bindings, value: V) => V;\n get: (bindings: Bindings) => V[];\n getFirst: (bindings: Bindings) => V | undefined;\n values: () => V[];\n}\n"]}
package/lib/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './ActorRdfJoinOptionalHash';
package/lib/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./ActorRdfJoinOptionalHash"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6DAA2C","sourcesContent":["export * from './ActorRdfJoinOptionalHash';\n"]}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@comunica/actor-rdf-join-optional-hash",
3
+ "version": "3.2.0",
4
+ "description": "A optional-hash rdf-join actor",
5
+ "lsd:module": true,
6
+ "license": "MIT",
7
+ "homepage": "https://comunica.dev/",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/comunica/comunica.git",
11
+ "directory": "packages/actor-rdf-join-optional-hash"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/comunica/comunica/issues"
15
+ },
16
+ "keywords": [
17
+ "comunica",
18
+ "actor",
19
+ "rdf-join",
20
+ "optional-hash"
21
+ ],
22
+ "sideEffects": false,
23
+ "main": "lib/index.js",
24
+ "typings": "lib/index",
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "files": [
29
+ "components",
30
+ "lib/**/*.d.ts",
31
+ "lib/**/*.js",
32
+ "lib/**/*.js.map"
33
+ ],
34
+ "scripts": {
35
+ "build": "yarn run build:ts && yarn run build:components",
36
+ "build:ts": "node \"../../node_modules/typescript/bin/tsc\"",
37
+ "build:components": "componentsjs-generator"
38
+ },
39
+ "dependencies": {
40
+ "@comunica/bus-query-operation": "^3.2.0",
41
+ "@comunica/bus-rdf-join": "^3.2.0",
42
+ "@comunica/mediatortype-join-coefficients": "^3.2.0",
43
+ "@comunica/types": "^3.2.0",
44
+ "@rdfjs/types": "*",
45
+ "asynciterator": "^3.9.0",
46
+ "rdf-string": "^1.6.3"
47
+ },
48
+ "gitHead": "87baf2afed021a254859e64b92f34d9b51c6a7db"
49
+ }