-
Notifications
You must be signed in to change notification settings - Fork 74
Expand file tree
/
Copy pathExecutionHelpers.js
More file actions
143 lines (122 loc) · 5.44 KB
/
ExecutionHelpers.js
File metadata and controls
143 lines (122 loc) · 5.44 KB
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*globals define*/
define([
'underscore',
], function(
_,
) {
class ExecutionHelpers {
constructor(core, rootNode) {
this.core = core;
this.rootNode = rootNode;
}
async snapshotOperation(node, dst, base) {
// If we are making a snapshot, we should copy the base operation
// and set the attributes, add the child nodes, etc
if (!base) {
base = this.core.getBase(node);
}
const snapshot = this.core.createNode({
base: base,
parent: dst
});
const names = this.core.getAttributeNames(node);
const values = names.map(name => this.core.getAttribute(node, name));
names.forEach((name, i) =>
this.core.setAttribute(snapshot, name, values[i]));
const ptrNames = this.core.getValidPointerNames(node)
.filter(name => name !== 'base');
const setPointers = Promise.all(
ptrNames.map(async name => {
const targetPath = this.core.getPointerPath(node, name);
if (targetPath) {
const target = await this.core.loadByPath(this.rootNode, targetPath);
const targetCopy = this.core.copyNode(target, snapshot);
this.core.setPointer(snapshot, name, targetCopy);
}
})
);
await setPointers;
// Copy the data I/O
const metaTypeComparator = (a, b) => {
const aId = this.core.getPath(this.core.getMetaType(a));
const bId = this.core.getPath(this.core.getMetaType(b));
return aId < bId ? -1 : 1;
};
const srcCntrs = (await this.core.loadChildren(node))
.sort(metaTypeComparator);
const [dstInput, dstOutput] = (await this.core.loadChildren(snapshot))
.sort(metaTypeComparator);
const [srcInputs, srcOutputs] = (await Promise.all(srcCntrs.map(ctr => this.core.loadChildren(ctr))));
const copies = srcInputs.map(n => {
const copy = this.core.copyNode(n, dstInput);
const inheritancePath = this.getInheritedAncestors(n);
const dataMetaNode = inheritancePath.reverse()
.find(node => this.core.getAttribute(node, 'name') === 'Data');
this.core.setPointer(copy, 'base', dataMetaNode);
this.core.setAttribute(copy, 'name', this.core.getAttribute(n, 'name'));
return copy;
});
copies.push(...srcOutputs.map(n => this.shallowCopy(n, dstOutput)));
const oldNewPairs = _.zip(srcInputs.concat(srcOutputs), copies);
oldNewPairs.push([node, snapshot]);
return {snapshot, pairs: oldNewPairs};
}
getInheritedAncestors (node) {
const path = [];
while (node) {
path.push(node);
node = this.core.getBase(node);
}
return path;
}
shallowCopy (original, dst) {
const attrNames = this.core.getAttributeNames(original);
const copy = this.core.createNode({
base: this.core.getMetaType(original),
parent: dst
});
const values = attrNames.map(name => this.core.getAttribute(original, name));
attrNames.forEach((name, i) =>
this.core.setAttribute(copy, name, values[i]));
return copy;
}
async setDataContents(node, dataNode) {
const dataType = this.core.getAttribute(dataNode, 'type');
this.core.setAttribute(node, 'type', dataType);
const hash = this.core.getAttribute(dataNode, 'data');
this.core.setAttribute(node, 'data', hash);
const provOutput = this.core.getAttribute(dataNode, 'provOutput');
if (provOutput) {
this.core.setAttribute(node, 'provOutput', provOutput);
}
await this.clearProvenance(node);
const provDataId = this.core.getPointerPath(dataNode, 'provenance');
if (provDataId) {
const implOp = await this.core.loadByPath(this.rootNode, provDataId);
const provCopy = this.core.copyNode(implOp, node);
this.core.setPointer(node, 'provenance', provCopy);
}
}
async clearProvenance(dataNode) {
const provDataId = this.core.getPointerPath(dataNode, 'provenance');
if (provDataId) {
const provData = await this.core.loadByPath(this.rootNode, provDataId);
const {node} = this.getImplicitOperation(provData);
this.core.deleteNode(node);
}
}
getImplicitOperation(dataNode) {
const metanodes = Object.values(this.core.getAllMetaNodes(dataNode));
const implicitOp = metanodes
.find(node => this.core.getAttribute(node, 'name') === 'ImplicitOperation');
let node = dataNode;
const path = [];
while (node && !this.core.isTypeOf(node, implicitOp)) {
path.push(this.core.getAttribute(node, 'name'));
node = this.core.getParent(node);
}
return {node, path};
}
}
return ExecutionHelpers;
});