typescript-ds-lib 0.2.8 → 0.3.0
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 +11 -6
- package/dist/benchmarks/benchmark.d.ts +5 -0
- package/dist/benchmarks/benchmark.js +23 -0
- package/dist/benchmarks/benchmark.js.map +1 -0
- package/dist/benchmarks/hash-table.d.ts +8 -0
- package/dist/benchmarks/hash-table.js +121 -0
- package/dist/benchmarks/hash-table.js.map +1 -0
- package/dist/benchmarks/run.d.ts +1 -0
- package/dist/benchmarks/run.js +12 -0
- package/dist/benchmarks/run.js.map +1 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.js +13 -11
- package/dist/index.js.map +1 -1
- package/dist/lib/graph.d.ts +14 -0
- package/dist/lib/graph.js +3 -0
- package/dist/lib/graph.js.map +1 -0
- package/dist/lib/hash-table-utils.d.ts +7 -0
- package/dist/lib/hash-table-utils.js +108 -0
- package/dist/lib/hash-table-utils.js.map +1 -0
- package/dist/lib/hash-table.d.ts +0 -2
- package/dist/lib/hash-table.js +24 -96
- package/dist/lib/hash-table.js.map +1 -1
- package/package.json +20 -3
package/README.md
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# TypeScript Data Structure Library
|
|
2
2
|
[](https://www.npmjs.com/package/typescript-ds-lib)
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
Provides Comparator for custom types. Just pass your own comparator function to the constructor.
|
|
4
|
+
TypeScript data structure implementations without external dependencies. Why to use this library?
|
|
6
5
|
|
|
7
6
|
- Fully Tested
|
|
8
7
|
- Fast
|
|
@@ -11,11 +10,13 @@ Provides Comparator for custom types. Just pass your own comparator function to
|
|
|
11
10
|
- Comes with Comparator (for custom types)
|
|
12
11
|
- `hashCode()` and `equals()` are supported
|
|
13
12
|
|
|
13
|
+
|
|
14
14
|
## Install
|
|
15
15
|
```
|
|
16
16
|
npm install typescript-ds-lib
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
|
|
19
20
|
## Usage
|
|
20
21
|
```typescript
|
|
21
22
|
import { Stack } from 'typescript-ds-lib';
|
|
@@ -32,6 +33,11 @@ console.log(stack.top()); // 2
|
|
|
32
33
|
console.log(stack.size()); // 2
|
|
33
34
|
```
|
|
34
35
|
|
|
36
|
+
|
|
37
|
+
## Documentation and Examples
|
|
38
|
+
See the [documentation](https://github.com/baloian/typescript-ds-lib/blob/master/doc/DOCUMENTATION.md) for more details and examples.
|
|
39
|
+
|
|
40
|
+
|
|
35
41
|
## Data Structures
|
|
36
42
|
- Stack
|
|
37
43
|
- Queue
|
|
@@ -42,12 +48,11 @@ console.log(stack.size()); // 2
|
|
|
42
48
|
- Deque
|
|
43
49
|
- Set
|
|
44
50
|
- Map
|
|
45
|
-
- Hash Table
|
|
51
|
+
- Hash Table (unordered map)
|
|
46
52
|
- Matrix
|
|
53
|
+
- Graph (coming soon)
|
|
47
54
|
|
|
48
|
-
|
|
49
|
-
## Documentation and Examples
|
|
50
|
-
See the [documentation](https://github.com/baloian/typescript-ds-lib/blob/master/doc/DOCUMENTATION.md) for more details and examples.
|
|
55
|
+
**Note:** The `Map` data structure is implemented as a Red-Black Tree and the `Set` data structure is implemented as a Binary Search Tree.
|
|
51
56
|
|
|
52
57
|
## Contributions
|
|
53
58
|
Contributions are welcome and can be made by submitting GitHub pull requests
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class BenchmarkBase {
|
|
4
|
+
measure(fn) {
|
|
5
|
+
const start = performance.now();
|
|
6
|
+
fn();
|
|
7
|
+
const end = performance.now();
|
|
8
|
+
return end - start;
|
|
9
|
+
}
|
|
10
|
+
formatResult(name, firstTime, secondTime, firstName = 'First', secondName = 'Second') {
|
|
11
|
+
const diff = Math.abs(firstTime - secondTime);
|
|
12
|
+
const ratio = Math.max(firstTime, secondTime) / Math.min(firstTime, secondTime);
|
|
13
|
+
const faster = secondTime > firstTime ? 'slower' : 'faster';
|
|
14
|
+
const percentage = ((ratio - 1) * 100).toFixed(2);
|
|
15
|
+
console.log(`\n${name} Times:`);
|
|
16
|
+
console.log(`${firstName}: ${firstTime.toFixed(2)}ms`);
|
|
17
|
+
console.log(`${secondName}: ${secondTime.toFixed(2)}ms`);
|
|
18
|
+
// console.log(`Difference: ${diff.toFixed(2)}ms`);
|
|
19
|
+
console.log(`${secondName} is ${ratio.toFixed(2)}x (${percentage}%) ${faster} than ${firstName}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.default = BenchmarkBase;
|
|
23
|
+
//# sourceMappingURL=benchmark.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"benchmark.js","sourceRoot":"","sources":["../../benchmarks/benchmark.ts"],"names":[],"mappings":";;AAAA,MAA8B,aAAa;IAC/B,OAAO,CAAC,EAAc;QAC9B,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,EAAE,EAAE,CAAC;QACL,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC9B,OAAO,GAAG,GAAG,KAAK,CAAC;IACrB,CAAC;IAES,YAAY,CAAC,IAAY,EAAE,SAAiB,EAAE,UAAkB,EAAE,YAAoB,OAAO,EAAE,aAAqB,QAAQ;QACpI,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,UAAU,CAAC,CAAC;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAChF,MAAM,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC5D,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAElD,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,GAAG,SAAS,KAAK,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,KAAK,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACzD,mDAAmD;QACnD,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,UAAU,MAAM,MAAM,SAAS,SAAS,EAAE,CAAC,CAAC;IACpG,CAAC;CAGF;AAtBD,gCAsBC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import BenchmarkBase from './benchmark';
|
|
2
|
+
export default class HashTableBenchmark extends BenchmarkBase {
|
|
3
|
+
protected iterations: number;
|
|
4
|
+
constructor(iterations?: number);
|
|
5
|
+
protected generateTestData(): [string, string][];
|
|
6
|
+
run(): void;
|
|
7
|
+
benchmarkCustomHashCode(): void;
|
|
8
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const benchmark_1 = __importDefault(require("./benchmark"));
|
|
7
|
+
const hash_table_1 = require("../lib/hash-table");
|
|
8
|
+
class HashTableBenchmark extends benchmark_1.default {
|
|
9
|
+
iterations;
|
|
10
|
+
constructor(iterations = 100000) {
|
|
11
|
+
super();
|
|
12
|
+
this.iterations = iterations;
|
|
13
|
+
}
|
|
14
|
+
generateTestData() {
|
|
15
|
+
return Array.from({ length: this.iterations }, (_, i) => [`key${i}`, `value${i}`]);
|
|
16
|
+
}
|
|
17
|
+
run() {
|
|
18
|
+
const testData = this.generateTestData();
|
|
19
|
+
// Test insertion
|
|
20
|
+
const map = new Map();
|
|
21
|
+
const hashTable = new hash_table_1.HashTable(8192 * 100);
|
|
22
|
+
const mapInsertTime = this.measure(() => {
|
|
23
|
+
for (const [key, value] of testData) {
|
|
24
|
+
map.set(key, value);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
const hashTableInsertTime = this.measure(() => {
|
|
28
|
+
for (const [key, value] of testData) {
|
|
29
|
+
hashTable.insert(key, value);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
// Test lookup
|
|
33
|
+
const mapLookupTime = this.measure(() => {
|
|
34
|
+
for (const [key] of testData) {
|
|
35
|
+
map.get(key);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
const hashTableLookupTime = this.measure(() => {
|
|
39
|
+
for (const [key] of testData) {
|
|
40
|
+
hashTable.get(key);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
// Test deletion
|
|
44
|
+
const mapDeleteTime = this.measure(() => {
|
|
45
|
+
for (const [key] of testData) {
|
|
46
|
+
map.delete(key);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
const hashTableDeleteTime = this.measure(() => {
|
|
50
|
+
for (const [key] of testData) {
|
|
51
|
+
hashTable.remove(key);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
// Print results
|
|
55
|
+
console.log(`\nBenchmark Results (${this.iterations.toLocaleString()} operations):`);
|
|
56
|
+
this.formatResult('Insertion', mapInsertTime, hashTableInsertTime, 'Map', 'HashTable');
|
|
57
|
+
// this.formatResult('Lookup', mapLookupTime, hashTableLookupTime, 'Map', 'HashTable');
|
|
58
|
+
// this.formatResult('Deletion', mapDeleteTime, hashTableDeleteTime, 'Map', 'HashTable');
|
|
59
|
+
}
|
|
60
|
+
benchmarkCustomHashCode() {
|
|
61
|
+
// Create test data with custom hash code implementation
|
|
62
|
+
class CustomKey {
|
|
63
|
+
value;
|
|
64
|
+
constructor(value) {
|
|
65
|
+
this.value = value;
|
|
66
|
+
}
|
|
67
|
+
hashCode() {
|
|
68
|
+
return this.value % 8192;
|
|
69
|
+
}
|
|
70
|
+
equals(other) {
|
|
71
|
+
return this.value === other.value;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const testData = [];
|
|
75
|
+
for (let i = 0; i < this.iterations; i++) {
|
|
76
|
+
testData.push([new CustomKey(i), i]);
|
|
77
|
+
}
|
|
78
|
+
// Test insertion
|
|
79
|
+
const map = new Map();
|
|
80
|
+
const hashTable = new hash_table_1.HashTable(8192 * 100);
|
|
81
|
+
const mapInsertTime = this.measure(() => {
|
|
82
|
+
for (const [key, value] of testData) {
|
|
83
|
+
map.set(key, value);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
const hashTableInsertTime = this.measure(() => {
|
|
87
|
+
for (const [key, value] of testData) {
|
|
88
|
+
hashTable.insert(key, value);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
// Test lookup
|
|
92
|
+
const mapLookupTime = this.measure(() => {
|
|
93
|
+
for (const [key] of testData) {
|
|
94
|
+
map.get(key);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
const hashTableLookupTime = this.measure(() => {
|
|
98
|
+
for (const [key] of testData) {
|
|
99
|
+
hashTable.get(key);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
// Test deletion
|
|
103
|
+
const mapDeleteTime = this.measure(() => {
|
|
104
|
+
for (const [key] of testData) {
|
|
105
|
+
map.delete(key);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
const hashTableDeleteTime = this.measure(() => {
|
|
109
|
+
for (const [key] of testData) {
|
|
110
|
+
hashTable.remove(key);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
// Print results
|
|
114
|
+
console.log(`\nBenchmark Results with Custom HashCode (${this.iterations.toLocaleString()} operations):`);
|
|
115
|
+
this.formatResult('Insertion', mapInsertTime, hashTableInsertTime, 'Map', 'HashTable');
|
|
116
|
+
this.formatResult('Lookup', mapLookupTime, hashTableLookupTime, 'Map', 'HashTable');
|
|
117
|
+
this.formatResult('Deletion', mapDeleteTime, hashTableDeleteTime, 'Map', 'HashTable');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
exports.default = HashTableBenchmark;
|
|
121
|
+
//# sourceMappingURL=hash-table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash-table.js","sourceRoot":"","sources":["../../benchmarks/hash-table.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const hash_table_1 = __importDefault(require("./hash-table"));
|
|
7
|
+
// Run benchmark
|
|
8
|
+
console.log('Starting benchmark...');
|
|
9
|
+
const benchmark = new hash_table_1.default(100000);
|
|
10
|
+
benchmark.run();
|
|
11
|
+
// benchmark.benchmarkCustomHashCode();
|
|
12
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../benchmarks/run.ts"],"names":[],"mappings":";;;;;AAAA,8DAA8C;AAE9C,gBAAgB;AAChB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;AACrC,MAAM,SAAS,GAAG,IAAI,oBAAkB,CAAC,MAAM,CAAC,CAAC;AACjD,SAAS,CAAC,GAAG,EAAE,CAAC;AAChB,uCAAuC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
export * from './types';
|
|
2
|
-
export { Stack } from './lib/stack';
|
|
3
|
-
export { Queue } from './lib/queue';
|
|
4
|
-
export { PriorityQueue } from './lib/priority-queue';
|
|
5
2
|
export { BinarySearchTree } from './lib/binary-search-tree';
|
|
6
3
|
export { Deque } from './lib/deque';
|
|
4
|
+
export { HashTable } from './lib/hash-table';
|
|
7
5
|
export { LinkedList } from './lib/linked-list';
|
|
8
|
-
export { Set } from './lib/set';
|
|
9
6
|
export { Map } from './lib/map';
|
|
7
|
+
export { Matrix } from './lib/matrix';
|
|
8
|
+
export { PriorityQueue } from './lib/priority-queue';
|
|
9
|
+
export { Queue } from './lib/queue';
|
|
10
10
|
export { RedBlackTree } from './lib/red-black-tree';
|
|
11
|
-
export {
|
|
11
|
+
export { Set } from './lib/set';
|
|
12
|
+
export { Stack } from './lib/stack';
|
package/dist/index.js
CHANGED
|
@@ -14,26 +14,28 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.
|
|
17
|
+
exports.Stack = exports.Set = exports.RedBlackTree = exports.Queue = exports.PriorityQueue = exports.Matrix = exports.Map = exports.LinkedList = exports.HashTable = exports.Deque = exports.BinarySearchTree = void 0;
|
|
18
18
|
__exportStar(require("./types"), exports);
|
|
19
|
-
var stack_1 = require("./lib/stack");
|
|
20
|
-
Object.defineProperty(exports, "Stack", { enumerable: true, get: function () { return stack_1.Stack; } });
|
|
21
|
-
var queue_1 = require("./lib/queue");
|
|
22
|
-
Object.defineProperty(exports, "Queue", { enumerable: true, get: function () { return queue_1.Queue; } });
|
|
23
|
-
var priority_queue_1 = require("./lib/priority-queue");
|
|
24
|
-
Object.defineProperty(exports, "PriorityQueue", { enumerable: true, get: function () { return priority_queue_1.PriorityQueue; } });
|
|
25
19
|
var binary_search_tree_1 = require("./lib/binary-search-tree");
|
|
26
20
|
Object.defineProperty(exports, "BinarySearchTree", { enumerable: true, get: function () { return binary_search_tree_1.BinarySearchTree; } });
|
|
27
21
|
var deque_1 = require("./lib/deque");
|
|
28
22
|
Object.defineProperty(exports, "Deque", { enumerable: true, get: function () { return deque_1.Deque; } });
|
|
23
|
+
var hash_table_1 = require("./lib/hash-table");
|
|
24
|
+
Object.defineProperty(exports, "HashTable", { enumerable: true, get: function () { return hash_table_1.HashTable; } });
|
|
29
25
|
var linked_list_1 = require("./lib/linked-list");
|
|
30
26
|
Object.defineProperty(exports, "LinkedList", { enumerable: true, get: function () { return linked_list_1.LinkedList; } });
|
|
31
|
-
var set_1 = require("./lib/set");
|
|
32
|
-
Object.defineProperty(exports, "Set", { enumerable: true, get: function () { return set_1.Set; } });
|
|
33
27
|
var map_1 = require("./lib/map");
|
|
34
28
|
Object.defineProperty(exports, "Map", { enumerable: true, get: function () { return map_1.Map; } });
|
|
29
|
+
var matrix_1 = require("./lib/matrix");
|
|
30
|
+
Object.defineProperty(exports, "Matrix", { enumerable: true, get: function () { return matrix_1.Matrix; } });
|
|
31
|
+
var priority_queue_1 = require("./lib/priority-queue");
|
|
32
|
+
Object.defineProperty(exports, "PriorityQueue", { enumerable: true, get: function () { return priority_queue_1.PriorityQueue; } });
|
|
33
|
+
var queue_1 = require("./lib/queue");
|
|
34
|
+
Object.defineProperty(exports, "Queue", { enumerable: true, get: function () { return queue_1.Queue; } });
|
|
35
35
|
var red_black_tree_1 = require("./lib/red-black-tree");
|
|
36
36
|
Object.defineProperty(exports, "RedBlackTree", { enumerable: true, get: function () { return red_black_tree_1.RedBlackTree; } });
|
|
37
|
-
var
|
|
38
|
-
Object.defineProperty(exports, "
|
|
37
|
+
var set_1 = require("./lib/set");
|
|
38
|
+
Object.defineProperty(exports, "Set", { enumerable: true, get: function () { return set_1.Set; } });
|
|
39
|
+
var stack_1 = require("./lib/stack");
|
|
40
|
+
Object.defineProperty(exports, "Stack", { enumerable: true, get: function () { return stack_1.Stack; } });
|
|
39
41
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,+DAA4D;AAAnD,sHAAA,gBAAgB,OAAA;AACzB,qCAAoC;AAA3B,8FAAA,KAAK,OAAA;AACd,+CAA6C;AAApC,uGAAA,SAAS,OAAA;AAClB,iDAA+C;AAAtC,yGAAA,UAAU,OAAA;AACnB,iCAAgC;AAAvB,0FAAA,GAAG,OAAA;AACZ,uCAAsC;AAA7B,gGAAA,MAAM,OAAA;AACf,uDAAqD;AAA5C,+GAAA,aAAa,OAAA;AACtB,qCAAoC;AAA3B,8FAAA,KAAK,OAAA;AACd,uDAAoD;AAA3C,8GAAA,YAAY,OAAA;AACrB,iCAAgC;AAAvB,0FAAA,GAAG,OAAA;AACZ,qCAAoC;AAA3B,8FAAA,KAAK,OAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface Graph<V, W> {
|
|
2
|
+
addVertex(vertex: V): void;
|
|
3
|
+
removeVertex(vertex: V): void;
|
|
4
|
+
addEdge(from: V, to: V, weight?: W): void;
|
|
5
|
+
removeEdge(from: V, to: V): void;
|
|
6
|
+
getNeighbors(vertex: V): V[];
|
|
7
|
+
getEdgeWeight(from: V, to: V): W;
|
|
8
|
+
getVertices(): V[];
|
|
9
|
+
hasVertex(vertex: V): boolean;
|
|
10
|
+
hasEdge(from: V, to: V): boolean;
|
|
11
|
+
vertexCount(): number;
|
|
12
|
+
edgeCount(): number;
|
|
13
|
+
clear(): void;
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../lib/graph.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HashTableUtils = void 0;
|
|
4
|
+
class HashTableUtils {
|
|
5
|
+
static valueToString(value) {
|
|
6
|
+
if (value === null || value === undefined)
|
|
7
|
+
return 'null';
|
|
8
|
+
let stringKey;
|
|
9
|
+
switch (typeof value) {
|
|
10
|
+
case 'number':
|
|
11
|
+
stringKey = value.toString();
|
|
12
|
+
break;
|
|
13
|
+
case 'object':
|
|
14
|
+
if (typeof value.toString === 'function') {
|
|
15
|
+
stringKey = value.toString();
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
stringKey = JSON.stringify(value);
|
|
19
|
+
}
|
|
20
|
+
break;
|
|
21
|
+
case 'string':
|
|
22
|
+
stringKey = value;
|
|
23
|
+
break;
|
|
24
|
+
case 'function':
|
|
25
|
+
stringKey = value.toString();
|
|
26
|
+
break;
|
|
27
|
+
case 'symbol':
|
|
28
|
+
stringKey = value.toString();
|
|
29
|
+
break;
|
|
30
|
+
default:
|
|
31
|
+
stringKey = String(value);
|
|
32
|
+
}
|
|
33
|
+
return stringKey;
|
|
34
|
+
}
|
|
35
|
+
// Thomas Wang, Integer Hash Functions.
|
|
36
|
+
static wangHash32(key) {
|
|
37
|
+
key = key >>> 0;
|
|
38
|
+
key = ~key + (key << 15);
|
|
39
|
+
key = key ^ (key >>> 12);
|
|
40
|
+
key = key + (key << 2);
|
|
41
|
+
key = key ^ (key >>> 4);
|
|
42
|
+
// Ensure multiplication wraps to 32 bits
|
|
43
|
+
key = ((key << 11) + (key << 3) + key) >>> 0;
|
|
44
|
+
key = key ^ (key >>> 16);
|
|
45
|
+
return key >>> 0;
|
|
46
|
+
}
|
|
47
|
+
/*
|
|
48
|
+
* DJB2a (variant using xor rather than +) hash algorithm.
|
|
49
|
+
* See: http://www.cse.yorku.ca/~oz/hash.html
|
|
50
|
+
*/
|
|
51
|
+
static hashFunction(str) {
|
|
52
|
+
let hash = 5381;
|
|
53
|
+
for (let i = 0; i < str.length; i++) {
|
|
54
|
+
hash = ((hash << 5) + hash) ^ str.charCodeAt(i);
|
|
55
|
+
}
|
|
56
|
+
// Convert the hash to an unsigned 32-bit integer to match C's unsigned long.
|
|
57
|
+
return hash >>> 0;
|
|
58
|
+
}
|
|
59
|
+
static hash(key, capacity) {
|
|
60
|
+
if (key && typeof key.hashCode === 'function') {
|
|
61
|
+
return key.hashCode();
|
|
62
|
+
}
|
|
63
|
+
if (typeof key === 'number' && Number.isSafeInteger(key)) {
|
|
64
|
+
return HashTableUtils.wangHash32(key) % capacity;
|
|
65
|
+
}
|
|
66
|
+
const stringKey = this.valueToString(key);
|
|
67
|
+
return this.hashFunction(stringKey) % capacity;
|
|
68
|
+
}
|
|
69
|
+
static keysEqual(key1, key2) {
|
|
70
|
+
if (key1 && key2 && typeof key1.equals === 'function') {
|
|
71
|
+
return key1.equals(key2);
|
|
72
|
+
}
|
|
73
|
+
if (key1 === key2)
|
|
74
|
+
return true;
|
|
75
|
+
if (typeof key1 === 'number' && typeof key2 === 'number' && isNaN(key1) && isNaN(key2))
|
|
76
|
+
return true;
|
|
77
|
+
if (typeof key1 !== 'object' && typeof key2 !== 'object')
|
|
78
|
+
return key1 === key2;
|
|
79
|
+
if (key1 instanceof Date && key2 instanceof Date) {
|
|
80
|
+
// Handle invalid dates
|
|
81
|
+
if (isNaN(key1.getTime()) && isNaN(key2.getTime()))
|
|
82
|
+
return true;
|
|
83
|
+
return key1.getTime() === key2.getTime();
|
|
84
|
+
}
|
|
85
|
+
if (key1 instanceof RegExp && key2 instanceof RegExp) {
|
|
86
|
+
return key1.toString() === key2.toString();
|
|
87
|
+
}
|
|
88
|
+
if (Array.isArray(key1) && Array.isArray(key2)) {
|
|
89
|
+
return key1.length === key2.length &&
|
|
90
|
+
key1.every((val, idx) => HashTableUtils.keysEqual(val, key2[idx]));
|
|
91
|
+
}
|
|
92
|
+
if (key1 === null && key2 === null)
|
|
93
|
+
return true;
|
|
94
|
+
if (key1 === undefined && key2 === undefined)
|
|
95
|
+
return true;
|
|
96
|
+
if (key1 === null || key1 === undefined || key2 === null || key2 === undefined)
|
|
97
|
+
return false;
|
|
98
|
+
if (typeof key1 === 'object' && typeof key2 === 'object') {
|
|
99
|
+
const keys1 = Object.keys(key1);
|
|
100
|
+
const keys2 = Object.keys(key2);
|
|
101
|
+
return keys1.length === keys2.length &&
|
|
102
|
+
keys1.every(k => k in key2 && HashTableUtils.keysEqual(key1[k], key2[k]));
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.HashTableUtils = HashTableUtils;
|
|
108
|
+
//# sourceMappingURL=hash-table-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash-table-utils.js","sourceRoot":"","sources":["../../lib/hash-table-utils.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/hash-table.d.ts
CHANGED
package/dist/lib/hash-table.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.HashTable = void 0;
|
|
4
|
+
const hash_table_utils_1 = require("./hash-table-utils");
|
|
4
5
|
class HashNode {
|
|
5
6
|
key;
|
|
6
7
|
value;
|
|
@@ -15,86 +16,43 @@ class HashTable {
|
|
|
15
16
|
table;
|
|
16
17
|
count;
|
|
17
18
|
capacity;
|
|
18
|
-
constructor(capacity =
|
|
19
|
-
|
|
19
|
+
constructor(capacity = 4096) {
|
|
20
|
+
// Handle negative or zero capacity by using default capacity
|
|
21
|
+
this.capacity = capacity <= 0 ? 4096 : capacity;
|
|
22
|
+
this.table = new Array(this.capacity).fill(null);
|
|
20
23
|
this.count = 0;
|
|
21
|
-
this.capacity = capacity;
|
|
22
|
-
}
|
|
23
|
-
hash(key) {
|
|
24
|
-
if (typeof key.hashCode === 'function') {
|
|
25
|
-
return key.hashCode();
|
|
26
|
-
}
|
|
27
|
-
let stringKey;
|
|
28
|
-
switch (typeof key) {
|
|
29
|
-
case 'number':
|
|
30
|
-
// If the number is a safe integer, use Knuth's multiplicative method.
|
|
31
|
-
if (Number.isSafeInteger(key)) {
|
|
32
|
-
const knuthConstant = 2654435761;
|
|
33
|
-
return (Math.abs(key * knuthConstant) >>> 0) % this.capacity;
|
|
34
|
-
}
|
|
35
|
-
stringKey = key.toString();
|
|
36
|
-
break;
|
|
37
|
-
case 'object':
|
|
38
|
-
if (key === null) {
|
|
39
|
-
stringKey = 'null';
|
|
40
|
-
}
|
|
41
|
-
else if (typeof key.toString === 'function') {
|
|
42
|
-
stringKey = key.toString();
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
stringKey = JSON.stringify(key);
|
|
46
|
-
}
|
|
47
|
-
break;
|
|
48
|
-
case 'string':
|
|
49
|
-
stringKey = key;
|
|
50
|
-
break;
|
|
51
|
-
case 'function':
|
|
52
|
-
stringKey = key.toString();
|
|
53
|
-
break;
|
|
54
|
-
case 'symbol':
|
|
55
|
-
stringKey = key.toString();
|
|
56
|
-
break;
|
|
57
|
-
case 'undefined':
|
|
58
|
-
stringKey = 'null';
|
|
59
|
-
break;
|
|
60
|
-
default:
|
|
61
|
-
stringKey = String(key);
|
|
62
|
-
}
|
|
63
|
-
let hash = 0;
|
|
64
|
-
// DJB2 hash algorithm
|
|
65
|
-
for (let i = 0; i < stringKey.length; i++) {
|
|
66
|
-
hash = ((hash << 5) + hash) + stringKey.charCodeAt(i);
|
|
67
|
-
hash = hash >>> 0; // Convert to 32-bit unsigned integer
|
|
68
|
-
}
|
|
69
|
-
return hash % this.capacity;
|
|
70
24
|
}
|
|
71
25
|
insert(key, value) {
|
|
72
|
-
const index =
|
|
73
|
-
|
|
26
|
+
const index = hash_table_utils_1.HashTableUtils.hash(key, this.capacity);
|
|
27
|
+
// Handle empty bucket case.
|
|
74
28
|
if (!this.table[index]) {
|
|
75
|
-
this.table[index] =
|
|
29
|
+
this.table[index] = new HashNode(key, value);
|
|
76
30
|
this.count++;
|
|
77
31
|
return;
|
|
78
32
|
}
|
|
33
|
+
// Check first node for key match. If it matches, update the value.
|
|
34
|
+
if (hash_table_utils_1.HashTableUtils.keysEqual(this.table[index].key, key)) {
|
|
35
|
+
this.table[index].value = value;
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
// Traverse chain to find key or last node. If it matches, update the value.
|
|
79
39
|
let current = this.table[index];
|
|
80
|
-
while (current) {
|
|
81
|
-
if (
|
|
82
|
-
current.value = value;
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
if (!current.next) {
|
|
86
|
-
current.next = newNode;
|
|
87
|
-
this.count++;
|
|
40
|
+
while (current.next) {
|
|
41
|
+
if (hash_table_utils_1.HashTableUtils.keysEqual(current.next.key, key)) {
|
|
42
|
+
current.next.value = value;
|
|
88
43
|
return;
|
|
89
44
|
}
|
|
90
45
|
current = current.next;
|
|
91
46
|
}
|
|
47
|
+
// Key not found, append new node.
|
|
48
|
+
current.next = new HashNode(key, value);
|
|
49
|
+
this.count++;
|
|
92
50
|
}
|
|
93
51
|
get(key) {
|
|
94
|
-
const index =
|
|
52
|
+
const index = hash_table_utils_1.HashTableUtils.hash(key, this.capacity);
|
|
95
53
|
let current = this.table[index];
|
|
96
54
|
while (current) {
|
|
97
|
-
if (
|
|
55
|
+
if (hash_table_utils_1.HashTableUtils.keysEqual(current.key, key)) {
|
|
98
56
|
return current.value;
|
|
99
57
|
}
|
|
100
58
|
current = current.next;
|
|
@@ -102,11 +60,11 @@ class HashTable {
|
|
|
102
60
|
return undefined;
|
|
103
61
|
}
|
|
104
62
|
remove(key) {
|
|
105
|
-
const index =
|
|
63
|
+
const index = hash_table_utils_1.HashTableUtils.hash(key, this.capacity);
|
|
106
64
|
let current = this.table[index];
|
|
107
65
|
let prev = null;
|
|
108
66
|
while (current) {
|
|
109
|
-
if (
|
|
67
|
+
if (hash_table_utils_1.HashTableUtils.keysEqual(current.key, key)) {
|
|
110
68
|
if (prev) {
|
|
111
69
|
prev.next = current.next;
|
|
112
70
|
}
|
|
@@ -121,36 +79,6 @@ class HashTable {
|
|
|
121
79
|
}
|
|
122
80
|
return false;
|
|
123
81
|
}
|
|
124
|
-
keysEqual(key1, key2) {
|
|
125
|
-
// Check if keys have equals method and use it for comparison
|
|
126
|
-
if (typeof key1.equals === 'function') {
|
|
127
|
-
return key1.equals(key2);
|
|
128
|
-
}
|
|
129
|
-
if (key1 === key2)
|
|
130
|
-
return true;
|
|
131
|
-
if (key1 == null || key2 == null)
|
|
132
|
-
return false;
|
|
133
|
-
if (typeof key1 !== 'object' && typeof key2 !== 'object') {
|
|
134
|
-
return key1 === key2;
|
|
135
|
-
}
|
|
136
|
-
if (key1 instanceof Date && key2 instanceof Date) {
|
|
137
|
-
return key1.getTime() === key2.getTime();
|
|
138
|
-
}
|
|
139
|
-
if (key1 instanceof RegExp && key2 instanceof RegExp) {
|
|
140
|
-
return key1.toString() === key2.toString();
|
|
141
|
-
}
|
|
142
|
-
if (Array.isArray(key1) && Array.isArray(key2)) {
|
|
143
|
-
return key1.length === key2.length &&
|
|
144
|
-
key1.every((val, idx) => this.keysEqual(val, key2[idx]));
|
|
145
|
-
}
|
|
146
|
-
if (typeof key1 === 'object' && typeof key2 === 'object') {
|
|
147
|
-
const keys1 = Object.keys(key1);
|
|
148
|
-
const keys2 = Object.keys(key2);
|
|
149
|
-
return keys1.length === keys2.length &&
|
|
150
|
-
keys1.every(k => k in key2 && this.keysEqual(key1[k], key2[k]));
|
|
151
|
-
}
|
|
152
|
-
return false;
|
|
153
|
-
}
|
|
154
82
|
size() {
|
|
155
83
|
return this.count;
|
|
156
84
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash-table.js","sourceRoot":"","sources":["../../lib/hash-table.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"hash-table.js","sourceRoot":"","sources":["../../lib/hash-table.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typescript-ds-lib",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A collection of TypeScript data structure implementations",
|
|
5
5
|
"author": "Artiom Baloian <artiom.baloian@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"scripts": {
|
|
15
15
|
"build": "rm -rf dist && tsc",
|
|
16
16
|
"prepare": "npm run build",
|
|
17
|
-
"test": "rm -rf dist && tsc && jest"
|
|
17
|
+
"test": "rm -rf dist && tsc && jest",
|
|
18
|
+
"benchmark": "ts-node benchmarks/run.ts"
|
|
18
19
|
},
|
|
19
20
|
"repository": {
|
|
20
21
|
"type": "git",
|
|
@@ -26,5 +27,21 @@
|
|
|
26
27
|
"@types/node": "^22.10.1",
|
|
27
28
|
"ts-jest": "^29.2.5",
|
|
28
29
|
"typescript": "^5.7.2"
|
|
29
|
-
}
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"typescript",
|
|
33
|
+
"data-structures",
|
|
34
|
+
"algorithms",
|
|
35
|
+
"binary-search-tree",
|
|
36
|
+
"linked-list",
|
|
37
|
+
"hash-table",
|
|
38
|
+
"queue",
|
|
39
|
+
"stack",
|
|
40
|
+
"deque",
|
|
41
|
+
"priority-queue",
|
|
42
|
+
"red-black-tree",
|
|
43
|
+
"set",
|
|
44
|
+
"map",
|
|
45
|
+
"matrix"
|
|
46
|
+
]
|
|
30
47
|
}
|