-
Notifications
You must be signed in to change notification settings - Fork 119
/
Copy pathOperations on Tree.js
72 lines (48 loc) · 1.54 KB
/
Operations on Tree.js
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
var LockingTree = function(parent) {
this.parents = parent;
this.children = [];
this.locked = new Map();
for (let i = 0; i < this.parents.length; ++i) {
this.children[i] = [];
}
for (let i = 1; i < this.parents.length; ++i) {
const parent = this.parents[i];
this.children[parent].push(i);
}
};
LockingTree.prototype.lock = function(num, user) {
if (this.locked.has(num)) return false;
this.locked.set(num, user);
return true;
};
LockingTree.prototype.unlock = function(num, user) {
if (!this.locked.has(num) || this.locked.get(num) != user) return false;
this.locked.delete(num);
return true;
};
LockingTree.prototype.upgrade = function(num, user) {
let isLocked = traverseUp(num, this.parents, this.locked);
if (isLocked) return false;
const queue = [];
isLocked = false;
queue.push(num);
while (queue.length > 0) {
const node = queue.shift();
if (node != num && this.locked.has(node)) {
isLocked = true;
this.locked.delete(node);
}
for (let i = 0; i < this.children[node].length; ++i) {
queue.push(this.children[node][i]);
}
}
if (!isLocked) return false;
this.locked.set(num, user);
return true;
function traverseUp(num, parents, locked) {
if (locked.has(num)) return true;
if (num === 0) return false;
const parentIdx = parents[num];
return traverseUp(parentIdx, parents, locked);
}
};