1 | import { factory } from '../../utils/factory'
|
2 |
|
3 | const name = 'Spa'
|
4 | const dependencies = ['addScalar', 'equalScalar', 'FibonacciHeap']
|
5 |
|
6 | export const createSpaClass = factory(name, dependencies, ({ addScalar, equalScalar, FibonacciHeap }) => {
|
7 | |
8 |
|
9 |
|
10 |
|
11 | function Spa () {
|
12 | if (!(this instanceof Spa)) { throw new SyntaxError('Constructor must be called with the new operator') }
|
13 |
|
14 |
|
15 | this._values = []
|
16 | this._heap = new FibonacciHeap()
|
17 | }
|
18 |
|
19 | |
20 |
|
21 |
|
22 | Spa.prototype.type = 'Spa'
|
23 | Spa.prototype.isSpa = true
|
24 |
|
25 | |
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 | Spa.prototype.set = function (i, v) {
|
32 |
|
33 | if (!this._values[i]) {
|
34 |
|
35 | const node = this._heap.insert(i, v)
|
36 |
|
37 | this._values[i] = node
|
38 | } else {
|
39 |
|
40 | this._values[i].value = v
|
41 | }
|
42 | }
|
43 |
|
44 | Spa.prototype.get = function (i) {
|
45 | const node = this._values[i]
|
46 | if (node) { return node.value }
|
47 | return 0
|
48 | }
|
49 |
|
50 | Spa.prototype.accumulate = function (i, v) {
|
51 |
|
52 | let node = this._values[i]
|
53 | if (!node) {
|
54 |
|
55 | node = this._heap.insert(i, v)
|
56 |
|
57 | this._values[i] = node
|
58 | } else {
|
59 |
|
60 | node.value = addScalar(node.value, v)
|
61 | }
|
62 | }
|
63 |
|
64 | Spa.prototype.forEach = function (from, to, callback) {
|
65 |
|
66 | const heap = this._heap
|
67 | const values = this._values
|
68 |
|
69 | const nodes = []
|
70 |
|
71 | let node = heap.extractMinimum()
|
72 | if (node) { nodes.push(node) }
|
73 |
|
74 | while (node && node.key <= to) {
|
75 |
|
76 | if (node.key >= from) {
|
77 |
|
78 | if (!equalScalar(node.value, 0)) {
|
79 |
|
80 | callback(node.key, node.value, this)
|
81 | }
|
82 | }
|
83 |
|
84 | node = heap.extractMinimum()
|
85 | if (node) { nodes.push(node) }
|
86 | }
|
87 |
|
88 | for (let i = 0; i < nodes.length; i++) {
|
89 |
|
90 | const n = nodes[i]
|
91 |
|
92 | node = heap.insert(n.key, n.value)
|
93 |
|
94 | values[node.key] = node
|
95 | }
|
96 | }
|
97 |
|
98 | Spa.prototype.swap = function (i, j) {
|
99 |
|
100 | let nodei = this._values[i]
|
101 | let nodej = this._values[j]
|
102 |
|
103 | if (!nodei && nodej) {
|
104 |
|
105 | nodei = this._heap.insert(i, nodej.value)
|
106 |
|
107 | this._heap.remove(nodej)
|
108 |
|
109 | this._values[i] = nodei
|
110 | this._values[j] = undefined
|
111 | } else if (nodei && !nodej) {
|
112 |
|
113 | nodej = this._heap.insert(j, nodei.value)
|
114 |
|
115 | this._heap.remove(nodei)
|
116 |
|
117 | this._values[j] = nodej
|
118 | this._values[i] = undefined
|
119 | } else if (nodei && nodej) {
|
120 |
|
121 | const v = nodei.value
|
122 | nodei.value = nodej.value
|
123 | nodej.value = v
|
124 | }
|
125 | }
|
126 |
|
127 | return Spa
|
128 | }, { isClass: true })
|