list-toolkit 2.1.1 → 2.2.1

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/README.md CHANGED
@@ -15,7 +15,7 @@ The toolkit provides the following data structures with a full set of efficientl
15
15
  * Value-based lists, where a list serves as a container for external objects, and node-based lists, where a list uses custom properties on external objects to link them around.
16
16
  * Hosted lists, which use a special head node to manage nodes, and headless lists, which point to an external list without including any headers.
17
17
  * Heaps:
18
- * Min-heap to support priority queues.
18
+ * Priority queues: min heap, leftist heap, skew heap.
19
19
  * Various list-based data structures:
20
20
  * Caches with various eviction algorithms: least recently used (LRU), least frequently used (LFU), first in first out (FIFO), and random.
21
21
  * A decorator is provided to decorate functions, methods, and getters with a cache of your choice.
@@ -146,6 +146,8 @@ BSD 3-Clause "New" or "Revised" License. See the LICENSE file for details.
146
146
 
147
147
  ## Release History
148
148
 
149
+ * 2.2.1 *Technical release: updated deps, added more tests.*
150
+ * 2.2.0 *Added leftist and skew heaps.*
149
151
  * 2.1.1 *Allowed functions to be used as nodes. Updated deps.*
150
152
  * 2.1.0 *Added splay tree. Updated deps.*
151
153
  * 2.0.0 *New major release.*
@@ -0,0 +1,63 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.HeapBase = void 0;
7
+ var _metaUtils = require("../meta-utils.js");
8
+ const defaultLess = (a, b) => a < b;
9
+ const defaultEqual = (a, b) => a === b;
10
+ class HeapBase {
11
+ constructor(options) {
12
+ (0, _metaUtils.copyOptions)(this, HeapBase.defaults, options);
13
+ }
14
+
15
+ // main methods
16
+ get isEmpty() {
17
+ throw new Error('Not implemented');
18
+ }
19
+ get top() {
20
+ throw new Error('Not implemented');
21
+ }
22
+ peek() {
23
+ return this.top;
24
+ }
25
+ pop() {
26
+ throw new Error('Not implemented');
27
+ }
28
+ push() {
29
+ throw new Error('Not implemented');
30
+ }
31
+ clear() {
32
+ throw new Error('Not implemented');
33
+ }
34
+
35
+ // performance methods
36
+ pushPop(value) {
37
+ this.push(value);
38
+ return this.pop();
39
+ }
40
+ replaceTop(value) {
41
+ const z = this.pop();
42
+ this.push(value);
43
+ return z;
44
+ }
45
+
46
+ // helper methods
47
+ merge(...args) {
48
+ throw new Error('Not implemented');
49
+ }
50
+ clone() {
51
+ throw new Error('Not implemented');
52
+ }
53
+ make(...args) {
54
+ return new this.constructor(this, ...args);
55
+ }
56
+ }
57
+ exports.HeapBase = HeapBase;
58
+ HeapBase.defaults = {
59
+ less: defaultLess,
60
+ equal: defaultEqual,
61
+ compare: null
62
+ };
63
+ var _default = exports.default = HeapBase;
@@ -0,0 +1,124 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.LeftistHeapNode = exports.LeftistHeap = void 0;
7
+ var _basics = _interopRequireDefault(require("./basics.js"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ const defaultLess = (a, b) => a < b;
10
+ const merge = (a, b, less) => {
11
+ if (!a) return b;
12
+ if (!b) return a;
13
+ if (less(b.value, a.value)) [a, b] = [b, a]; // swap
14
+
15
+ a.right = merge(a.right, b, less);
16
+ if (!a.left) {
17
+ [a.left, a.right] = [a.right, a.left]; // swap
18
+ a.s = 1;
19
+ return a;
20
+ }
21
+ if (a.left.s < a.right.s) {
22
+ [a.left, a.right] = [a.right, a.left]; // swap
23
+ }
24
+ a.s = a.right.s + 1;
25
+ return a;
26
+ };
27
+ class LeftistHeapNode {
28
+ constructor(value) {
29
+ this.value = value;
30
+ this.right = this.left = null;
31
+ this.s = 1;
32
+ }
33
+ clear() {
34
+ this.left = this.right = null;
35
+ this.s = 1;
36
+ }
37
+ clone() {
38
+ const node = new LeftistHeapNode(this.value);
39
+ node.left = this.left && this.left.clone();
40
+ node.right = this.right && this.right.clone();
41
+ return node;
42
+ }
43
+ }
44
+ exports.LeftistHeapNode = LeftistHeapNode;
45
+ class LeftistHeap extends _basics.default {
46
+ constructor(options, ...args) {
47
+ super(options);
48
+ if (typeof this.compare == 'function') {
49
+ this.less = (a, b) => this.compare(a, b) < 0;
50
+ }
51
+ this.root = null;
52
+ this.size = 0;
53
+ if (args.length) this.merge(...args);
54
+ }
55
+ get isEmpty() {
56
+ return !this.root;
57
+ }
58
+ get length() {
59
+ return this.size;
60
+ }
61
+ get top() {
62
+ return this.root ? this.root.value : undefined;
63
+ }
64
+ peek() {
65
+ return this.root ? this.root.value : undefined;
66
+ }
67
+ push(value) {
68
+ this.root = merge(this.root, new LeftistHeapNode(value), this.less);
69
+ ++this.size;
70
+ return this;
71
+ }
72
+ pop() {
73
+ if (!this.root) return;
74
+ const z = this.root;
75
+ this.root = merge(this.root.left, this.root.right, this.less);
76
+ --this.size;
77
+ return z.value;
78
+ }
79
+ pushPop(value) {
80
+ if (!this.root || this.less(value, this.root.value)) return value;
81
+ const z = this.root;
82
+ this.root = merge(z.left, new LeftistHeapNode(value), this.less);
83
+ this.root = merge(this.root, z.right, this.less);
84
+ return z.value;
85
+ }
86
+ replaceTop(value) {
87
+ if (!this.root) {
88
+ this.root = new LeftistHeapNode(value);
89
+ this.size = 1;
90
+ return; // undefined
91
+ }
92
+ const z = this.root;
93
+ this.root = merge(z.left, new LeftistHeapNode(value), this.less);
94
+ this.root = merge(this.root, z.right, this.less);
95
+ return z.value;
96
+ }
97
+ clear() {
98
+ this.root = null;
99
+ this.size = 0;
100
+ return this;
101
+ }
102
+ merge(...args) {
103
+ for (const other of args) {
104
+ this.root = merge(this.root, other.root, this.less);
105
+ this.size += other.size;
106
+ other.root = null;
107
+ other.size = 0;
108
+ }
109
+ return this;
110
+ }
111
+ clone() {
112
+ const heap = new LeftistHeap(this);
113
+ heap.root = this.root && this.root.clone();
114
+ heap.size = this.size;
115
+ return heap;
116
+ }
117
+ static from(array, options = _basics.default.defaults) {
118
+ const heap = new LeftistHeap(options);
119
+ for (const value of array) heap.push(value);
120
+ return heap;
121
+ }
122
+ }
123
+ exports.LeftistHeap = LeftistHeap;
124
+ var _default = exports.default = LeftistHeap;
@@ -4,15 +4,14 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = exports.MinHeap = void 0;
7
- var _metaUtils = require("../meta-utils.js");
7
+ var _basics = _interopRequireDefault(require("./basics.js"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
8
9
  // the following functions are inlined:
9
10
 
10
11
  // const left = i => (i << 1) + 1;
11
12
  // const right = i => (i + 1) << 1;
12
13
  // const parent = i => (i - 1) >> 1;
13
14
 
14
- const defaultLess = (a, b) => a < b;
15
- const defaultEqual = (a, b) => a === b;
16
15
  const up = (array, i, less = defaultLess) => {
17
16
  for (let p = i - 1 >> 1; i > 0; i = p, p = i - 1 >> 1) {
18
17
  const iValue = array[i],
@@ -38,15 +37,15 @@ const down = (array, i, less = defaultLess, n = array.length) => {
38
37
  }
39
38
  return array;
40
39
  };
41
- class MinHeap {
40
+ class MinHeap extends _basics.default {
42
41
  constructor(options, ...args) {
43
- (0, _metaUtils.copyOptions)(this, MinHeap.defaults, options);
42
+ super(options);
44
43
  if (typeof this.compare == 'function') {
45
44
  this.less = (a, b) => this.compare(a, b) < 0;
46
45
  this.equal = (a, b) => !this.compare(a, b);
47
46
  }
48
47
  this.array = [];
49
- this.merge(...args);
48
+ if (args.length) this.merge(...args);
50
49
  }
51
50
  get length() {
52
51
  return this.array.length;
@@ -191,9 +190,6 @@ class MinHeap {
191
190
  })), this.less);
192
191
  return this;
193
192
  }
194
- make(...args) {
195
- return new MinHeap(this, ...args);
196
- }
197
193
  clone() {
198
194
  const heap = new MinHeap(this);
199
195
  heap.array = this.array.slice(0);
@@ -288,11 +284,11 @@ class MinHeap {
288
284
  }
289
285
  return heapArray;
290
286
  }
287
+ static from(array, options = MinHeap.defaults) {
288
+ const heap = new MinHeap(options);
289
+ heap.array = MinHeap.build(array, heap.less);
290
+ return heap;
291
+ }
291
292
  }
292
293
  exports.MinHeap = MinHeap;
293
- MinHeap.defaults = {
294
- less: defaultLess,
295
- equal: defaultEqual,
296
- compare: null
297
- };
298
294
  var _default = exports.default = MinHeap;
@@ -0,0 +1,114 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.SkewHeapNode = exports.SkewHeap = void 0;
7
+ var _basics = _interopRequireDefault(require("./basics.js"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ const merge = (a, b, less) => {
10
+ if (!a) return b;
11
+ if (!b) return a;
12
+ if (less(b.value, a.value)) [a, b] = [b, a]; // swap
13
+
14
+ const temp = a.right;
15
+ a.right = a.left;
16
+ a.left = merge(b, temp, less);
17
+ return a;
18
+ };
19
+ class SkewHeapNode {
20
+ constructor(value) {
21
+ this.value = value;
22
+ this.right = this.left = null;
23
+ }
24
+ clear() {
25
+ this.left = this.right = null;
26
+ }
27
+ clone() {
28
+ const node = new SkewHeapNode(this.value);
29
+ node.left = this.left && this.left.clone();
30
+ node.right = this.right && this.right.clone();
31
+ return node;
32
+ }
33
+ }
34
+ exports.SkewHeapNode = SkewHeapNode;
35
+ class SkewHeap extends _basics.default {
36
+ constructor(options, ...args) {
37
+ super(options);
38
+ if (typeof this.compare == 'function') {
39
+ this.less = (a, b) => this.compare(a, b) < 0;
40
+ }
41
+ this.root = null;
42
+ this.size = 0;
43
+ if (args.length) this.merge(...args);
44
+ }
45
+ get isEmpty() {
46
+ return !this.root;
47
+ }
48
+ get length() {
49
+ return this.size;
50
+ }
51
+ get top() {
52
+ return this.root ? this.root.value : undefined;
53
+ }
54
+ peek() {
55
+ return this.root ? this.root.value : undefined;
56
+ }
57
+ push(value) {
58
+ this.root = merge(this.root, new SkewHeapNode(value), this.less);
59
+ ++this.size;
60
+ return this;
61
+ }
62
+ pop() {
63
+ if (!this.root) return;
64
+ const z = this.root;
65
+ this.root = merge(this.root.left, this.root.right, this.less);
66
+ --this.size;
67
+ return z.value;
68
+ }
69
+ pushPop(value) {
70
+ if (!this.root || this.less(value, this.root.value)) return value;
71
+ const z = this.root;
72
+ this.root = merge(z.left, new SkewHeapNode(value), this.less);
73
+ this.root = merge(this.root, z.right, this.less);
74
+ return z.value;
75
+ }
76
+ replaceTop(value) {
77
+ if (!this.root) {
78
+ this.root = new SkewHeapNode(value);
79
+ this.size = 1;
80
+ return; // undefined
81
+ }
82
+ const z = this.root;
83
+ this.root = merge(z.left, new SkewHeapNode(value), this.less);
84
+ this.root = merge(this.root, z.right, this.less);
85
+ return z.value;
86
+ }
87
+ clear() {
88
+ this.root = null;
89
+ this.size = 0;
90
+ return this;
91
+ }
92
+ merge(...args) {
93
+ for (const other of args) {
94
+ this.root = merge(this.root, other.root, this.less);
95
+ this.size += other.size;
96
+ other.root = null;
97
+ other.size = 0;
98
+ }
99
+ return this;
100
+ }
101
+ clone() {
102
+ const heap = new SkewHeap(this);
103
+ heap.root = this.root && this.root.clone();
104
+ heap.size = this.size;
105
+ return heap;
106
+ }
107
+ static from(array, options = _basics.default.defaults) {
108
+ const heap = new SkewHeap(options);
109
+ for (const value of array) heap.push(value);
110
+ return heap;
111
+ }
112
+ }
113
+ exports.SkewHeap = SkewHeap;
114
+ var _default = exports.default = SkewHeap;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "list-toolkit",
3
- "version": "2.1.1",
3
+ "version": "2.2.1",
4
4
  "description": "List-based data structures to organize your objects.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -17,6 +17,9 @@
17
17
  "test:bun": "tape6-bun --flags FO",
18
18
  "test:deno-original": "tape6-deno --flags FO",
19
19
  "test:deno": "deno run -A `tape6-runner main` --flags FO",
20
+ "test:proc": "tape6-proc --flags FO",
21
+ "test:proc:bun": "bun run `npx tape6-proc --self` --flags FO",
22
+ "test:proc:deno": "deno run -A `npx tape6-proc --self` --flags FO --runFileArgs -A",
20
23
  "start": "tape6-server --trace"
21
24
  },
22
25
  "repository": {
@@ -31,16 +34,19 @@
31
34
  "data structures"
32
35
  ],
33
36
  "author": "Eugene Lazutkin <eugene.lazutkin@gmail.com> (http://www.lazutkin.com/)",
37
+ "funding": "https://github.com/sponsors/uhop",
34
38
  "license": "BSD-3-Clause",
35
39
  "bugs": {
36
40
  "url": "https://github.com/uhop/list-toolkit/issues"
37
41
  },
38
42
  "homepage": "https://github.com/uhop/list-toolkit#readme",
39
43
  "devDependencies": {
40
- "@babel/cli": "^7.25.6",
41
- "@babel/core": "^7.25.2",
42
- "@babel/preset-env": "^7.25.4",
43
- "tape-six": "^0.12.2"
44
+ "@babel/cli": "^7.25.7",
45
+ "@babel/core": "^7.25.7",
46
+ "@babel/preset-env": "^7.25.7",
47
+ "nano-benchmark": "^1.0.4",
48
+ "tape-six": "^1.0.2",
49
+ "tape-six-proc": "^1.0.0"
44
50
  },
45
51
  "files": [
46
52
  "/src",
@@ -0,0 +1,58 @@
1
+ 'use strict';
2
+
3
+ import {copyOptions} from '../meta-utils.js';
4
+
5
+ const defaultLess = (a, b) => a < b;
6
+ const defaultEqual = (a, b) => a === b;
7
+
8
+ export class HeapBase {
9
+ constructor(options) {
10
+ copyOptions(this, HeapBase.defaults, options);
11
+ }
12
+
13
+ // main methods
14
+ get isEmpty() {
15
+ throw new Error('Not implemented');
16
+ }
17
+ get top() {
18
+ throw new Error('Not implemented');
19
+ }
20
+ peek() {
21
+ return this.top;
22
+ }
23
+ pop() {
24
+ throw new Error('Not implemented');
25
+ }
26
+ push() {
27
+ throw new Error('Not implemented');
28
+ }
29
+ clear() {
30
+ throw new Error('Not implemented');
31
+ }
32
+
33
+ // performance methods
34
+ pushPop(value) {
35
+ this.push(value);
36
+ return this.pop();
37
+ }
38
+ replaceTop(value) {
39
+ const z = this.pop();
40
+ this.push(value);
41
+ return z;
42
+ }
43
+
44
+ // helper methods
45
+ merge(...args) {
46
+ throw new Error('Not implemented');
47
+ }
48
+ clone() {
49
+ throw new Error('Not implemented');
50
+ }
51
+ make(...args) {
52
+ return new this.constructor(this, ...args);
53
+ }
54
+ }
55
+
56
+ HeapBase.defaults = {less: defaultLess, equal: defaultEqual, compare: null};
57
+
58
+ export default HeapBase;
@@ -0,0 +1,125 @@
1
+ 'use strict';
2
+
3
+ import HeapBase from './basics.js';
4
+
5
+ const defaultLess = (a, b) => a < b;
6
+
7
+ const merge = (a, b, less) => {
8
+ if (!a) return b;
9
+ if (!b) return a;
10
+ if (less(b.value, a.value)) [a, b] = [b, a]; // swap
11
+
12
+ a.right = merge(a.right, b, less);
13
+
14
+ if (!a.left) {
15
+ [a.left, a.right] = [a.right, a.left]; // swap
16
+ a.s = 1;
17
+ return a;
18
+ }
19
+
20
+ if (a.left.s < a.right.s) {
21
+ [a.left, a.right] = [a.right, a.left]; // swap
22
+ }
23
+ a.s = a.right.s + 1;
24
+ return a;
25
+ };
26
+
27
+ export class LeftistHeapNode {
28
+ constructor(value) {
29
+ this.value = value;
30
+ this.right = this.left = null;
31
+ this.s = 1;
32
+ }
33
+ clear() {
34
+ this.left = this.right = null;
35
+ this.s = 1;
36
+ }
37
+ clone() {
38
+ const node = new LeftistHeapNode(this.value);
39
+ node.left = this.left && this.left.clone();
40
+ node.right = this.right && this.right.clone();
41
+ return node;
42
+ }
43
+ }
44
+
45
+ export class LeftistHeap extends HeapBase {
46
+ constructor(options, ...args) {
47
+ super(options);
48
+ if (typeof this.compare == 'function') {
49
+ this.less = (a, b) => this.compare(a, b) < 0;
50
+ }
51
+ this.root = null;
52
+ this.size = 0;
53
+ if (args.length) this.merge(...args);
54
+ }
55
+ get isEmpty() {
56
+ return !this.root;
57
+ }
58
+ get length() {
59
+ return this.size;
60
+ }
61
+ get top() {
62
+ return this.root ? this.root.value : undefined;
63
+ }
64
+ peek() {
65
+ return this.root ? this.root.value : undefined;
66
+ }
67
+ push(value) {
68
+ this.root = merge(this.root, new LeftistHeapNode(value), this.less);
69
+ ++this.size;
70
+ return this;
71
+ }
72
+ pop() {
73
+ if (!this.root) return;
74
+ const z = this.root;
75
+ this.root = merge(this.root.left, this.root.right, this.less);
76
+ --this.size;
77
+ return z.value;
78
+ }
79
+ pushPop(value) {
80
+ if (!this.root || this.less(value, this.root.value)) return value;
81
+ const z = this.root;
82
+ this.root = merge(z.left, new LeftistHeapNode(value), this.less);
83
+ this.root = merge(this.root, z.right, this.less);
84
+ return z.value;
85
+ }
86
+ replaceTop(value) {
87
+ if (!this.root) {
88
+ this.root = new LeftistHeapNode(value);
89
+ this.size = 1;
90
+ return; // undefined
91
+ }
92
+ const z = this.root;
93
+ this.root = merge(z.left, new LeftistHeapNode(value), this.less);
94
+ this.root = merge(this.root, z.right, this.less);
95
+ return z.value;
96
+ }
97
+ clear() {
98
+ this.root = null;
99
+ this.size = 0;
100
+ return this;
101
+ }
102
+ merge(...args) {
103
+ for (const other of args) {
104
+ this.root = merge(this.root, other.root, this.less);
105
+ this.size += other.size;
106
+ other.root = null;
107
+ other.size = 0;
108
+ }
109
+ return this;
110
+ }
111
+ clone() {
112
+ const heap = new LeftistHeap(this);
113
+ heap.root = this.root && this.root.clone();
114
+ heap.size = this.size;
115
+ return heap;
116
+ }
117
+
118
+ static from(array, options = HeapBase.defaults) {
119
+ const heap = new LeftistHeap(options);
120
+ for (const value of array) heap.push(value);
121
+ return heap;
122
+ }
123
+ }
124
+
125
+ export default LeftistHeap;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- import {copyOptions} from '../meta-utils.js';
3
+ import HeapBase from './basics.js';
4
4
 
5
5
  // the following functions are inlined:
6
6
 
@@ -8,9 +8,6 @@ import {copyOptions} from '../meta-utils.js';
8
8
  // const right = i => (i + 1) << 1;
9
9
  // const parent = i => (i - 1) >> 1;
10
10
 
11
- const defaultLess = (a, b) => a < b;
12
- const defaultEqual = (a, b) => a === b;
13
-
14
11
  const up = (array, i, less = defaultLess) => {
15
12
  for (let p = (i - 1) >> 1; i > 0; i = p, p = (i - 1) >> 1) {
16
13
  const iValue = array[i],
@@ -38,15 +35,15 @@ const down = (array, i, less = defaultLess, n = array.length) => {
38
35
  return array;
39
36
  };
40
37
 
41
- export class MinHeap {
38
+ export class MinHeap extends HeapBase {
42
39
  constructor(options, ...args) {
43
- copyOptions(this, MinHeap.defaults, options);
40
+ super(options);
44
41
  if (typeof this.compare == 'function') {
45
42
  this.less = (a, b) => this.compare(a, b) < 0;
46
43
  this.equal = (a, b) => !this.compare(a, b);
47
44
  }
48
45
  this.array = [];
49
- this.merge(...args);
46
+ if (args.length) this.merge(...args);
50
47
  }
51
48
 
52
49
  get length() {
@@ -216,10 +213,6 @@ export class MinHeap {
216
213
  return this;
217
214
  }
218
215
 
219
- make(...args) {
220
- return new MinHeap(this, ...args);
221
- }
222
-
223
216
  clone() {
224
217
  const heap = new MinHeap(this);
225
218
  heap.array = this.array.slice(0);
@@ -327,8 +320,12 @@ export class MinHeap {
327
320
  }
328
321
  return heapArray;
329
322
  }
330
- }
331
323
 
332
- MinHeap.defaults = {less: defaultLess, equal: defaultEqual, compare: null};
324
+ static from(array, options = MinHeap.defaults) {
325
+ const heap = new MinHeap(options);
326
+ heap.array = MinHeap.build(array, heap.less);
327
+ return heap;
328
+ }
329
+ }
333
330
 
334
331
  export default MinHeap;
@@ -0,0 +1,113 @@
1
+ 'use strict';
2
+
3
+ import HeapBase from './basics.js';
4
+
5
+ const merge = (a, b, less) => {
6
+ if (!a) return b;
7
+ if (!b) return a;
8
+ if (less(b.value, a.value)) [a, b] = [b, a]; // swap
9
+
10
+ const temp = a.right;
11
+ a.right = a.left;
12
+ a.left = merge(b, temp, less);
13
+
14
+ return a;
15
+ };
16
+
17
+ export class SkewHeapNode {
18
+ constructor(value) {
19
+ this.value = value;
20
+ this.right = this.left = null;
21
+ }
22
+ clear() {
23
+ this.left = this.right = null;
24
+ }
25
+ clone() {
26
+ const node = new SkewHeapNode(this.value);
27
+ node.left = this.left && this.left.clone();
28
+ node.right = this.right && this.right.clone();
29
+ return node;
30
+ }
31
+ }
32
+
33
+ export class SkewHeap extends HeapBase {
34
+ constructor(options, ...args) {
35
+ super(options);
36
+ if (typeof this.compare == 'function') {
37
+ this.less = (a, b) => this.compare(a, b) < 0;
38
+ }
39
+ this.root = null;
40
+ this.size = 0;
41
+ if (args.length) this.merge(...args);
42
+ }
43
+ get isEmpty() {
44
+ return !this.root;
45
+ }
46
+ get length() {
47
+ return this.size;
48
+ }
49
+ get top() {
50
+ return this.root ? this.root.value : undefined;
51
+ }
52
+ peek() {
53
+ return this.root ? this.root.value : undefined;
54
+ }
55
+ push(value) {
56
+ this.root = merge(this.root, new SkewHeapNode(value), this.less);
57
+ ++this.size;
58
+ return this;
59
+ }
60
+ pop() {
61
+ if (!this.root) return;
62
+ const z = this.root;
63
+ this.root = merge(this.root.left, this.root.right, this.less);
64
+ --this.size;
65
+ return z.value;
66
+ }
67
+ pushPop(value) {
68
+ if (!this.root || this.less(value, this.root.value)) return value;
69
+ const z = this.root;
70
+ this.root = merge(z.left, new SkewHeapNode(value), this.less);
71
+ this.root = merge(this.root, z.right, this.less);
72
+ return z.value;
73
+ }
74
+ replaceTop(value) {
75
+ if (!this.root) {
76
+ this.root = new SkewHeapNode(value);
77
+ this.size = 1;
78
+ return; // undefined
79
+ }
80
+ const z = this.root;
81
+ this.root = merge(z.left, new SkewHeapNode(value), this.less);
82
+ this.root = merge(this.root, z.right, this.less);
83
+ return z.value;
84
+ }
85
+ clear() {
86
+ this.root = null;
87
+ this.size = 0;
88
+ return this;
89
+ }
90
+ merge(...args) {
91
+ for (const other of args) {
92
+ this.root = merge(this.root, other.root, this.less);
93
+ this.size += other.size;
94
+ other.root = null;
95
+ other.size = 0;
96
+ }
97
+ return this;
98
+ }
99
+ clone() {
100
+ const heap = new SkewHeap(this);
101
+ heap.root = this.root && this.root.clone();
102
+ heap.size = this.size;
103
+ return heap;
104
+ }
105
+
106
+ static from(array, options = HeapBase.defaults) {
107
+ const heap = new SkewHeap(options);
108
+ for (const value of array) heap.push(value);
109
+ return heap;
110
+ }
111
+ }
112
+
113
+ export default SkewHeap;