data-structure-typed 1.36.7 → 1.36.9

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 (84) hide show
  1. package/.eslintrc.js +1 -1
  2. package/CHANGELOG.md +3 -1
  3. package/README.md +8 -0
  4. package/dist/data-structures/binary-tree/avl-tree.d.ts +5 -5
  5. package/dist/data-structures/binary-tree/avl-tree.js +6 -6
  6. package/dist/data-structures/binary-tree/avl-tree.js.map +1 -1
  7. package/dist/data-structures/binary-tree/binary-tree.d.ts +18 -85
  8. package/dist/data-structures/binary-tree/binary-tree.js +76 -128
  9. package/dist/data-structures/binary-tree/binary-tree.js.map +1 -1
  10. package/dist/data-structures/binary-tree/tree-multiset.d.ts +9 -16
  11. package/dist/data-structures/binary-tree/tree-multiset.js +10 -20
  12. package/dist/data-structures/binary-tree/tree-multiset.js.map +1 -1
  13. package/dist/data-structures/hash/hash-map.d.ts +1 -1
  14. package/dist/data-structures/hash/hash-map.js +1 -1
  15. package/dist/data-structures/hash/hash-table.d.ts +3 -3
  16. package/dist/data-structures/hash/hash-table.js +3 -3
  17. package/dist/data-structures/heap/heap.d.ts +136 -11
  18. package/dist/data-structures/heap/heap.js +293 -13
  19. package/dist/data-structures/heap/heap.js.map +1 -1
  20. package/dist/data-structures/linked-list/skip-linked-list.d.ts +3 -3
  21. package/dist/data-structures/linked-list/skip-linked-list.js +3 -3
  22. package/dist/data-structures/queue/deque.d.ts +2 -2
  23. package/dist/data-structures/queue/deque.js +2 -2
  24. package/dist/data-structures/queue/queue.js +1 -1
  25. package/dist/data-structures/trie/trie.d.ts +2 -2
  26. package/dist/data-structures/trie/trie.js +2 -2
  27. package/dist/interfaces/binary-tree.d.ts +1 -1
  28. package/lib/data-structures/binary-tree/avl-tree.d.ts +5 -5
  29. package/lib/data-structures/binary-tree/avl-tree.js +6 -6
  30. package/lib/data-structures/binary-tree/binary-tree.d.ts +18 -85
  31. package/lib/data-structures/binary-tree/binary-tree.js +76 -128
  32. package/lib/data-structures/binary-tree/tree-multiset.d.ts +9 -16
  33. package/lib/data-structures/binary-tree/tree-multiset.js +10 -20
  34. package/lib/data-structures/hash/hash-map.d.ts +1 -1
  35. package/lib/data-structures/hash/hash-map.js +1 -1
  36. package/lib/data-structures/hash/hash-table.d.ts +3 -3
  37. package/lib/data-structures/hash/hash-table.js +3 -3
  38. package/lib/data-structures/heap/heap.d.ts +136 -11
  39. package/lib/data-structures/heap/heap.js +290 -12
  40. package/lib/data-structures/linked-list/skip-linked-list.d.ts +3 -3
  41. package/lib/data-structures/linked-list/skip-linked-list.js +3 -3
  42. package/lib/data-structures/queue/deque.d.ts +2 -2
  43. package/lib/data-structures/queue/deque.js +2 -2
  44. package/lib/data-structures/queue/queue.js +1 -1
  45. package/lib/data-structures/trie/trie.d.ts +2 -2
  46. package/lib/data-structures/trie/trie.js +2 -2
  47. package/lib/interfaces/binary-tree.d.ts +1 -1
  48. package/package.json +7 -6
  49. package/src/data-structures/binary-tree/avl-tree.ts +6 -6
  50. package/src/data-structures/binary-tree/binary-tree.ts +79 -214
  51. package/src/data-structures/binary-tree/rb-tree.ts +3 -3
  52. package/src/data-structures/binary-tree/tree-multiset.ts +10 -21
  53. package/src/data-structures/hash/hash-map.ts +1 -1
  54. package/src/data-structures/hash/hash-table.ts +3 -3
  55. package/src/data-structures/heap/heap.ts +340 -16
  56. package/src/data-structures/linked-list/skip-linked-list.ts +3 -3
  57. package/src/data-structures/queue/deque.ts +2 -2
  58. package/src/data-structures/queue/queue.ts +1 -1
  59. package/src/data-structures/trie/trie.ts +2 -2
  60. package/src/interfaces/binary-tree.ts +1 -1
  61. package/test/types/index.ts +1 -0
  62. package/test/types/utils/big-o.ts +1 -0
  63. package/test/types/utils/index.ts +1 -0
  64. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +14 -14
  65. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +2 -2
  66. package/test/unit/data-structures/binary-tree/bst.test.ts +28 -28
  67. package/test/unit/data-structures/binary-tree/overall.test.ts +3 -3
  68. package/test/unit/data-structures/binary-tree/rb-tree.test.ts +1 -1
  69. package/test/unit/data-structures/binary-tree/tree-multiset.test.ts +28 -28
  70. package/test/unit/data-structures/graph/directed-graph.test.ts +1 -1
  71. package/test/unit/data-structures/graph/undirected-graph.test.ts +1 -1
  72. package/test/unit/data-structures/hash/hash-map.test.ts +2 -2
  73. package/test/unit/data-structures/hash/hash-table.test.ts +5 -5
  74. package/test/unit/data-structures/heap/heap.test.ts +192 -1
  75. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +7 -7
  76. package/test/unit/data-structures/linked-list/skip-list.test.ts +2 -2
  77. package/test/unit/data-structures/priority-queue/max-priority-queue.test.ts +1 -1
  78. package/test/unit/data-structures/queue/deque.test.ts +3 -3
  79. package/test/unit/data-structures/trie/trie.test.ts +5 -5
  80. package/test/utils/big-o.ts +199 -0
  81. package/test/utils/index.ts +1 -1
  82. package/umd/bundle.min.js +1 -1
  83. package/umd/bundle.min.js.map +1 -1
  84. package/test/utils/magnitude.ts +0 -21
@@ -1,4 +1,5 @@
1
- import {MaxHeap, MinHeap} from '../../../../src';
1
+ import {FibonacciHeap, MaxHeap, MinHeap} from '../../../../src';
2
+ import {logBigOMetricsWrap} from '../../../utils';
2
3
 
3
4
  describe('Heap Operation Test', () => {
4
5
  it('should numeric heap work well', function () {
@@ -60,3 +61,193 @@ describe('Heap Operation Test', () => {
60
61
  }
61
62
  });
62
63
  });
64
+
65
+ describe('FibonacciHeap', () => {
66
+ let heap: FibonacciHeap<number>;
67
+
68
+ beforeEach(() => {
69
+ heap = new FibonacciHeap<number>();
70
+ });
71
+
72
+ test('push & peek', () => {
73
+ heap.push(10);
74
+ heap.push(5);
75
+ expect(heap.peek()).toBe(5);
76
+ });
77
+
78
+ test('pop', () => {
79
+ heap.push(10);
80
+ heap.push(5);
81
+ heap.push(15);
82
+ expect(heap.pop()).toBe(5);
83
+ expect(heap.pop()).toBe(10);
84
+ expect(heap.pop()).toBe(15);
85
+ });
86
+
87
+ test('pop on an empty heap', () => {
88
+ expect(heap.pop()).toBeUndefined();
89
+ });
90
+
91
+ test('size', () => {
92
+ expect(heap.size).toBe(0);
93
+ heap.push(10);
94
+ expect(heap.size).toBe(1);
95
+ heap.pop();
96
+ expect(heap.size).toBe(0);
97
+ });
98
+
99
+ test('clear', () => {
100
+ heap.push(10);
101
+ heap.push(5);
102
+ heap.clear();
103
+ expect(heap.size).toBe(0);
104
+ expect(heap.peek()).toBeUndefined();
105
+ });
106
+
107
+ test('custom comparator', () => {
108
+ const maxHeap = new FibonacciHeap<number>((a, b) => b - a);
109
+ maxHeap.push(10);
110
+ maxHeap.push(5);
111
+ expect(maxHeap.peek()).toBe(10);
112
+ });
113
+ });
114
+
115
+ describe('FibonacciHeap', () => {
116
+ let heap: FibonacciHeap<number>;
117
+
118
+ beforeEach(() => {
119
+ heap = new FibonacciHeap<number>();
120
+ });
121
+
122
+ it('should initialize an empty heap', () => {
123
+ expect(heap.size).toBe(0);
124
+ expect(heap.peek()).toBeUndefined();
125
+ });
126
+
127
+ it('should push items into the heap and update size', () => {
128
+ heap.push(10);
129
+ heap.push(5);
130
+
131
+ expect(heap.size).toBe(2);
132
+ });
133
+
134
+ it('should peek the minimum item', () => {
135
+ heap.push(10);
136
+ heap.push(5);
137
+ heap.push(15);
138
+
139
+ expect(heap.peek()).toBe(5);
140
+ });
141
+
142
+ it('should pop the minimum item and update size', () => {
143
+ heap.push(10);
144
+ heap.push(5);
145
+ heap.push(15);
146
+
147
+ const minItem = heap.pop();
148
+
149
+ expect(minItem).toBe(5);
150
+ expect(heap.size).toBe(2);
151
+ });
152
+
153
+ it('should correctly merge two heaps', () => {
154
+ const heap1 = new FibonacciHeap<number>();
155
+ const heap2 = new FibonacciHeap<number>();
156
+
157
+ heap1.push(10);
158
+ heap2.push(5);
159
+
160
+ heap1.merge(heap2);
161
+
162
+ expect(heap1.size).toBe(2);
163
+ expect(heap1.peek()).toBe(5);
164
+ });
165
+
166
+ it('should clear the heap', () => {
167
+ heap.push(10);
168
+ heap.push(5);
169
+
170
+ heap.clear();
171
+
172
+ expect(heap.size).toBe(0);
173
+ expect(heap.peek()).toBeUndefined();
174
+ });
175
+
176
+ it('should handle custom comparators', () => {
177
+ const customComparator = (a: number, b: number) => b - a;
178
+ const customHeap = new FibonacciHeap<number>(customComparator);
179
+
180
+ customHeap.push(10);
181
+ customHeap.push(5);
182
+ customHeap.push(15);
183
+
184
+ expect(customHeap.peek()).toBe(15);
185
+ });
186
+
187
+ describe('FibonacciHeap Merge', () => {
188
+ it('should merge two Fibonacci heaps correctly', () => {
189
+ const heap1 = new FibonacciHeap<number>();
190
+ heap1.push(5).push(10);
191
+
192
+ const heap2 = new FibonacciHeap<number>();
193
+ heap2.push(3).push(7);
194
+
195
+ heap1.merge(heap2);
196
+
197
+ expect(heap1.size).toBe(4); // Combined size of both heaps
198
+ expect(heap2.size).toBe(0); // Merged heap should be empty
199
+ expect(heap1.peek()).toBe(3); // Minimum element should be 3
200
+ });
201
+ });
202
+ });
203
+
204
+ describe('FibonacciHeap Stress Test', () => {
205
+ it('should handle a large number of elements efficiently', () => {
206
+ const testByMagnitude = (magnitude: number) => {
207
+ const heap = new FibonacciHeap<number>();
208
+
209
+ // Add 1000 elements to the heap
210
+ for (let i = 1; i <= magnitude; i++) {
211
+ heap.push(i);
212
+ }
213
+
214
+ // Verify that the minimum element is 1 (smallest element)
215
+ expect(heap.peek()).toBe(1);
216
+
217
+ // Remove all 1000 elements from the heap
218
+ const elements = [];
219
+ while (heap.size > 0) {
220
+ elements.push(heap.pop());
221
+ }
222
+
223
+ // Verify that all elements were removed in ascending order
224
+ for (let i = 1; i <= magnitude; i++) {
225
+ expect(elements[i - 1]).toBe(i);
226
+ }
227
+
228
+ // Verify that the heap is now empty
229
+ expect(heap.size).toBe(0);
230
+ };
231
+
232
+ testByMagnitude(1000);
233
+
234
+ // [
235
+ // 10, 100, 1000, 5000, 10000, 20000, 50000, 75000, 100000,
236
+ // 150000, 200000, 250000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000
237
+ // ].forEach(m => logBigOMetricsWrap<typeof testByMagnitude>(testByMagnitude, [m]));
238
+ [
239
+ 10, 100, 1000, 5000, 10000, 20000, 50000, 75000, 100000, 150000, 200000, 250000, 300000, 400000, 500000, 600000,
240
+ 700000, 800000, 900000, 1000000
241
+ ].forEach(m =>
242
+ logBigOMetricsWrap(
243
+ (c: number) => {
244
+ const result: number[] = [];
245
+ for (let i = 0; i < c; i++) result.push(i);
246
+ return result;
247
+ },
248
+ [m],
249
+ 'loopPush'
250
+ )
251
+ );
252
+ });
253
+ });
@@ -18,7 +18,7 @@ describe('SinglyLinkedList Operation Test', () => {
18
18
  });
19
19
 
20
20
  describe('pop', () => {
21
- it('should remove and return the last element of the list', () => {
21
+ it('should delete and return the last element of the list', () => {
22
22
  list.push(1);
23
23
  list.push(2);
24
24
  const popped = list.pop();
@@ -33,7 +33,7 @@ describe('SinglyLinkedList Operation Test', () => {
33
33
  });
34
34
 
35
35
  describe('shift', () => {
36
- it('should remove and return the first element of the list', () => {
36
+ it('should delete and return the first element of the list', () => {
37
37
  list.push(1);
38
38
  list.push(2);
39
39
  const shifted = list.shift();
@@ -109,7 +109,7 @@ describe('SinglyLinkedList Operation Test', () => {
109
109
  });
110
110
 
111
111
  describe('removeValue', () => {
112
- it('should remove the first occurrence of a value from the list', () => {
112
+ it('should delete the first occurrence of a value from the list', () => {
113
113
  list.push(1);
114
114
  list.push(2);
115
115
  list.push(3);
@@ -240,8 +240,8 @@ describe('SinglyLinkedList Operation Test', () => {
240
240
  });
241
241
  });
242
242
 
243
- describe('remove', () => {
244
- it('should remove and return the element at the specified index', () => {
243
+ describe('delete', () => {
244
+ it('should delete and return the element at the specified index', () => {
245
245
  list.push(1);
246
246
  list.push(2);
247
247
  list.push(3);
@@ -256,7 +256,7 @@ describe('SinglyLinkedList Operation Test', () => {
256
256
  expect(removed).toBeUndefined();
257
257
  });
258
258
 
259
- it('should remove and return the first element', () => {
259
+ it('should delete and return the first element', () => {
260
260
  list.push(1);
261
261
  list.push(2);
262
262
  const removed = list.deleteAt(0);
@@ -264,7 +264,7 @@ describe('SinglyLinkedList Operation Test', () => {
264
264
  expect(list.toArray()).toEqual([2]);
265
265
  });
266
266
 
267
- it('should remove and return the last element', () => {
267
+ it('should delete and return the last element', () => {
268
268
  list.push(1);
269
269
  list.push(2);
270
270
  const removed = list.deleteAt(1);
@@ -25,12 +25,12 @@ describe('SkipList', () => {
25
25
  expect(skipList.get(0)).toBeUndefined();
26
26
  });
27
27
 
28
- it('should remove elements correctly', () => {
28
+ it('should delete elements correctly', () => {
29
29
  skipList.add(1, 'One');
30
30
  skipList.add(2, 'Two');
31
31
  skipList.add(3, 'Three');
32
32
 
33
- skipList.remove(2);
33
+ skipList.delete(2);
34
34
 
35
35
  expect(skipList.get(2)).toBeUndefined(); // 修改这里的断言
36
36
  });
@@ -27,7 +27,7 @@ describe('MaxPriorityQueue Operation Test', () => {
27
27
  expect(priorityQueue.poll()?.keyA).toBe(1);
28
28
  });
29
29
 
30
- it('should return and remove the smallest element', () => {
30
+ it('should return and delete the smallest element', () => {
31
31
  const priorityQueue = new MaxPriorityQueue<number>();
32
32
  priorityQueue.add(5);
33
33
  priorityQueue.add(3);
@@ -16,7 +16,7 @@ describe('Deque Tests', () => {
16
16
  expect(deque.peekLast()).toBe(2);
17
17
  });
18
18
 
19
- it('should remove elements from the beginning and end', () => {
19
+ it('should delete elements from the beginning and end', () => {
20
20
  deque.addFirst(1);
21
21
  deque.addLast(2);
22
22
  deque.pollFirst();
@@ -69,7 +69,7 @@ describe('Deque Tests', () => {
69
69
  expect(objectDeque.peekLast()).toBe('two');
70
70
  });
71
71
 
72
- it('should remove elements from the beginning and end', () => {
72
+ it('should delete elements from the beginning and end', () => {
73
73
  objectDeque.addFirst('one');
74
74
  objectDeque.addLast('two');
75
75
  objectDeque.pollFirst();
@@ -106,7 +106,7 @@ describe('Deque Tests', () => {
106
106
  expect(arrayDeque.peekLast()).toBe(2);
107
107
  });
108
108
 
109
- it('should remove elements from the beginning and end', () => {
109
+ it('should delete elements from the beginning and end', () => {
110
110
  arrayDeque.addFirst(1);
111
111
  arrayDeque.addLast(2);
112
112
  arrayDeque.pollFirst();
@@ -81,15 +81,15 @@ describe('Trie', () => {
81
81
  expect(words).toEqual(['apple', 'application', 'app']);
82
82
  });
83
83
 
84
- it('should remove words from Trie', () => {
84
+ it('should delete words from Trie', () => {
85
85
  const trie = new Trie();
86
86
  trie.add('apple');
87
87
  trie.add('app');
88
88
  expect(trie.has('apple')).toBe(true);
89
- trie.remove('apple');
89
+ trie.delete('apple');
90
90
  expect(trie.has('apple')).toBe(false);
91
91
  expect(trie.has('app')).toBe(true);
92
- trie.remove('app');
92
+ trie.delete('app');
93
93
  expect(trie.has('app')).toBe(false);
94
94
  });
95
95
 
@@ -772,9 +772,9 @@ describe('Trie operations', () => {
772
772
  test('Remove Words', () => {
773
773
  trie.add('apple');
774
774
  trie.add('banana');
775
- expect(trie.remove('apple')).toBe(true);
775
+ expect(trie.delete('apple')).toBe(true);
776
776
  expect(trie.has('apple')).toBe(false);
777
- expect(trie.remove('cherry')).toBe(false);
777
+ expect(trie.delete('cherry')).toBe(false);
778
778
  });
779
779
 
780
780
  test('Case Sensitivity', () => {
@@ -0,0 +1,199 @@
1
+ import {AnyFunction} from '../types';
2
+
3
+ const orderReducedBy = 2; // reduction of bigO's order compared to the baseline bigO
4
+
5
+ export const magnitude = {
6
+ CONSTANT: Math.floor(Number.MAX_SAFE_INTEGER / Math.pow(10, orderReducedBy)),
7
+ LOG_N: Math.pow(10, 9 - orderReducedBy),
8
+ LINEAR: Math.pow(10, 6 - orderReducedBy),
9
+ N_LOG_N: Math.pow(10, 5 - orderReducedBy),
10
+ SQUARED: Math.pow(10, 4 - orderReducedBy),
11
+ CUBED: Math.pow(10, 3 - orderReducedBy),
12
+ FACTORIAL: 20 - orderReducedBy
13
+ };
14
+
15
+ export const bigO = {
16
+ CONSTANT: magnitude.CONSTANT / 100000,
17
+ LOG_N: Math.log2(magnitude.LOG_N) / 1000,
18
+ LINEAR: magnitude.LINEAR / 1000,
19
+ N_LOG_N: (magnitude.N_LOG_N * Math.log2(magnitude.LOG_N)) / 1000,
20
+ SQUARED: Math.pow(magnitude.SQUARED, 2) / 1000,
21
+ CUBED: Math.pow(magnitude.SQUARED, 3) / 1000,
22
+ FACTORIAL: 10000
23
+ };
24
+
25
+ function findPotentialN(input: any): number {
26
+ let longestArray: any[] = [];
27
+ let mostProperties: {[key: string]: any} = {};
28
+
29
+ function recurse(obj: any) {
30
+ if (Array.isArray(obj)) {
31
+ if (obj.length > longestArray.length) {
32
+ longestArray = obj;
33
+ }
34
+ } else if (typeof obj === 'object' && obj !== null) {
35
+ const keys = Object.keys(obj);
36
+ if (keys.length > Object.keys(mostProperties).length) {
37
+ mostProperties = obj;
38
+ }
39
+ keys.forEach(key => {
40
+ recurse(obj[key]);
41
+ });
42
+ }
43
+ }
44
+
45
+ if (Array.isArray(input)) {
46
+ input.forEach(item => {
47
+ recurse(item);
48
+ });
49
+ } else {
50
+ recurse(input);
51
+ }
52
+
53
+ // return [longestArray, mostProperties] : [any[], { [key: string]: any }];
54
+ return Math.max(longestArray.length, Object.keys(mostProperties).length);
55
+ }
56
+
57
+ function linearRegression(x: number[], y: number[]) {
58
+ const n = x.length;
59
+
60
+ const sumX = x.reduce((acc, val) => acc + val, 0);
61
+ const sumY = y.reduce((acc, val) => acc + val, 0);
62
+
63
+ const sumXSquared = x.reduce((acc, val) => acc + val ** 2, 0);
64
+ const sumXY = x.reduce((acc, val, i) => acc + val * y[i], 0);
65
+
66
+ const slope = (n * sumXY - sumX * sumY) / (n * sumXSquared - sumX ** 2);
67
+ const intercept = (sumY - slope * sumX) / n;
68
+
69
+ const yHat = x.map(val => slope * val + intercept);
70
+
71
+ const totalVariation = y.map((val, i) => (val - yHat[i]) ** 2).reduce((acc, val) => acc + val, 0);
72
+ const explainedVariation = y.map(val => (val - sumY / n) ** 2).reduce((acc, val) => acc + val, 0);
73
+
74
+ const rSquared = 1 - totalVariation / explainedVariation;
75
+
76
+ return {slope, intercept, rSquared};
77
+ }
78
+
79
+ function estimateBigO(runtimes: number[], dataSizes: number[]): string {
80
+ // Make sure the input runtimes and data sizes have the same length
81
+ if (runtimes.length !== dataSizes.length) {
82
+ return 'Lengths of input arrays do not match';
83
+ }
84
+
85
+ // Create an array to store the computational complexity of each data point
86
+ const complexities: string[] = [];
87
+
88
+ // Traverse different possible complexities
89
+ const complexitiesToCheck: string[] = [
90
+ 'O(1)', // constant time complexity
91
+ 'O(log n)', // Logarithmic time complexity
92
+ 'O(n)', // linear time complexity
93
+ 'O(n log n)', // linear logarithmic time complexity
94
+ 'O(n^2)' // squared time complexity
95
+ ];
96
+
97
+ for (const complexity of complexitiesToCheck) {
98
+ // Calculate data points for fitting
99
+ const fittedData: number[] = dataSizes.map(size => {
100
+ if (complexity === 'O(1)') {
101
+ return 1; // constant time complexity
102
+ } else if (complexity === 'O(log n)') {
103
+ return Math.log(size);
104
+ } else if (complexity === 'O(n)') {
105
+ return size;
106
+ } else if (complexity === 'O(n log n)') {
107
+ return size * Math.log(size);
108
+ } else if (complexity === 'O(n^2)') {
109
+ return size ** 2;
110
+ } else {
111
+ return size ** 10;
112
+ }
113
+ });
114
+
115
+ // Fit the data points using linear regression analysis
116
+ const regressionResult = linearRegression(fittedData, runtimes);
117
+
118
+ // Check the R-squared value of the fit. It is usually considered a valid fit if it is greater than 0.9.
119
+ if (regressionResult.rSquared >= 0.9) {
120
+ complexities.push(complexity);
121
+ }
122
+ }
123
+
124
+ // If there is no valid fitting result, return "cannot estimate", otherwise return the estimated time complexity
125
+ if (complexities.length === 0) {
126
+ return 'Unable to estimate';
127
+ } else {
128
+ return complexities.join(' or ');
129
+ }
130
+ }
131
+
132
+ const methodLogs: Map<string, [number, number][]> = new Map();
133
+
134
+ export function logBigOMetricsWrap<F extends AnyFunction>(fn: F, args: Parameters<F>, fnName: string) {
135
+ const startTime = performance.now();
136
+ const result = fn(args);
137
+ const endTime = performance.now();
138
+ const runTime = endTime - startTime;
139
+ const methodName = `${fnName}`;
140
+ if (!methodLogs.has(methodName)) {
141
+ methodLogs.set(methodName, []);
142
+ }
143
+
144
+ const methodLog = methodLogs.get(methodName);
145
+
146
+ const maxDataSize = args.length === 1 && typeof args[0] === 'number' ? args[0] : findPotentialN(args);
147
+ if (methodLog) {
148
+ methodLog.push([runTime, maxDataSize]);
149
+
150
+ if (methodLog.length >= 20) {
151
+ console.log('triggered', methodName, methodLog);
152
+ const bigO = estimateBigO(
153
+ methodLog.map(([runTime]) => runTime),
154
+ methodLog.map(([runTime]) => runTime)
155
+ );
156
+ console.log(`Estimated Big O: ${bigO}`);
157
+ methodLogs.delete(methodName);
158
+ }
159
+ }
160
+
161
+ return result;
162
+ }
163
+
164
+ export function logBigOMetrics(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
165
+ const originalMethod = descriptor.value;
166
+
167
+ descriptor.value = function (...args: any[]) {
168
+ const startTime = performance.now();
169
+ const result = originalMethod.apply(this, args);
170
+ const endTime = performance.now();
171
+ const runTime = endTime - startTime;
172
+
173
+ const methodName = `${target.constructor.name}.${propertyKey}`;
174
+ if (!methodLogs.has(methodName)) {
175
+ methodLogs.set(methodName, []);
176
+ }
177
+
178
+ const methodLog = methodLogs.get(methodName);
179
+
180
+ const maxDataSize = args.length === 1 && typeof args[0] === 'number' ? args[0] : findPotentialN(args);
181
+ if (methodLog) {
182
+ methodLog.push([runTime, maxDataSize]);
183
+
184
+ if (methodLog.length >= 20) {
185
+ console.log('triggered', methodName, methodLog);
186
+ const bigO = estimateBigO(
187
+ methodLog.map(([runTime]) => runTime),
188
+ methodLog.map(([runTime]) => runTime)
189
+ );
190
+ console.log(`Estimated Big O: ${bigO}`);
191
+ methodLogs.delete(methodName);
192
+ }
193
+ }
194
+
195
+ return result;
196
+ };
197
+
198
+ return descriptor;
199
+ }
@@ -1,2 +1,2 @@
1
1
  export * from './number';
2
- export * from './magnitude';
2
+ export * from './big-o';