data-structure-typed 1.41.2 → 1.41.4

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.
Files changed (77) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +57 -0
  3. package/benchmark/report.html +73 -0
  4. package/benchmark/report.json +239 -0
  5. package/dist/cjs/data-structures/binary-tree/binary-tree.js +11 -10
  6. package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
  7. package/dist/mjs/data-structures/binary-tree/binary-tree.js +11 -10
  8. package/dist/umd/data-structure-typed.min.js +1 -1
  9. package/dist/umd/data-structure-typed.min.js.map +1 -1
  10. package/jest.integration.config.js +5 -0
  11. package/package.json +13 -8
  12. package/src/data-structures/binary-tree/binary-tree.ts +12 -9
  13. package/test/config.ts +1 -1
  14. package/test/performance/data-structures/binary-tree/avl-tree.test.ts +24 -0
  15. package/test/performance/data-structures/binary-tree/binary-index-tree.test.ts +0 -0
  16. package/test/performance/data-structures/binary-tree/binary-tree.test.ts +25 -0
  17. package/test/performance/data-structures/binary-tree/bst.test.ts +24 -0
  18. package/test/performance/data-structures/binary-tree/overall.test.ts +0 -0
  19. package/test/performance/data-structures/binary-tree/rb-tree.test.ts +0 -0
  20. package/test/performance/data-structures/binary-tree/segment-tree.test.ts +0 -0
  21. package/test/performance/data-structures/binary-tree/tree-multiset.test.ts +0 -0
  22. package/test/performance/data-structures/graph/abstract-graph.test.ts +0 -0
  23. package/test/performance/data-structures/graph/directed-graph.test.ts +0 -0
  24. package/test/performance/data-structures/graph/map-graph.test.ts +0 -0
  25. package/test/performance/data-structures/graph/overall.test.ts +0 -0
  26. package/test/performance/data-structures/graph/undirected-graph.test.ts +0 -0
  27. package/test/performance/data-structures/hash/coordinate-map.test.ts +0 -0
  28. package/test/performance/data-structures/hash/coordinate-set.test.ts +0 -0
  29. package/test/performance/data-structures/hash/hash-map.test.ts +0 -0
  30. package/test/performance/data-structures/hash/hash-table.test.ts +0 -0
  31. package/test/performance/data-structures/heap/heap.test.ts +30 -0
  32. package/test/performance/data-structures/heap/max-heap.test.ts +0 -0
  33. package/test/performance/data-structures/heap/min-heap.test.ts +0 -0
  34. package/test/performance/data-structures/linked-list/doubly-linked-list.test.ts +40 -0
  35. package/test/performance/data-structures/linked-list/linked-list.test.ts +0 -0
  36. package/test/performance/data-structures/linked-list/singly-linked-list.test.ts +34 -0
  37. package/test/performance/data-structures/linked-list/skip-linked-list.test.ts +0 -0
  38. package/test/performance/data-structures/linked-list/skip-list.test.ts +0 -0
  39. package/test/performance/data-structures/matrix/matrix.test.ts +0 -0
  40. package/test/performance/data-structures/matrix/matrix2d.test.ts +0 -0
  41. package/test/performance/data-structures/matrix/navigator.test.ts +0 -0
  42. package/test/performance/data-structures/matrix/vector2d.test.ts +0 -0
  43. package/test/performance/data-structures/priority-queue/max-priority-queue.test.ts +19 -0
  44. package/test/performance/data-structures/priority-queue/min-priority-queue.test.ts +0 -0
  45. package/test/performance/data-structures/priority-queue/priority-queue.test.ts +0 -0
  46. package/test/performance/data-structures/queue/deque.test.ts +21 -0
  47. package/test/performance/data-structures/queue/queue.test.ts +25 -0
  48. package/test/performance/data-structures/stack/stack.test.ts +0 -0
  49. package/test/performance/data-structures/tree/tree.test.ts +0 -0
  50. package/test/performance/data-structures/trie/trie.test.ts +0 -0
  51. package/test/performance/reportor.ts +174 -0
  52. package/test/performance/types/index.ts +1 -0
  53. package/test/performance/types/reportor.ts +3 -0
  54. package/test/types/utils/index.ts +1 -0
  55. package/test/types/utils/json2html.ts +1 -0
  56. package/test/unit/data-structures/binary-tree/rb-tree.test.ts +5 -5
  57. package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +0 -23
  58. package/test/unit/data-structures/linked-list/linked-list.test.ts +3 -30
  59. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +0 -21
  60. package/test/unit/data-structures/matrix/matrix2d.test.ts +1 -1
  61. package/test/unit/data-structures/priority-queue/max-priority-queue.test.ts +0 -32
  62. package/test/unit/data-structures/priority-queue/priority-queue.test.ts +2 -2
  63. package/test/unit/data-structures/queue/queue.test.ts +3 -39
  64. package/test/utils/array.ts +5 -0
  65. package/test/utils/big-o.ts +7 -7
  66. package/test/utils/console.ts +30 -0
  67. package/test/utils/index.ts +4 -0
  68. package/test/utils/is.ts +56 -0
  69. package/test/utils/json2html.ts +322 -0
  70. package/test/utils/number.ts +11 -1
  71. package/test/config.js +0 -4
  72. package/test/types/index.js +0 -29
  73. package/test/types/utils/big-o.js +0 -2
  74. package/test/types/utils/index.js +0 -29
  75. package/test/utils/big-o.js +0 -222
  76. package/test/utils/index.js +0 -30
  77. package/test/utils/number.js +0 -14
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ preset: 'ts-jest',
3
+ testEnvironment: 'node',
4
+ testMatch: ['<rootDir>/test/integration/**/*.test.ts', '<rootDir>/test/integration/**/*.test.js'],
5
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "data-structure-typed",
3
- "version": "1.41.2",
3
+ "version": "1.41.4",
4
4
  "description": "Data Structures of Javascript & TypeScript. Binary Tree, BST, Graph, Heap, Priority Queue, Linked List, Queue, Deque, Stack, AVL Tree, Tree Multiset, Trie, Directed Graph, Undirected Graph, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/mjs/index.js",
@@ -31,15 +31,17 @@
31
31
  "reformat": "npm run reformat:src && npm run reformat:test",
32
32
  "update:subs": "npm i avl-tree-typed binary-tree-typed bst-typed heap-typed --save-dev",
33
33
  "install:all-subs": "npm i avl-tree-typed binary-tree-typed bst-typed deque-typed directed-graph-typed doubly-linked-list-typed graph-typed heap-typed linked-list-typed max-heap-typed max-priority-queue-typed min-heap-typed min-priority-queue-typed priority-queue-typed singly-linked-list-typed stack-typed tree-multiset-typed trie-typed undirected-graph-typed queue-typed --save-dev",
34
- "test": "jest",
34
+ "test": "jest --runInBand",
35
+ "test:integration": "npm run update:subs && jest --config jest.integration.config.js",
36
+ "benchmark": "ts-node test/performance/reportor.ts",
35
37
  "check:deps": "dependency-cruiser src",
36
38
  "changelog": "auto-changelog",
37
39
  "coverage:badge": "istanbul-badges-readme",
38
- "ci": "env && git fetch --tags && npm run check && npm run lint && npm run build && npm run update:subs && npm run test && npm run changelog",
40
+ "ci": "env && git fetch --tags && npm run check && npm run lint && npm run build && npm run test && npm run changelog",
39
41
  "copy:to-subs": "sh scripts/copy_to_all_subs.sh",
40
42
  "publish:subs": "npm run copy:to-subs && sh scripts/publish_all_subs.sh",
41
43
  "publish:docs": "sh scripts/publish_docs.sh",
42
- "publish:all": "npm run ci && npm publish && npm run publish:docs && npm run publish:subs"
44
+ "publish:all": "npm run ci && npm run benchmark && npm publish && npm run publish:docs && npm run publish:subs"
43
45
  },
44
46
  "repository": {
45
47
  "type": "git",
@@ -58,25 +60,28 @@
58
60
  "@types/benchmark": "^2.1.3",
59
61
  "@types/jest": "^29.5.5",
60
62
  "@types/node": "^20.8.2",
63
+ "@types/underscore": "^1.11.12",
61
64
  "@typescript-eslint/eslint-plugin": "^6.7.4",
62
65
  "@typescript-eslint/parser": "^6.7.4",
63
66
  "auto-changelog": "^2.4.0",
64
- "avl-tree-typed": "^1.41.1",
67
+ "avl-tree-typed": "^1.41.2",
65
68
  "benchmark": "^2.1.4",
66
- "binary-tree-typed": "^1.41.1",
67
- "bst-typed": "^1.41.1",
69
+ "binary-tree-typed": "^1.41.2",
70
+ "bst-typed": "^1.41.2",
68
71
  "dependency-cruiser": "^14.1.0",
69
72
  "eslint": "^8.50.0",
70
73
  "eslint-config-prettier": "^9.0.0",
71
74
  "eslint-import-resolver-alias": "^1.1.2",
72
75
  "eslint-import-resolver-typescript": "^3.6.1",
73
76
  "eslint-plugin-import": "^2.28.1",
74
- "heap-typed": "^1.41.1",
77
+ "fast-glob": "^3.3.1",
78
+ "heap-typed": "^1.41.2",
75
79
  "istanbul-badges-readme": "^1.8.5",
76
80
  "jest": "^29.7.0",
77
81
  "prettier": "^3.0.3",
78
82
  "ts-jest": "^29.1.1",
79
83
  "ts-loader": "^9.4.4",
84
+ "ts-node": "^10.9.1",
80
85
  "tsup": "^7.2.0",
81
86
  "typedoc": "^0.25.1",
82
87
  "typescript": "^5.2.2"
@@ -179,7 +179,10 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
179
179
  while (queue.size > 0) {
180
180
  const cur = queue.shift();
181
181
  if (cur) {
182
- if (newNode && cur.key === newNode.key) return;
182
+ if (newNode && cur.key === newNode.key) {
183
+ cur.value = newNode.value;
184
+ return;
185
+ }
183
186
  const inserted = this._addTo(newNode, cur);
184
187
  if (inserted !== undefined) return inserted;
185
188
  if (cur.left) queue.push(cur.left);
@@ -201,16 +204,16 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
201
204
  return;
202
205
  }
203
206
 
204
- const key = typeof keyOrNode === 'number' ? keyOrNode : keyOrNode ? keyOrNode.key : undefined;
205
- const existNode = key !== undefined ? this.getNode(key, (node: N) => node.key) : undefined;
207
+ // const key = typeof keyOrNode === 'number' ? keyOrNode : keyOrNode ? keyOrNode.key : undefined;
208
+ // const existNode = key !== undefined ? this.getNode(key, (node: N) => node.key) : undefined;
206
209
 
207
210
  if (this.root) {
208
- if (existNode) {
209
- existNode.value = value;
210
- inserted = existNode;
211
- } else {
212
- inserted = _bfs(this.root, needInsert);
213
- }
211
+ // if (existNode) {
212
+ // existNode.value = value;
213
+ // inserted = existNode;
214
+ // } else {
215
+ inserted = _bfs(this.root, needInsert);
216
+ // }
214
217
  } else {
215
218
  this._setRoot(needInsert);
216
219
  if (needInsert !== null) {
package/test/config.ts CHANGED
@@ -1 +1 @@
1
- export const isDebugTest = true;
1
+ export const isDebugTest = false;
@@ -0,0 +1,24 @@
1
+ import {AVLTree} from '../../../../src';
2
+ import * as Benchmark from 'benchmark';
3
+ import {magnitude, randomInt, randomIntArray} from '../../../utils';
4
+
5
+ const suite = new Benchmark.Suite();
6
+ const avl = new AVLTree<number>();
7
+ const {N_LOG_N} = magnitude;
8
+
9
+ suite
10
+ .add(`add ${N_LOG_N} randomly`, () => {
11
+ for (let i = 0; i < N_LOG_N; i++) avl.add(randomInt(0, N_LOG_N));
12
+ })
13
+ .add(`delete ${N_LOG_N} randomly`, () => {
14
+ for (let i = 0; i < N_LOG_N; i++) avl.delete(randomInt(0, N_LOG_N));
15
+ })
16
+ .add(`addMany ${N_LOG_N}`, () => {
17
+ const arr = randomIntArray(N_LOG_N);
18
+ avl.addMany(arr);
19
+ })
20
+ .add(`get ${N_LOG_N}`, () => {
21
+ for (let i = 0; i < N_LOG_N; i++) avl.get(randomInt(-N_LOG_N, N_LOG_N));
22
+ });
23
+
24
+ export {suite};
@@ -0,0 +1,25 @@
1
+ import {BinaryTree} from '../../../../src';
2
+ import * as Benchmark from 'benchmark';
3
+ import {magnitude, randomInt, randomIntArray} from '../../../utils';
4
+
5
+ const suite = new Benchmark.Suite();
6
+ const biTree = new BinaryTree<number>();
7
+ const {N_LOG_N} = magnitude;
8
+
9
+ suite
10
+ .add(`add ${N_LOG_N}`, () => {
11
+ for (let i = 0; i < N_LOG_N; i++) biTree.add(randomInt(-N_LOG_N, N_LOG_N));
12
+ })
13
+ .add(`delete ${N_LOG_N}`, () => {
14
+ for (let i = 0; i < N_LOG_N; i++) biTree.delete(randomInt(-N_LOG_N, N_LOG_N));
15
+ })
16
+ .add(`addMany ${N_LOG_N}`, () => {
17
+ biTree.clear();
18
+ const arr = randomIntArray(N_LOG_N);
19
+ biTree.addMany(arr);
20
+ })
21
+ .add(`get ${N_LOG_N}`, () => {
22
+ for (let i = 0; i < N_LOG_N; i++) biTree.get(randomInt(-N_LOG_N, N_LOG_N));
23
+ });
24
+
25
+ export {suite};
@@ -0,0 +1,24 @@
1
+ import {BST} from '../../../../src';
2
+ import * as Benchmark from 'benchmark';
3
+ import {magnitude, randomInt, randomIntArray} from '../../../utils';
4
+
5
+ const suite = new Benchmark.Suite();
6
+ const bst = new BST<number>();
7
+ const {N_LOG_N} = magnitude;
8
+
9
+ suite
10
+ .add(`add ${N_LOG_N} randomly`, () => {
11
+ for (let i = 0; i < N_LOG_N; i++) bst.add(randomInt(0, N_LOG_N));
12
+ })
13
+ .add(`delete ${N_LOG_N} randomly`, () => {
14
+ for (let i = 0; i < N_LOG_N; i++) bst.delete(randomInt(0, N_LOG_N));
15
+ })
16
+ .add(`addMany ${N_LOG_N} balanced`, () => {
17
+ const arr = randomIntArray(N_LOG_N);
18
+ bst.addMany(arr);
19
+ })
20
+ .add(`get ${N_LOG_N}`, () => {
21
+ for (let i = 0; i < N_LOG_N; i++) bst.get(randomInt(-N_LOG_N, N_LOG_N));
22
+ });
23
+
24
+ export {suite};
@@ -0,0 +1,30 @@
1
+ import {FibonacciHeap, Heap} from '../../../../src';
2
+ import * as Benchmark from 'benchmark';
3
+ import {magnitude} from '../../../utils';
4
+
5
+ const suite = new Benchmark.Suite();
6
+ const {N_LOG_N} = magnitude;
7
+
8
+ suite
9
+ .add(`add & ${N_LOG_N}`, () => {
10
+ const heap = new Heap<number>({comparator: (a, b) => b - a});
11
+
12
+ for (let i = 0; i < N_LOG_N; i++) {
13
+ heap.add(i);
14
+ }
15
+
16
+ for (let i = 0; i < N_LOG_N; i++) {
17
+ heap.pop();
18
+ }
19
+ })
20
+ .add(`fib add & pop ${N_LOG_N}`, () => {
21
+ const fbHeap = new FibonacciHeap<number>();
22
+ for (let i = 1; i <= N_LOG_N; i++) {
23
+ fbHeap.push(i);
24
+ }
25
+ for (let i = 1; i <= N_LOG_N; i++) {
26
+ fbHeap.pop();
27
+ }
28
+ });
29
+
30
+ export {suite};
@@ -0,0 +1,40 @@
1
+ import {DoublyLinkedList, DoublyLinkedListNode} from '../../../../src';
2
+ import * as Benchmark from 'benchmark';
3
+ import {magnitude} from '../../../utils';
4
+
5
+ const suite = new Benchmark.Suite();
6
+ const {LINEAR, N_LOG_N} = magnitude;
7
+
8
+ suite
9
+ .add(`unshift ${LINEAR}`, () => {
10
+ const list = new DoublyLinkedList<number>();
11
+
12
+ for (let i = 0; i < LINEAR; i++) {
13
+ list.unshift(i);
14
+ }
15
+ })
16
+ .add(`unshift & shift ${LINEAR}`, () => {
17
+ const list = new DoublyLinkedList<number>();
18
+
19
+ for (let i = 0; i < LINEAR; i++) {
20
+ list.unshift(i);
21
+ }
22
+ for (let i = 0; i < LINEAR; i++) {
23
+ list.shift();
24
+ }
25
+ })
26
+ .add(`insertBefore ${N_LOG_N}`, () => {
27
+ const doublyList = new DoublyLinkedList<number>();
28
+ let midNode: DoublyLinkedListNode | null = null;
29
+ const midIndex = Math.floor(N_LOG_N / 2);
30
+ for (let i = 0; i < N_LOG_N; i++) {
31
+ doublyList.push(i);
32
+ if (i === midIndex) {
33
+ midNode = doublyList.getNode(i);
34
+ } else if (i > midIndex && midNode) {
35
+ doublyList.insertBefore(midNode, i);
36
+ }
37
+ }
38
+ });
39
+
40
+ export {suite};
@@ -0,0 +1,34 @@
1
+ import {SinglyLinkedList, SinglyLinkedListNode} from '../../../../src';
2
+ import * as Benchmark from 'benchmark';
3
+ import {magnitude} from '../../../utils';
4
+
5
+ const suite = new Benchmark.Suite();
6
+ const {N_LOG_N} = magnitude;
7
+
8
+ suite
9
+ .add(`push & pop ${N_LOG_N}`, () => {
10
+ const list = new SinglyLinkedList<number>();
11
+
12
+ for (let i = 0; i < N_LOG_N; i++) {
13
+ list.push(i);
14
+ }
15
+
16
+ for (let i = 0; i < N_LOG_N; i++) {
17
+ list.pop();
18
+ }
19
+ })
20
+ .add(`insertBefore ${N_LOG_N}`, () => {
21
+ const singlyList = new SinglyLinkedList<number>();
22
+ let midSinglyNode: SinglyLinkedListNode | null = null;
23
+ const midIndex = Math.floor(N_LOG_N / 2);
24
+ for (let i = 0; i < N_LOG_N; i++) {
25
+ singlyList.push(i);
26
+ if (i === midIndex) {
27
+ midSinglyNode = singlyList.getNode(i);
28
+ } else if (i > midIndex && midSinglyNode) {
29
+ singlyList.insertBefore(midSinglyNode.value, i);
30
+ }
31
+ }
32
+ });
33
+
34
+ export {suite};
@@ -0,0 +1,19 @@
1
+ import {MaxPriorityQueue} from '../../../../src';
2
+ import * as Benchmark from 'benchmark';
3
+ import {magnitude} from '../../../utils';
4
+
5
+ const suite = new Benchmark.Suite();
6
+ const {LINEAR} = magnitude;
7
+
8
+ suite.add(`refill & poll ${LINEAR}`, () => {
9
+ const nodes = Array.from(
10
+ new Set<number>(Array.from(new Array(LINEAR), () => Math.floor(Math.random() * LINEAR * 100)))
11
+ );
12
+ const maxPQ = new MaxPriorityQueue<number>();
13
+ maxPQ.refill(nodes);
14
+ while (maxPQ.size > 0) {
15
+ maxPQ.poll();
16
+ }
17
+ });
18
+
19
+ export {suite};
@@ -0,0 +1,21 @@
1
+ import {Deque} from '../../../../src';
2
+ import * as Benchmark from 'benchmark';
3
+ import {magnitude} from '../../../utils';
4
+
5
+ export const suite = new Benchmark.Suite();
6
+ const {LINEAR} = magnitude;
7
+
8
+ suite
9
+ .add(`push ${LINEAR}`, () => {
10
+ const deque = new Deque<number>();
11
+ for (let i = 0; i < LINEAR; i++) {
12
+ deque.push(i);
13
+ }
14
+ })
15
+ .add(`shift ${LINEAR}`, () => {
16
+ const deque = new Deque<number>();
17
+ for (let i = 0; i < LINEAR; i++) {
18
+ deque.push(i);
19
+ deque.shift();
20
+ }
21
+ });
@@ -0,0 +1,25 @@
1
+ import {Queue} from '../../../../src';
2
+ import * as Benchmark from 'benchmark';
3
+ import {magnitude} from '../../../utils';
4
+
5
+ const suite = new Benchmark.Suite();
6
+ const {LINEAR} = magnitude;
7
+
8
+ suite
9
+ .add(`push ${LINEAR}`, () => {
10
+ const queue = new Queue<number>();
11
+
12
+ for (let i = 0; i < LINEAR; i++) {
13
+ queue.push(i);
14
+ }
15
+ })
16
+ .add(`push & shift ${LINEAR}`, () => {
17
+ const queue = new Queue<number>();
18
+
19
+ for (let i = 0; i < LINEAR; i++) {
20
+ queue.push(i);
21
+ queue.shift();
22
+ }
23
+ });
24
+
25
+ export {suite};
@@ -0,0 +1,174 @@
1
+ import * as Benchmark from 'benchmark';
2
+ import * as path from 'path';
3
+ import * as fs from 'fs';
4
+ import * as fastGlob from 'fast-glob';
5
+ import {Color, numberFix, render} from '../utils';
6
+ import {PerformanceTest} from './types';
7
+
8
+ const reportDistPath = 'benchmark';
9
+ const testDir = path.join(__dirname, 'data-structures');
10
+ const testFiles = fastGlob.sync(path.join(testDir, '**', '*.test.ts'));
11
+
12
+ const report: {[key: string]: any} = {};
13
+
14
+ let testFileCount = 0,
15
+ completedCount = 0;
16
+
17
+ const performanceTests: PerformanceTest[] = [];
18
+ const {GREEN, BOLD, RED, END, YELLOW, CYAN, BG_YELLOW} = Color;
19
+
20
+ testFiles.forEach((file: string) => {
21
+ testFileCount++;
22
+ const testName = path.basename(file, '.test.ts');
23
+ const testFunction = require(file);
24
+ const {suite} = testFunction;
25
+ if (suite) performanceTests.push({testName, suite, file});
26
+ });
27
+
28
+ const composeReport = () => {
29
+ if (!fs.existsSync(reportDistPath)) fs.mkdirSync(reportDistPath, {recursive: true});
30
+
31
+ const filePath = path.join(reportDistPath, 'report.json');
32
+ const htmlFilePath = path.join(reportDistPath, 'report.html');
33
+ fs.writeFileSync(filePath, JSON.stringify(report, null, 2));
34
+ let html = `<!DOCTYPE html>
35
+ <html lang="en">
36
+ <head>
37
+ <meta charset="UTF-8">
38
+ <title>performance of data-structure-typed</title>
39
+ <style>
40
+ *{
41
+ box-sizing: border-box;
42
+ }
43
+ #json-to-html {
44
+ padding: 0 10px 20px;
45
+ }
46
+
47
+ .json-to-html-label {
48
+ font-size: 2rem;
49
+ margin: 2rem 0 0 3px;
50
+ }
51
+ .content table {
52
+ width: 100%;
53
+ table-layout: fixed;
54
+ border-collapse: collapse;
55
+ margin-top: 10px;
56
+ font-size: 16px;
57
+ }
58
+
59
+ .content table th,
60
+ .content table td {
61
+ padding: 8px 12px;
62
+ text-align: left;
63
+ border: 1px solid #ddd;
64
+ }
65
+
66
+ .content table th {
67
+ background-color: #f2f2f2;
68
+ font-weight: bold;
69
+ }
70
+
71
+ .content table tr:nth-child(odd) {
72
+ background-color: #ffffff;
73
+ }
74
+ </style>
75
+ </head>
76
+ <body>
77
+ <div id="json-to-html">`;
78
+ let htmlTables = '';
79
+ for (const r in report) {
80
+ if (report.hasOwnProperty(r)) {
81
+ htmlTables += render(report[r].testName, report[r].benchmarks, {
82
+ plainHtml: true,
83
+ '<>': 'table',
84
+ html: [
85
+ {
86
+ '<>': 'tr',
87
+ html: [
88
+ {'<>': 'td', html: '${name}'},
89
+ {'<>': 'td', html: '${periodMS}'},
90
+ {'<>': 'td', html: '${mean}'}
91
+ ]
92
+ }
93
+ ]
94
+ });
95
+ }
96
+ }
97
+ html += htmlTables;
98
+ html += `</div>
99
+ </body>
100
+ </html>`;
101
+ writeIntoMarkdown(htmlTables);
102
+ fs.writeFileSync(htmlFilePath, html);
103
+ console.log(`Performance ${BOLD}${GREEN}report${END} file generated`);
104
+ };
105
+
106
+ function writeIntoMarkdown(html: string) {
107
+ const parentDirectory = path.resolve(__dirname, '../..'); // The path to the parent directory
108
+ const markdownFilePath = path.join(parentDirectory, 'README.md'); // Path to README.md file
109
+ const textToInsert = html;
110
+
111
+ // Read the original README.md file
112
+ fs.readFile(markdownFilePath, 'utf8', (err, data) => {
113
+ if (err) {
114
+ console.error('Unable to read README.md file:', err);
115
+ return;
116
+ }
117
+
118
+ // Find the location in the README.md file where you want to insert the text, for example under a specific tag
119
+ const insertMarker = '## Benchmark';
120
+
121
+ const index = data.indexOf(insertMarker);
122
+ if (index === -1) {
123
+ console.error('Unable to find insertion point');
124
+ return;
125
+ }
126
+
127
+ // insert text
128
+ const updatedMarkdown =
129
+ data.slice(0, index + insertMarker.length) + '\n' + textToInsert + data.slice(index + insertMarker.length);
130
+
131
+ // Try writing the modified content back to the README.md file
132
+ fs.writeFile(markdownFilePath, updatedMarkdown, 'utf8', err => {
133
+ if (err) {
134
+ console.error('Unable to write to README.md file:', err);
135
+ } else {
136
+ console.log('The text has been successfully inserted into the README.md file!');
137
+ }
138
+ });
139
+ });
140
+ }
141
+
142
+ performanceTests.forEach(item => {
143
+ const {suite, testName, file} = item;
144
+ console.log(`${BG_YELLOW}Running in${END}: ${CYAN}${file}${END}`);
145
+
146
+ if (suite) {
147
+ suite
148
+ .on('complete', function (this: Benchmark.Suite) {
149
+ completedCount++;
150
+ report[testName] = {};
151
+ report[testName].benchmarks = this.map((benchmark: Benchmark) => ({
152
+ 'test name': benchmark.name,
153
+ 'time taken (ms)': numberFix(benchmark.times.period * 1000, 2),
154
+ 'executions per sec': numberFix(benchmark.hz, 2),
155
+ 'executed times': numberFix(benchmark.count, 0),
156
+ 'sample mean (secs)': numberFix(benchmark.stats.mean, 2),
157
+ 'sample deviation': numberFix(benchmark.stats.deviation, 2)
158
+ }));
159
+ report[testName].testName = testName;
160
+ const isDone = completedCount === performanceTests.length;
161
+ console.log(
162
+ `Files: ${GREEN}${testFileCount}${END} `,
163
+ `Suites: ${GREEN}${performanceTests.length}${END} `,
164
+ `Progress: ${isDone ? GREEN : YELLOW}${completedCount}${END}/${isDone ? GREEN : RED}${
165
+ performanceTests.length
166
+ }${END}`
167
+ );
168
+ if (isDone) {
169
+ composeReport();
170
+ }
171
+ })
172
+ .run({async: false});
173
+ }
174
+ });
@@ -0,0 +1 @@
1
+ export * from './reportor';
@@ -0,0 +1,3 @@
1
+ import * as Benchmark from 'benchmark';
2
+
3
+ export type PerformanceTest = {testName: string; suite: Benchmark.Suite; file: string};
@@ -1 +1,2 @@
1
1
  export * from './big-o';
2
+ export * from './json2html';
@@ -0,0 +1 @@
1
+ export type Json2htmlOptions = {plainHtml?: boolean} & Partial<{[key: string]: any}>;
@@ -1,5 +1,5 @@
1
- import {RBTNColor, RBTreeNode, RedBlackTree, NIL} from '../../../../src';
2
- import {getRandomInt} from '../../../utils';
1
+ import {NIL, RBTNColor, RBTreeNode, RedBlackTree} from '../../../../src';
2
+ import {randomInt} from '../../../utils';
3
3
  import {isDebugTest} from '../../../config';
4
4
 
5
5
  const isDebug = isDebugTest;
@@ -427,9 +427,9 @@ describe('RedBlackTree', () => {
427
427
  });
428
428
 
429
429
  it('should fix the tree after insertion and deletion', () => {
430
- for (let i = 0; i < 1000; i++) {
431
- tree.insert(getRandomInt(-100, 1000));
432
- tree.delete(getRandomInt(-100, 1000));
430
+ for (let i = 0; i < 100; i++) {
431
+ tree.insert(randomInt(-100, 1000));
432
+ tree.delete(randomInt(-100, 1000));
433
433
  }
434
434
  });
435
435
  });