-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjoinOnEulerDiagramParts.ts
72 lines (60 loc) · 2.41 KB
/
joinOnEulerDiagramParts.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import { _ } from './constants';
import { DetailingModifier, EulerDiagramPartsCombinations, JoinOnEulerDiagramParts, LRA } from './types';
export function buildJoinerOnEulerDiagramPartsWithCustomDetailingModifier<
Detailing extends DetailingModifier = 'A'
>() {
return function * __joinOnEulerDiagramParts<
const EulerDiagramParts extends EulerDiagramPartsCombinations,
L,
R,
MergedResult,
TupleType = JoinOnEulerDiagramParts<L, R, EulerDiagramParts, Detailing>,
>(
left: Iterable<L>,
right: Iterable<R>,
eulerDiagramParts: EulerDiagramParts,
merge: (tuple: TupleType) => MergedResult,
passesJoinCondition: (tuple: LRA<L, R>) => boolean,
): Generator<MergedResult> {
const bits = parseInt(eulerDiagramParts, 2);
const shouldAddLeftExclusivePart = bits & 0b100;
const shouldAddInnerPart = bits & 0b010;
const shouldAddRightExclusivePart = bits & 0b001;
let ref = {} as { unmatchedRightIndices: Set<number> };
if(shouldAddRightExclusivePart)
ref.unmatchedRightIndices = new Set(
Array.from(right, (e, i) => i)
);
for (const l of left) {
let didLeftFailAllJoinConditions = true;
let rIndex = -1;
// Starts with -1 because is being incremented before used
for (const r of right) {
const tuple = [l, r] satisfies LRA<L, R>;
rIndex++;
if (!passesJoinCondition(tuple)) continue;
didLeftFailAllJoinConditions = false;
if(shouldAddRightExclusivePart)
ref.unmatchedRightIndices.delete(rIndex);
if(shouldAddInnerPart)
yield merge(tuple as TupleType);
}
if(
didLeftFailAllJoinConditions
&& shouldAddLeftExclusivePart
)
yield merge([l, _] as TupleType);
}
if(shouldAddRightExclusivePart) {
let rIndex = 0;
for (const r of right) {
if(ref.unmatchedRightIndices.has(rIndex++))
yield merge([_, r] as TupleType);
}
}
}
}
export const joinOnEulerDiagramPartsWithAtomicMergeArgs = buildJoinerOnEulerDiagramPartsWithCustomDetailingModifier<"A">();
export const joinOnEulerDiagramPartsWithCompactedMergeArgs = buildJoinerOnEulerDiagramPartsWithCustomDetailingModifier<"C">();
export const joinOnEulerDiagramPartsWithExtendedMergeArgs = buildJoinerOnEulerDiagramPartsWithCustomDetailingModifier<"E">();
export const joinOnEulerDiagramParts = joinOnEulerDiagramPartsWithAtomicMergeArgs;