data-structure-typed 1.54.2 → 1.54.3
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/CHANGELOG.md +1 -1
- package/LICENSE +2 -2
- package/README.md +14 -1
- package/README_zh-CN.md +1 -1
- package/benchmark/report.html +4 -1
- package/benchmark/report.json +76 -17
- package/dist/cjs/data-structures/binary-tree/avl-tree-counter.d.ts +21 -20
- package/dist/cjs/data-structures/binary-tree/avl-tree-counter.js +8 -7
- package/dist/cjs/data-structures/binary-tree/avl-tree-counter.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +12 -12
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js +2 -2
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/avl-tree.d.ts +25 -21
- package/dist/cjs/data-structures/binary-tree/avl-tree.js +12 -8
- package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +111 -225
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +177 -144
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/bst.d.ts +59 -53
- package/dist/cjs/data-structures/binary-tree/bst.js +75 -119
- package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/red-black-tree.d.ts +18 -18
- package/dist/cjs/data-structures/binary-tree/red-black-tree.js +6 -6
- package/dist/cjs/data-structures/binary-tree/red-black-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/tree-counter.d.ts +19 -19
- package/dist/cjs/data-structures/binary-tree/tree-counter.js +12 -12
- package/dist/cjs/data-structures/binary-tree/tree-counter.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +12 -12
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +2 -2
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
- package/dist/cjs/types/data-structures/binary-tree/binary-tree.d.ts +1 -0
- package/dist/cjs/types/data-structures/binary-tree/bst.d.ts +1 -1
- package/dist/cjs/utils/utils.d.ts +2 -2
- package/dist/esm/data-structures/binary-tree/avl-tree-counter.d.ts +21 -20
- package/dist/esm/data-structures/binary-tree/avl-tree-counter.js +9 -8
- package/dist/esm/data-structures/binary-tree/avl-tree-counter.js.map +1 -1
- package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.d.ts +12 -12
- package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.js +3 -3
- package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
- package/dist/esm/data-structures/binary-tree/avl-tree.d.ts +25 -21
- package/dist/esm/data-structures/binary-tree/avl-tree.js +13 -9
- package/dist/esm/data-structures/binary-tree/avl-tree.js.map +1 -1
- package/dist/esm/data-structures/binary-tree/binary-tree.d.ts +111 -225
- package/dist/esm/data-structures/binary-tree/binary-tree.js +181 -148
- package/dist/esm/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/esm/data-structures/binary-tree/bst.d.ts +59 -53
- package/dist/esm/data-structures/binary-tree/bst.js +76 -120
- package/dist/esm/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/esm/data-structures/binary-tree/red-black-tree.d.ts +18 -18
- package/dist/esm/data-structures/binary-tree/red-black-tree.js +7 -7
- package/dist/esm/data-structures/binary-tree/red-black-tree.js.map +1 -1
- package/dist/esm/data-structures/binary-tree/tree-counter.d.ts +19 -19
- package/dist/esm/data-structures/binary-tree/tree-counter.js +13 -13
- package/dist/esm/data-structures/binary-tree/tree-counter.js.map +1 -1
- package/dist/esm/data-structures/binary-tree/tree-multi-map.d.ts +12 -12
- package/dist/esm/data-structures/binary-tree/tree-multi-map.js +3 -3
- package/dist/esm/data-structures/binary-tree/tree-multi-map.js.map +1 -1
- package/dist/esm/types/data-structures/binary-tree/binary-tree.d.ts +1 -0
- package/dist/esm/types/data-structures/binary-tree/bst.d.ts +1 -1
- package/dist/esm/utils/utils.d.ts +2 -2
- package/dist/umd/data-structure-typed.js +296 -279
- package/dist/umd/data-structure-typed.min.js +5 -12
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +7 -7
- package/src/data-structures/binary-tree/avl-tree-counter.ts +30 -23
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +25 -15
- package/src/data-structures/binary-tree/avl-tree.ts +35 -29
- package/src/data-structures/binary-tree/binary-tree.ts +469 -252
- package/src/data-structures/binary-tree/bst.ts +141 -143
- package/src/data-structures/binary-tree/red-black-tree.ts +27 -35
- package/src/data-structures/binary-tree/tree-counter.ts +33 -27
- package/src/data-structures/binary-tree/tree-multi-map.ts +25 -17
- package/src/types/data-structures/binary-tree/binary-tree.ts +1 -0
- package/src/types/data-structures/binary-tree/bst.ts +1 -1
- package/src/utils/utils.ts +2 -2
- package/test/integration/compile.mjs +21 -21
- package/test/performance/data-structures/binary-tree/avl-tree.test.mjs +71 -0
- package/test/performance/data-structures/binary-tree/red-black-tree.test.mjs +81 -0
- package/test/performance/{reportor.js → reportor.mjs} +264 -8
- package/test/performance/reportor.ts +1 -1
- package/test/unit/data-structures/binary-tree/avl-tree-counter.test.ts +7 -7
- package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +4 -5
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +72 -5
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +132 -82
- package/test/unit/data-structures/binary-tree/bst.test.ts +12 -12
- package/test/unit/data-structures/binary-tree/red-black-tree.test.ts +4 -12
- package/test/unit/data-structures/binary-tree/tree-counter.test.ts +4 -4
- package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +5 -5
- package/test/utils/json2html.ts +0 -154
- package/test/performance/data-structures/binary-tree/avl-tree.test.js +0 -45
- /package/test/performance/data-structures/binary-tree/{rb-tree.test.ts → red-black-tree.test.ts} +0 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { AVLTree } from 'data-structure-typed';
|
|
2
|
+
import Benchmark from 'benchmark';
|
|
3
|
+
|
|
4
|
+
const magnitude = {
|
|
5
|
+
THOUSAND: 1000,
|
|
6
|
+
TEN_THOUSAND: 10000,
|
|
7
|
+
HUNDRED_THOUSAND: 100000,
|
|
8
|
+
MILLION: 1000000,
|
|
9
|
+
TEN_MILLION: 10000000,
|
|
10
|
+
BILLION: 100000000
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
function getRandomIntArray(length = 1000, min = -1000, max = 1000, unique = true) {
|
|
14
|
+
if (unique) {
|
|
15
|
+
if (max - min + 1 < length) {
|
|
16
|
+
throw new Error('Range too small for unique values with the specified length');
|
|
17
|
+
}
|
|
18
|
+
const allNumbers = Array.from({ length: max - min + 1 }, (_, i) => i + min);
|
|
19
|
+
for (let i = allNumbers.length - 1; i > 0; i--) {
|
|
20
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
21
|
+
[allNumbers[i], allNumbers[j]] = [allNumbers[j], allNumbers[i]];
|
|
22
|
+
}
|
|
23
|
+
return allNumbers.slice(0, length);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
return Array.from({ length }, () => Math.floor(Math.random() * (max - min + 1)) + min);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const suite = new Benchmark.Suite();
|
|
31
|
+
const avlTree = new AVLTree();
|
|
32
|
+
const { HUNDRED_THOUSAND } = magnitude;
|
|
33
|
+
const randomArray = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND - 1, true);
|
|
34
|
+
suite
|
|
35
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add randomly`, () => {
|
|
36
|
+
avlTree.clear();
|
|
37
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
38
|
+
avlTree.add(randomArray[i]);
|
|
39
|
+
})
|
|
40
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add`, () => {
|
|
41
|
+
avlTree.clear();
|
|
42
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
43
|
+
avlTree.add(i);
|
|
44
|
+
})
|
|
45
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} get`, () => {
|
|
46
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
47
|
+
avlTree.get(randomArray[i]);
|
|
48
|
+
})
|
|
49
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} getNode`, () => {
|
|
50
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
51
|
+
avlTree.getNode(randomArray[i]);
|
|
52
|
+
})
|
|
53
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} iterator`, () => {
|
|
54
|
+
const entries = [...avlTree];
|
|
55
|
+
return entries.length === HUNDRED_THOUSAND;
|
|
56
|
+
})
|
|
57
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & delete orderly`, () => {
|
|
58
|
+
avlTree.clear();
|
|
59
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
60
|
+
avlTree.add(i);
|
|
61
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
62
|
+
avlTree.delete(i);
|
|
63
|
+
})
|
|
64
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & delete randomly`, () => {
|
|
65
|
+
avlTree.clear();
|
|
66
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
67
|
+
avlTree.add(randomArray[i]);
|
|
68
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
69
|
+
avlTree.delete(randomArray[i]);
|
|
70
|
+
});
|
|
71
|
+
export { suite };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { RedBlackTree } from 'data-structure-typed';
|
|
2
|
+
import Benchmark from 'benchmark';
|
|
3
|
+
|
|
4
|
+
const magnitude = {
|
|
5
|
+
THOUSAND: 1000,
|
|
6
|
+
TEN_THOUSAND: 10000,
|
|
7
|
+
HUNDRED_THOUSAND: 100000,
|
|
8
|
+
MILLION: 1000000,
|
|
9
|
+
TEN_MILLION: 10000000,
|
|
10
|
+
BILLION: 100000000
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
function getRandomIntArray(length = 1000, min = -1000, max = 1000, unique = true) {
|
|
14
|
+
if (unique) {
|
|
15
|
+
if (max - min + 1 < length) {
|
|
16
|
+
throw new Error('Range too small for unique values with the specified length');
|
|
17
|
+
}
|
|
18
|
+
const allNumbers = Array.from({ length: max - min + 1 }, (_, i) => i + min);
|
|
19
|
+
for (let i = allNumbers.length - 1; i > 0; i--) {
|
|
20
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
21
|
+
[allNumbers[i], allNumbers[j]] = [allNumbers[j], allNumbers[i]];
|
|
22
|
+
}
|
|
23
|
+
return allNumbers.slice(0, length);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
return Array.from({ length }, () => Math.floor(Math.random() * (max - min + 1)) + min);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const suite = new Benchmark.Suite();
|
|
30
|
+
const rbTree = new RedBlackTree();
|
|
31
|
+
const rbTreeNodeMode = new RedBlackTree([], { isMapMode: false });
|
|
32
|
+
const { HUNDRED_THOUSAND } = magnitude;
|
|
33
|
+
const randomArray = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND - 1, true);
|
|
34
|
+
suite
|
|
35
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add randomly`, () => {
|
|
36
|
+
rbTree.clear();
|
|
37
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
38
|
+
rbTree.add(randomArray[i]);
|
|
39
|
+
})
|
|
40
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add`, () => {
|
|
41
|
+
rbTree.clear();
|
|
42
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
43
|
+
rbTree.add(i);
|
|
44
|
+
})
|
|
45
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} get`, () => {
|
|
46
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
47
|
+
rbTree.get(randomArray[i]);
|
|
48
|
+
})
|
|
49
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} getNode`, () => {
|
|
50
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
51
|
+
rbTree.getNode(randomArray[i]);
|
|
52
|
+
})
|
|
53
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} node mode add randomly`, () => {
|
|
54
|
+
rbTreeNodeMode.clear();
|
|
55
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
56
|
+
rbTreeNodeMode.add(randomArray[i]);
|
|
57
|
+
})
|
|
58
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} node mode get`, () => {
|
|
59
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
60
|
+
rbTreeNodeMode.get(randomArray[i]);
|
|
61
|
+
})
|
|
62
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} iterator`, () => {
|
|
63
|
+
const entries = [...rbTree];
|
|
64
|
+
return entries.length === HUNDRED_THOUSAND;
|
|
65
|
+
})
|
|
66
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & delete orderly`, () => {
|
|
67
|
+
rbTree.clear();
|
|
68
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
69
|
+
rbTree.add(i);
|
|
70
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
71
|
+
rbTree.delete(i);
|
|
72
|
+
})
|
|
73
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & delete randomly`, () => {
|
|
74
|
+
rbTree.clear();
|
|
75
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
76
|
+
rbTree.add(randomArray[i]);
|
|
77
|
+
for (let i = 0; i < randomArray.length; i++)
|
|
78
|
+
rbTree.delete(randomArray[i]);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
export { suite };
|
|
@@ -1,15 +1,268 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
2
|
import * as fs from 'fs';
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
3
|
+
import fastGlob from 'fast-glob';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
5
|
|
|
6
|
+
const isNumber = (value) => {
|
|
7
|
+
return typeof value === 'number';
|
|
8
|
+
};
|
|
9
|
+
const isString = (value) => {
|
|
10
|
+
return typeof value === 'string';
|
|
11
|
+
};
|
|
12
|
+
const isBoolean = (value) => {
|
|
13
|
+
return typeof value === 'boolean';
|
|
14
|
+
};
|
|
15
|
+
const isDate = (value) => {
|
|
16
|
+
return value instanceof Date;
|
|
17
|
+
};
|
|
18
|
+
const isNull = (value) => {
|
|
19
|
+
return value === null;
|
|
20
|
+
};
|
|
21
|
+
const isUndefined = (value) => {
|
|
22
|
+
return typeof value === 'undefined';
|
|
23
|
+
};
|
|
24
|
+
const isFunction = (value) => {
|
|
25
|
+
return typeof value === 'function';
|
|
26
|
+
};
|
|
27
|
+
const isObject = (value) => {
|
|
28
|
+
return typeof value === 'object';
|
|
29
|
+
};
|
|
30
|
+
const isArray = (value) => {
|
|
31
|
+
return Array.isArray(value);
|
|
32
|
+
};
|
|
33
|
+
const isEqual = (objA, objB) => {
|
|
34
|
+
if (objA === objB) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
if (typeof objA !== 'object' || typeof objB !== 'object' || objA === null || objB === null) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
const keysA = Object.keys(objA);
|
|
41
|
+
const keysB = Object.keys(objB);
|
|
42
|
+
if (keysA.length !== keysB.length) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
for (const key of keysA) {
|
|
46
|
+
if (!keysB.includes(key)) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
if (!isEqual(objA[key], objB[key])) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return true;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
function toggleJS(options) {
|
|
57
|
+
if (options === null || options === void 0 ? void 0 : options.plainHtml) {
|
|
58
|
+
return '';
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
return 'onclick="json-to-html.toggleVisibility(this);return false"';
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function makeLabelDiv(options, level, keyName, datatype) {
|
|
65
|
+
if (typeof keyName === 'number') {
|
|
66
|
+
return `<div class='index'><span class='json-to-html-label'>${keyName} </span></div>`;
|
|
67
|
+
}
|
|
68
|
+
else if (typeof keyName === 'string') {
|
|
69
|
+
if (datatype === 'array') {
|
|
70
|
+
return `<div class='collapsible level${level}' ${toggleJS(options)}><span class='json-to-html-label'>${keyName}</span></div>`;
|
|
71
|
+
}
|
|
72
|
+
else if (datatype === 'object') {
|
|
73
|
+
return `<div class='attribute collapsible level${level}' ${toggleJS(options)}><span class='json-to-html-label'>${keyName}:</span></div>`;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
return `<div class='leaf level${level}'><span class='json-to-html-label'>${keyName}:</span></div>`;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
return '';
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function getContentClass(keyName) {
|
|
84
|
+
if (typeof keyName === 'string') {
|
|
85
|
+
return 'content';
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
return '';
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function isPlainObject(val) {
|
|
92
|
+
let lastKey;
|
|
93
|
+
let lastOwnKey;
|
|
94
|
+
for (const key in val) {
|
|
95
|
+
if (val.hasOwnProperty(key)) {
|
|
96
|
+
lastOwnKey = key;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
for (const key in val) {
|
|
100
|
+
lastKey = key;
|
|
101
|
+
}
|
|
102
|
+
return lastOwnKey === lastKey;
|
|
103
|
+
}
|
|
104
|
+
function isLeafValue(val) {
|
|
105
|
+
return (isNumber(val) ||
|
|
106
|
+
isString(val) ||
|
|
107
|
+
isBoolean(val) ||
|
|
108
|
+
isDate(val) ||
|
|
109
|
+
isNull(val) ||
|
|
110
|
+
isUndefined(val) ||
|
|
111
|
+
isNaN(val) ||
|
|
112
|
+
isFunction(val) ||
|
|
113
|
+
!isPlainObject(val));
|
|
114
|
+
}
|
|
115
|
+
function isLeafObject(obj) {
|
|
116
|
+
if (!isObject(obj)) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
for (const key in obj) {
|
|
120
|
+
const val = obj[key];
|
|
121
|
+
if (!isLeafValue(val)) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
function isTable(arr) {
|
|
128
|
+
if (!isArray(arr)) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
if (arr.length === 0 || !isObject(arr[0])) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
let nonCompliant = arr.find(row => !isLeafObject(row));
|
|
136
|
+
if (nonCompliant) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
const cols = Object.keys(arr[0]);
|
|
141
|
+
nonCompliant = arr.find((row) => !isEqual(cols, Object.keys(row)));
|
|
142
|
+
return !nonCompliant;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function drawTable(arr) {
|
|
147
|
+
function drawRow(headers, rowObj) {
|
|
148
|
+
return '<td>' + headers.map(header => rowObj[header]).join('</td><td>') + '</td>';
|
|
149
|
+
}
|
|
150
|
+
const cols = Object.keys(arr[0]);
|
|
151
|
+
const content = arr.map(rowObj => drawRow(cols, rowObj));
|
|
152
|
+
const headingHtml = '<tr><th>' + cols.join('</th><th>') + '</th></tr>';
|
|
153
|
+
const contentHtml = '<tr>' + content.join('</tr><tr>') + '</tr>';
|
|
154
|
+
return '<table style="display: table; width:100%; table-layout: fixed;">' + headingHtml + contentHtml + '</table>';
|
|
155
|
+
}
|
|
156
|
+
function _render(name, data, options, level, altRow) {
|
|
157
|
+
const contentClass = getContentClass(name);
|
|
158
|
+
if (isArray(data)) {
|
|
159
|
+
const title = makeLabelDiv(options, level, `${name}`, 'array');
|
|
160
|
+
let subs;
|
|
161
|
+
if (isTable(data)) {
|
|
162
|
+
subs = drawTable(data);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
subs =
|
|
166
|
+
"<div class='altRows'>" +
|
|
167
|
+
data
|
|
168
|
+
.map((val, idx) => _render(idx.toString(), val, options, level + 1, idx % 2))
|
|
169
|
+
.join("</div><div class='altRows'>") +
|
|
170
|
+
'</div>';
|
|
171
|
+
}
|
|
172
|
+
return `<div class="json-to-html-collapse clearfix ${altRow}">
|
|
173
|
+
${title}
|
|
174
|
+
<div class="${contentClass}">${subs}</div>
|
|
175
|
+
</div>`;
|
|
176
|
+
}
|
|
177
|
+
else if (isLeafValue(data)) {
|
|
178
|
+
const title = makeLabelDiv(options, level, name);
|
|
179
|
+
if (isFunction(data)) {
|
|
180
|
+
return `${title}<span class='json-to-html-value'> -function() can't _render-</span>`;
|
|
181
|
+
}
|
|
182
|
+
else if (!isPlainObject(data)) {
|
|
183
|
+
if (isFunction(data.toString)) {
|
|
184
|
+
return `${title}<span class='json-to-html-value'> ${data.toString()}</span>`;
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
return `${title}<span class='json-to-html-value'> -instance object, can't render-</span>`;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
return `${title}<span class='json-to-html-value'> ${data}</span>`;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
const title = makeLabelDiv(options, level, name, 'object');
|
|
196
|
+
let count = 0;
|
|
197
|
+
const subs = '<div>' +
|
|
198
|
+
Object.entries(data)
|
|
199
|
+
.map(([key, val]) => _render(key, val, options, level + 1, count++ % 2))
|
|
200
|
+
.join('</div><div>') +
|
|
201
|
+
'</div>';
|
|
202
|
+
const inner = `<div class="json-to-html-expand clearfix ${altRow}">
|
|
203
|
+
${title}
|
|
204
|
+
<div class="${contentClass}">${subs}</div>
|
|
205
|
+
</div>`;
|
|
206
|
+
return `${level === 0 ? "<div id='json-to-html'>" : ''}
|
|
207
|
+
${inner}
|
|
208
|
+
${level === 0 ? '</div>' : ''}`;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
export function render(name, json, options) {
|
|
212
|
+
return `${_render(name, json, options, 0, 0)}`;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
217
|
+
const __dirname = path.dirname(__filename);
|
|
218
|
+
|
|
219
|
+
function numberFix(num, decimalPlaces) {
|
|
220
|
+
if (num > 10000 || num < 0.001) {
|
|
221
|
+
const [mantissa, exponent] = num.toExponential().split('e');
|
|
222
|
+
const formattedMantissa = Number(mantissa).toFixed(decimalPlaces);
|
|
223
|
+
return `${formattedMantissa}e${exponent}`;
|
|
224
|
+
} else {
|
|
225
|
+
return num.toFixed(decimalPlaces);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
const ConsoleColor = {
|
|
229
|
+
END: '\x1b[0m',
|
|
230
|
+
BOLD: '\x1b[1m',
|
|
231
|
+
DIM: '\x1b[2m',
|
|
232
|
+
ITALIC: '\x1b[3m',
|
|
233
|
+
UNDERLINE: '\x1b[4m',
|
|
234
|
+
INVERSE: '\x1b[7m',
|
|
235
|
+
STRIKETHROUGH: '\x1b[9m',
|
|
236
|
+
NO_BOLD: '\x1b[22m',
|
|
237
|
+
NO_ITALIC: '\x1b[23m',
|
|
238
|
+
NO_UNDERLINE: '\x1b[24m',
|
|
239
|
+
NO_INVERSE: '\x1b[27m',
|
|
240
|
+
NO_STRIKETHROUGH: '\x1b[29m',
|
|
241
|
+
BLACK: '\x1b[30m',
|
|
242
|
+
RED: '\x1b[31m',
|
|
243
|
+
GREEN: '\x1b[32m',
|
|
244
|
+
YELLOW: '\x1b[33m',
|
|
245
|
+
BLUE: '\x1b[34m',
|
|
246
|
+
MAGENTA: '\x1b[35m',
|
|
247
|
+
GRAY: '\x1b[90m',
|
|
248
|
+
CYAN: '\x1b[36m',
|
|
249
|
+
WHITE: '\x1b[37m',
|
|
250
|
+
BG_BLACK: '\x1b[40m',
|
|
251
|
+
BG_RED: '\x1b[41m',
|
|
252
|
+
BG_GREEN: '\x1b[42m',
|
|
253
|
+
BG_YELLOW: '\x1b[43m',
|
|
254
|
+
BG_BLUE: '\x1b[44m',
|
|
255
|
+
BG_MAGENTA: '\x1b[45m',
|
|
256
|
+
BG_CYAN: '\x1b[46m',
|
|
257
|
+
BG_WHITE: '\x1b[47m'
|
|
258
|
+
};
|
|
6
259
|
const args = process.argv.slice(2);
|
|
7
260
|
const { GREEN, BOLD, END, YELLOW, GRAY, CYAN, BG_YELLOW } = ConsoleColor;
|
|
8
261
|
const isOnlyOrdered = true;
|
|
9
262
|
const runOrder = [
|
|
10
263
|
'heap',
|
|
11
264
|
'avl-tree',
|
|
12
|
-
'
|
|
265
|
+
'red-black-tree',
|
|
13
266
|
'doubly-linked-list',
|
|
14
267
|
'directed-graph',
|
|
15
268
|
'queue',
|
|
@@ -25,6 +278,7 @@ const getRelativePath = file => {
|
|
|
25
278
|
return path.relative(__dirname, file);
|
|
26
279
|
};
|
|
27
280
|
const coloredLabeled = (label, file) => {
|
|
281
|
+
|
|
28
282
|
const relativeFilePath = getRelativePath(file);
|
|
29
283
|
const directory = path.dirname(relativeFilePath);
|
|
30
284
|
const fileName = path.basename(relativeFilePath);
|
|
@@ -33,7 +287,8 @@ const coloredLabeled = (label, file) => {
|
|
|
33
287
|
const parentDirectory = path.resolve(__dirname, '../..');
|
|
34
288
|
const reportDistPath = path.join(parentDirectory, 'benchmark');
|
|
35
289
|
const testDir = path.join(__dirname, 'data-structures');
|
|
36
|
-
|
|
290
|
+
let allFiles = fastGlob.sync(path.join(testDir, '**', '*.test.mjs'));
|
|
291
|
+
|
|
37
292
|
let testFiles;
|
|
38
293
|
let isIndividual = false;
|
|
39
294
|
if (args.length > 0) {
|
|
@@ -51,9 +306,9 @@ if (args.length > 0) {
|
|
|
51
306
|
const report = {};
|
|
52
307
|
let completedCount = 0;
|
|
53
308
|
const performanceTests = [];
|
|
54
|
-
|
|
55
|
-
const testName = path.basename(file, '.test.
|
|
56
|
-
const testFunction =
|
|
309
|
+
for (const file of testFiles) {
|
|
310
|
+
const testName = path.basename(file, '.test.mjs');
|
|
311
|
+
const testFunction = await import(file);
|
|
57
312
|
const { suite } = testFunction;
|
|
58
313
|
if (suite)
|
|
59
314
|
performanceTests.push({
|
|
@@ -61,7 +316,8 @@ testFiles.forEach(file => {
|
|
|
61
316
|
suite,
|
|
62
317
|
file
|
|
63
318
|
});
|
|
64
|
-
}
|
|
319
|
+
}
|
|
320
|
+
|
|
65
321
|
const composeReport = () => {
|
|
66
322
|
if (!fs.existsSync(reportDistPath))
|
|
67
323
|
fs.mkdirSync(reportDistPath, {
|
|
@@ -91,7 +91,7 @@ describe('AVLTreeCounter operations test1', () => {
|
|
|
91
91
|
expect(minNodeBySpecificNode?.key).toBe(15);
|
|
92
92
|
|
|
93
93
|
let subTreeSum = 0;
|
|
94
|
-
if (node15) avlCounter.dfs(node => (subTreeSum += node.key), 'PRE', 15);
|
|
94
|
+
if (node15) avlCounter.dfs(node => (subTreeSum += node.key), 'PRE', false, 15);
|
|
95
95
|
expect(subTreeSum).toBe(31);
|
|
96
96
|
let lesserSum = 0;
|
|
97
97
|
avlCounter.lesserOrGreaterTraverse((node: AVLTreeCounterNode<number>) => (lesserSum += node.key), -1, 10);
|
|
@@ -99,7 +99,7 @@ describe('AVLTreeCounter operations test1', () => {
|
|
|
99
99
|
|
|
100
100
|
expect(node15 instanceof AVLTreeCounterNode);
|
|
101
101
|
if (node15 instanceof AVLTreeCounterNode) {
|
|
102
|
-
const subTreeAdd = avlCounter.dfs(node => (node.count += 1), 'PRE', 15);
|
|
102
|
+
const subTreeAdd = avlCounter.dfs(node => (node.count += 1), 'PRE', false, 15);
|
|
103
103
|
expect(subTreeAdd);
|
|
104
104
|
}
|
|
105
105
|
const node11 = avlCounter.getNode(11);
|
|
@@ -347,7 +347,7 @@ describe('AVLTreeCounter operations test recursively1', () => {
|
|
|
347
347
|
expect(minNodeBySpecificNode?.key).toBe(15);
|
|
348
348
|
|
|
349
349
|
let subTreeSum = 0;
|
|
350
|
-
if (node15) avlCounter.dfs(node => (subTreeSum += node.key), 'PRE', 15);
|
|
350
|
+
if (node15) avlCounter.dfs(node => (subTreeSum += node.key), 'PRE', false, 15);
|
|
351
351
|
expect(subTreeSum).toBe(31);
|
|
352
352
|
let lesserSum = 0;
|
|
353
353
|
avlCounter.lesserOrGreaterTraverse((node: AVLTreeCounterNode<number>) => (lesserSum += node.key), -1, 10);
|
|
@@ -355,7 +355,7 @@ describe('AVLTreeCounter operations test recursively1', () => {
|
|
|
355
355
|
|
|
356
356
|
expect(node15 instanceof AVLTreeCounterNode);
|
|
357
357
|
if (node15 instanceof AVLTreeCounterNode) {
|
|
358
|
-
const subTreeAdd = avlCounter.dfs(node => (node.count += 1), 'PRE', 15);
|
|
358
|
+
const subTreeAdd = avlCounter.dfs(node => (node.count += 1), 'PRE', false, 15);
|
|
359
359
|
expect(subTreeAdd);
|
|
360
360
|
}
|
|
361
361
|
const node11 = avlCounter.getNode(11);
|
|
@@ -709,7 +709,7 @@ describe('AVLTreeCounter toEntryFn', () => {
|
|
|
709
709
|
|
|
710
710
|
expect(avlCounter.morris(node => node.key, 'IN')).toEqual(expected);
|
|
711
711
|
expect(avlCounter.dfs(node => node.key, 'IN')).toEqual(expected);
|
|
712
|
-
expect(avlCounter.dfs(node => node.key, 'IN', avlCounter.root, 'RECURSIVE')).toEqual(expected);
|
|
712
|
+
expect(avlCounter.dfs(node => node.key, 'IN', false, avlCounter.root, 'RECURSIVE')).toEqual(expected);
|
|
713
713
|
});
|
|
714
714
|
|
|
715
715
|
it('should toEntryFn 2', () => {
|
|
@@ -724,7 +724,7 @@ describe('AVLTreeCounter toEntryFn', () => {
|
|
|
724
724
|
|
|
725
725
|
expect(avlCounter.morris(node => node.key, 'IN')).toEqual(expected);
|
|
726
726
|
expect(avlCounter.dfs(node => node.key, 'IN')).toEqual(expected);
|
|
727
|
-
expect(avlCounter.dfs(node => node.key, 'IN', avlCounter.root, 'RECURSIVE')).toEqual(expected);
|
|
727
|
+
expect(avlCounter.dfs(node => node.key, 'IN', false, avlCounter.root, 'RECURSIVE')).toEqual(expected);
|
|
728
728
|
});
|
|
729
729
|
|
|
730
730
|
it('should toEntryFn throw error', () => {
|
|
@@ -760,7 +760,7 @@ describe('AVLTreeCounter toEntryFn', () => {
|
|
|
760
760
|
|
|
761
761
|
expect(avlCounter.morris(node => node.key, 'IN')).toEqual(expected);
|
|
762
762
|
expect(avlCounter.dfs(node => node.key, 'IN')).toEqual(expected);
|
|
763
|
-
expect(avlCounter.dfs(node => node.key, 'IN', avlCounter.root, 'RECURSIVE')).toEqual(expected);
|
|
763
|
+
expect(avlCounter.dfs(node => node.key, 'IN', false, avlCounter.root, 'RECURSIVE')).toEqual(expected);
|
|
764
764
|
});
|
|
765
765
|
});
|
|
766
766
|
|
|
@@ -50,7 +50,7 @@ describe('AVLTreeMultiMap Test', () => {
|
|
|
50
50
|
expect(getMinNodeBySpecificNode?.key).toBe(12);
|
|
51
51
|
|
|
52
52
|
let subTreeSum = 0;
|
|
53
|
-
if (node15) avlTmm.dfs(node => (subTreeSum += node.key), 'PRE', node15);
|
|
53
|
+
if (node15) avlTmm.dfs(node => (subTreeSum += node.key), 'PRE', false, node15);
|
|
54
54
|
expect(subTreeSum).toBe(70);
|
|
55
55
|
|
|
56
56
|
let lesserSum = 0;
|
|
@@ -176,7 +176,7 @@ describe('AVLTreeMultiMap Test recursively', () => {
|
|
|
176
176
|
expect(getMinNodeBySpecificNode?.key).toBe(12);
|
|
177
177
|
|
|
178
178
|
let subTreeSum = 0;
|
|
179
|
-
if (node15) avlTmm.dfs(node => (subTreeSum += node.key), 'PRE', node15);
|
|
179
|
+
if (node15) avlTmm.dfs(node => (subTreeSum += node.key), 'PRE', false, node15);
|
|
180
180
|
expect(subTreeSum).toBe(70);
|
|
181
181
|
|
|
182
182
|
let lesserSum = 0;
|
|
@@ -509,7 +509,7 @@ describe('AVLTreeMultiMap not map mode', () => {
|
|
|
509
509
|
expect(getMinNodeBySpecificNode?.key).toBe(12);
|
|
510
510
|
|
|
511
511
|
let subTreeSum = 0;
|
|
512
|
-
if (node15) avlTmm.dfs(node => (subTreeSum += node.key), 'PRE', node15);
|
|
512
|
+
if (node15) avlTmm.dfs(node => (subTreeSum += node.key), 'PRE', false, node15);
|
|
513
513
|
expect(subTreeSum).toBe(70);
|
|
514
514
|
|
|
515
515
|
let lesserSum = 0;
|
|
@@ -527,7 +527,6 @@ describe('AVLTreeMultiMap not map mode test recursively', () => {
|
|
|
527
527
|
const avlTmm = new AVLTreeMultiMap<number>([], { iterationType: 'RECURSIVE' });
|
|
528
528
|
|
|
529
529
|
for (const i of arr) avlTmm.add([i, [i]]);
|
|
530
|
-
|
|
531
530
|
const node6 = avlTmm.getNode(6);
|
|
532
531
|
|
|
533
532
|
expect(node6 && avlTmm.getHeight(node6)).toBe(3);
|
|
@@ -544,7 +543,7 @@ describe('AVLTreeMultiMap not map mode test recursively', () => {
|
|
|
544
543
|
expect(getMinNodeBySpecificNode?.key).toBe(12);
|
|
545
544
|
|
|
546
545
|
let subTreeSum = 0;
|
|
547
|
-
if (node15) avlTmm.dfs(node => (subTreeSum += node.key), 'PRE', node15);
|
|
546
|
+
if (node15) avlTmm.dfs(node => (subTreeSum += node.key), 'PRE', false, node15);
|
|
548
547
|
expect(subTreeSum).toBe(70);
|
|
549
548
|
|
|
550
549
|
let lesserSum = 0;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AVLTree, AVLTreeNode, BinaryTreeNode, BSTNode } from '../../../../src';
|
|
1
|
+
import { AVLTree, AVLTreeNode, BinaryTreeNode, BSTNode, Range } from '../../../../src';
|
|
2
2
|
|
|
3
3
|
describe('AVL Tree Test', () => {
|
|
4
4
|
it('should perform various operations on a AVL Tree', () => {
|
|
@@ -24,7 +24,7 @@ describe('AVL Tree Test', () => {
|
|
|
24
24
|
expect(getMinNodeBySpecificNode?.key).toBe(12);
|
|
25
25
|
|
|
26
26
|
let subTreeSum = 0;
|
|
27
|
-
if (node15) avlTree.dfs(node => (subTreeSum += node.key), 'PRE', node15);
|
|
27
|
+
if (node15) avlTree.dfs(node => (subTreeSum += node.key), 'PRE', false, node15);
|
|
28
28
|
expect(subTreeSum).toBe(70);
|
|
29
29
|
|
|
30
30
|
let lesserSum = 0;
|
|
@@ -150,7 +150,7 @@ describe('AVL Tree Test recursively', () => {
|
|
|
150
150
|
expect(getMinNodeBySpecificNode?.key).toBe(12);
|
|
151
151
|
|
|
152
152
|
let subTreeSum = 0;
|
|
153
|
-
if (node15) avlTree.dfs(node => (subTreeSum += node.key), 'PRE', node15);
|
|
153
|
+
if (node15) avlTree.dfs(node => (subTreeSum += node.key), 'PRE', false, node15);
|
|
154
154
|
expect(subTreeSum).toBe(70);
|
|
155
155
|
|
|
156
156
|
let lesserSum = 0;
|
|
@@ -480,7 +480,7 @@ describe('AVL Tree not map mode', () => {
|
|
|
480
480
|
expect(getMinNodeBySpecificNode?.key).toBe(12);
|
|
481
481
|
|
|
482
482
|
let subTreeSum = 0;
|
|
483
|
-
if (node15) avlTree.dfs(node => (subTreeSum += node.key), 'PRE', node15);
|
|
483
|
+
if (node15) avlTree.dfs(node => (subTreeSum += node.key), 'PRE', false, node15);
|
|
484
484
|
expect(subTreeSum).toBe(70);
|
|
485
485
|
|
|
486
486
|
let lesserSum = 0;
|
|
@@ -515,7 +515,7 @@ describe('AVL Tree not map mode test recursively', () => {
|
|
|
515
515
|
expect(getMinNodeBySpecificNode?.key).toBe(12);
|
|
516
516
|
|
|
517
517
|
let subTreeSum = 0;
|
|
518
|
-
if (node15) avlTree.dfs(node => (subTreeSum += node.key), 'PRE', node15);
|
|
518
|
+
if (node15) avlTree.dfs(node => (subTreeSum += node.key), 'PRE', false, node15);
|
|
519
519
|
expect(subTreeSum).toBe(70);
|
|
520
520
|
|
|
521
521
|
let lesserSum = 0;
|
|
@@ -542,3 +542,70 @@ describe('AVLTree iterative methods not map mode', () => {
|
|
|
542
542
|
expect(cloned.get(cloned.root?.right?.key)).toBe('c');
|
|
543
543
|
});
|
|
544
544
|
});
|
|
545
|
+
|
|
546
|
+
describe('classic use', () => {
|
|
547
|
+
// Test case for finding elements in a given range
|
|
548
|
+
it('@example Find elements in a range', () => {
|
|
549
|
+
type Datum = { timestamp: Date; temperature: number };
|
|
550
|
+
// Fixed dataset of CPU temperature readings
|
|
551
|
+
const cpuData: Datum[] = [
|
|
552
|
+
{ timestamp: new Date('2024-12-02T00:00:00'), temperature: 55.1 },
|
|
553
|
+
{ timestamp: new Date('2024-12-02T00:01:00'), temperature: 56.3 },
|
|
554
|
+
{ timestamp: new Date('2024-12-02T00:02:00'), temperature: 54.8 },
|
|
555
|
+
{ timestamp: new Date('2024-12-02T00:03:00'), temperature: 57.2 },
|
|
556
|
+
{ timestamp: new Date('2024-12-02T00:04:00'), temperature: 58.0 },
|
|
557
|
+
{ timestamp: new Date('2024-12-02T00:05:00'), temperature: 59.4 },
|
|
558
|
+
{ timestamp: new Date('2024-12-02T00:06:00'), temperature: 60.1 },
|
|
559
|
+
{ timestamp: new Date('2024-12-02T00:07:00'), temperature: 61.3 },
|
|
560
|
+
{ timestamp: new Date('2024-12-02T00:08:00'), temperature: 62.0 },
|
|
561
|
+
{ timestamp: new Date('2024-12-02T00:09:00'), temperature: 63.5 },
|
|
562
|
+
{ timestamp: new Date('2024-12-02T00:10:00'), temperature: 64.0 },
|
|
563
|
+
{ timestamp: new Date('2024-12-02T00:11:00'), temperature: 62.8 },
|
|
564
|
+
{ timestamp: new Date('2024-12-02T00:12:00'), temperature: 61.5 },
|
|
565
|
+
{ timestamp: new Date('2024-12-02T00:13:00'), temperature: 60.2 },
|
|
566
|
+
{ timestamp: new Date('2024-12-02T00:14:00'), temperature: 59.8 },
|
|
567
|
+
{ timestamp: new Date('2024-12-02T00:15:00'), temperature: 58.6 },
|
|
568
|
+
{ timestamp: new Date('2024-12-02T00:16:00'), temperature: 57.4 },
|
|
569
|
+
{ timestamp: new Date('2024-12-02T00:17:00'), temperature: 56.2 },
|
|
570
|
+
{ timestamp: new Date('2024-12-02T00:18:00'), temperature: 55.7 },
|
|
571
|
+
{ timestamp: new Date('2024-12-02T00:19:00'), temperature: 54.5 },
|
|
572
|
+
{ timestamp: new Date('2024-12-02T00:20:00'), temperature: 53.2 },
|
|
573
|
+
{ timestamp: new Date('2024-12-02T00:21:00'), temperature: 52.8 },
|
|
574
|
+
{ timestamp: new Date('2024-12-02T00:22:00'), temperature: 51.9 },
|
|
575
|
+
{ timestamp: new Date('2024-12-02T00:23:00'), temperature: 50.5 },
|
|
576
|
+
{ timestamp: new Date('2024-12-02T00:24:00'), temperature: 49.8 },
|
|
577
|
+
{ timestamp: new Date('2024-12-02T00:25:00'), temperature: 48.7 },
|
|
578
|
+
{ timestamp: new Date('2024-12-02T00:26:00'), temperature: 47.5 },
|
|
579
|
+
{ timestamp: new Date('2024-12-02T00:27:00'), temperature: 46.3 },
|
|
580
|
+
{ timestamp: new Date('2024-12-02T00:28:00'), temperature: 45.9 },
|
|
581
|
+
{ timestamp: new Date('2024-12-02T00:29:00'), temperature: 45.0 }
|
|
582
|
+
];
|
|
583
|
+
|
|
584
|
+
// Create an AVL tree to store CPU temperature data
|
|
585
|
+
const cpuTemperatureTree = new AVLTree<Date, number, Datum>(cpuData, {
|
|
586
|
+
toEntryFn: ({ timestamp, temperature }) => [timestamp, temperature]
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
// Query a specific time range (e.g., from 00:05 to 00:15)
|
|
590
|
+
const rangeStart = new Date('2024-12-02T00:05:00');
|
|
591
|
+
const rangeEnd = new Date('2024-12-02T00:15:00');
|
|
592
|
+
const rangeResults = cpuTemperatureTree.rangeSearch([rangeStart, rangeEnd], node => ({
|
|
593
|
+
minute: node ? node.key.getMinutes() : 0,
|
|
594
|
+
temperature: cpuTemperatureTree.get(node ? node.key : undefined)
|
|
595
|
+
}));
|
|
596
|
+
|
|
597
|
+
expect(rangeResults).toEqual( [
|
|
598
|
+
{ minute: 5, temperature: 59.4 },
|
|
599
|
+
{ minute: 6, temperature: 60.1 },
|
|
600
|
+
{ minute: 7, temperature: 61.3 },
|
|
601
|
+
{ minute: 8, temperature: 62 },
|
|
602
|
+
{ minute: 9, temperature: 63.5 },
|
|
603
|
+
{ minute: 10, temperature: 64 },
|
|
604
|
+
{ minute: 11, temperature: 62.8 },
|
|
605
|
+
{ minute: 12, temperature: 61.5 },
|
|
606
|
+
{ minute: 13, temperature: 60.2 },
|
|
607
|
+
{ minute: 14, temperature: 59.8 },
|
|
608
|
+
{ minute: 15, temperature: 58.6 }
|
|
609
|
+
]);
|
|
610
|
+
});
|
|
611
|
+
});
|