@keyv/bigmap 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Jared Wray
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # @keyv/redis [<img width="100" align="right" src="https://jaredwray.com/images/keyv-symbol.svg" alt="keyv">](https://github.com/jaredwra/keyv)
2
+
3
+ > Bigmap for Keyv
4
+
5
+ [![build](https://github.com/jaredwray/keyv/actions/workflows/tests.yaml/badge.svg)](https://github.com/jaredwray/keyv/actions/workflows/tests.yaml)
6
+ [![codecov](https://codecov.io/gh/jaredwray/keyv/branch/main/graph/badge.svg?token=bRzR3RyOXZ)](https://codecov.io/gh/jaredwray/keyv)
7
+ [![npm](https://img.shields.io/npm/v/@keyv/redis.svg)](https://www.npmjs.com/package/@keyv/redis)
8
+ [![npm](https://img.shields.io/npm/dm/@keyv/redis)](https://npmjs.com/package/@keyv/redis)
9
+
10
+ # Features
11
+ * Based on the Map interface and uses the same API.
12
+ * Lightweight with no dependencies.
13
+ * Scales to past the 17 million key limit of a regular Map.
14
+ * Uses a hash `djb2Hash` for fast key lookups.
15
+ * Ability to use your own hash function.
16
+ * Built in Typescript and Generics for type safety.
17
+ * Used as default in-memory store for `Keyv`.
18
+ * Used as in-memory store for `@keyv/fs`.
19
+ * Used in `@cacheable/memory` for scalable in-memory caching.
20
+ * Maintained regularly with a focus on performance and reliability.
21
+
22
+ # Table of Contents
23
+
24
+
25
+ # Installation
26
+
27
+ ```bash
28
+ npm install --save keyv @keyv/bigmap
29
+ ```
30
+
31
+ # Usage
32
+
33
+ # Benchmarks
34
+
35
+ # Contributing
36
+
37
+ Please see our [contributing](https://github.com/jaredwray/keyv/blob/main/CONTRIBUTING.md) guide.
38
+
39
+ # License
40
+
41
+ [MIT © Jared Wray](LICENSE)
package/dist/index.cjs ADDED
@@ -0,0 +1,253 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ BigMap: () => BigMap,
24
+ defaultHashFunction: () => defaultHashFunction,
25
+ djb2Hash: () => djb2Hash
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+ var import_hookified = require("hookified");
29
+ function defaultHashFunction(key, storeSize) {
30
+ return djb2Hash(key, 0, storeSize - 1);
31
+ }
32
+ function djb2Hash(string_, min = 0, max = 10) {
33
+ let hash = 5381;
34
+ for (let i = 0; i < string_.length; i++) {
35
+ hash = hash * 33 ^ string_.charCodeAt(i);
36
+ }
37
+ const range = max - min + 1;
38
+ return min + Math.abs(hash) % range;
39
+ }
40
+ var BigMap = class extends import_hookified.Hookified {
41
+ _storeSize = 4;
42
+ _store = Array.from({ length: this._storeSize }, () => /* @__PURE__ */ new Map());
43
+ _storeHashFunction;
44
+ /**
45
+ * Creates an instance of BigMap.
46
+ * @param {BigMapOptions<K, V>} [options] - Optional configuration options for the BigMap.
47
+ */
48
+ constructor(options) {
49
+ super(options);
50
+ if (options?.storeSize !== void 0) {
51
+ if (options.storeSize < 1) {
52
+ throw new Error("Store size must be at least 1.");
53
+ }
54
+ this.storeSize = options.storeSize;
55
+ }
56
+ this.initStore();
57
+ this._storeHashFunction = options?.storeHashFunction ?? defaultHashFunction;
58
+ }
59
+ /**
60
+ * Gets the number of maps in the store.
61
+ * @returns {number} The number of maps in the store.
62
+ */
63
+ get storeSize() {
64
+ return this._storeSize;
65
+ }
66
+ /**
67
+ * Sets the number of maps in the store. If the size is less than 1, an error is thrown.
68
+ * If you change the store size it will clear all entries.
69
+ * @param {number} size - The new size of the store.
70
+ * @throws {Error} If the size is less than 1.
71
+ */
72
+ set storeSize(size) {
73
+ if (size < 1) {
74
+ throw new Error("Store size must be at least 1.");
75
+ }
76
+ this._storeSize = size;
77
+ this.clear();
78
+ this.initStore();
79
+ }
80
+ /**
81
+ * Gets the hash function used for storing keys.
82
+ * @returns {StoreHashFunction | undefined} The hash function used for storing keys, or undefined if not set.
83
+ */
84
+ get storeHashFunction() {
85
+ return this._storeHashFunction;
86
+ }
87
+ /**
88
+ * Sets the hash function used for storing keys.
89
+ * @param {StoreHashFunction} hashFunction - The hash function to use for storing keys.
90
+ */
91
+ set storeHashFunction(hashFunction) {
92
+ this._storeHashFunction = hashFunction ?? defaultHashFunction;
93
+ }
94
+ /**
95
+ * Gets the store, which is an array of maps.
96
+ * @returns {Array<Map<K, V>>} The array of maps in the store.
97
+ */
98
+ get store() {
99
+ return this._store;
100
+ }
101
+ /**
102
+ * Gets the map at the specified index in the store.
103
+ * @param {number} index - The index of the map to retrieve.
104
+ * @returns {Map<K, V>} The map at the specified index.
105
+ */
106
+ getStoreMap(index) {
107
+ if (index < 0 || index >= this._storeSize) {
108
+ throw new Error(`Index out of bounds: ${index}. Valid range is 0 to ${this._storeSize - 1}.`);
109
+ }
110
+ return this._store[index];
111
+ }
112
+ /**
113
+ * Initializes the store with empty maps.
114
+ * This method is called when the BigMap instance is created.
115
+ */
116
+ initStore() {
117
+ this._store = Array.from({ length: this._storeSize }, () => /* @__PURE__ */ new Map());
118
+ }
119
+ /**
120
+ * Gets the store for a specific key.
121
+ * The store is determined by applying the hash function to the key and the store size.
122
+ * If the hash function is not set, it defaults to using the default hash function.
123
+ * @param key - The key for which to get the store.
124
+ * @returns The store for the specified key.
125
+ */
126
+ getStore(key) {
127
+ if (this._storeSize === 1) {
128
+ return this.getStoreMap(0);
129
+ }
130
+ const storeSize = this._storeSize - 1;
131
+ const index = this._storeHashFunction ? this._storeHashFunction(String(key), storeSize) : defaultHashFunction(String(key), storeSize);
132
+ return this.getStoreMap(index);
133
+ }
134
+ /**
135
+ * Returns an iterable of key-value pairs in the map.
136
+ * @returns {IterableIterator<[K, V]>} An iterable of key-value pairs in the map.
137
+ */
138
+ entries() {
139
+ const entries = [];
140
+ for (const store of this._store) {
141
+ store.forEach((value, key) => entries.push([key, value]));
142
+ }
143
+ return entries[Symbol.iterator]();
144
+ }
145
+ /**
146
+ * Returns an iterable of keys in the map.
147
+ * @returns {IterableIterator<K>} An iterable of keys in the map.
148
+ */
149
+ keys() {
150
+ const keys = [];
151
+ for (const store of this._store) {
152
+ store.forEach((_, key) => keys.push(key));
153
+ }
154
+ return keys[Symbol.iterator]();
155
+ }
156
+ /**
157
+ * Returns an iterable of values in the map.
158
+ * @returns {IterableIterator<V>} An iterable of values in the map.
159
+ */
160
+ values() {
161
+ const values = [];
162
+ for (const store of this._store) {
163
+ store.forEach((value) => values.push(value));
164
+ }
165
+ return values[Symbol.iterator]();
166
+ }
167
+ /**
168
+ * Returns an iterator that iterates over the key-value pairs in the map.
169
+ * @returns {IterableIterator<[K, V]>} An iterator that iterates over the key-value pairs in the map.
170
+ */
171
+ [Symbol.iterator]() {
172
+ const entries = [];
173
+ for (const store of this._store) {
174
+ store.forEach((value, key) => entries.push([key, value]));
175
+ }
176
+ return entries[Symbol.iterator]();
177
+ }
178
+ /**
179
+ * Clears all entries in the map.
180
+ * @returns {void} This method does not return a value.
181
+ */
182
+ clear() {
183
+ for (const store of this._store) {
184
+ store.clear();
185
+ }
186
+ }
187
+ /**
188
+ * Deletes a key-value pair from the map.
189
+ * @param {K} key - The key of the entry to delete.
190
+ * @returns {boolean} Returns true if the entry was deleted, false if the key was not found.
191
+ */
192
+ delete(key) {
193
+ const store = this.getStore(key);
194
+ const deleted = store.delete(key);
195
+ return deleted;
196
+ }
197
+ /**
198
+ * Calls a provided callback function once for each key-value pair in the map.
199
+ * @param {function} callbackfn - The function to execute for each key-value pair.
200
+ * @param {any} [thisArg] - An optional value to use as `this` when executing the callback.
201
+ */
202
+ forEach(callbackfn, thisArg) {
203
+ this._store.forEach((store) => {
204
+ store.forEach(callbackfn, thisArg);
205
+ });
206
+ }
207
+ /**
208
+ * Gets the value associated with the specified key.
209
+ * @param {K} key - The key of the entry to get.
210
+ * @returns {V | undefined} The value associated with the key, or undefined if the key does not exist.
211
+ */
212
+ get(key) {
213
+ const store = this.getStore(key);
214
+ return store.get(key);
215
+ }
216
+ /**
217
+ * Checks if the map contains a key.
218
+ * @param {K} key - The key to check for existence.
219
+ * @returns {boolean} Returns true if the key exists, false otherwise.
220
+ */
221
+ has(key) {
222
+ const store = this.getStore(key);
223
+ return store.has(key);
224
+ }
225
+ /**
226
+ * Sets the value for a key in the map.
227
+ * @param {K} key - The key of the entry to set.
228
+ * @param {V} value - The value to set for the entry.
229
+ * @returns {Map<K, V>} The map instance.
230
+ */
231
+ set(key, value) {
232
+ const store = this.getStore(key);
233
+ store.set(key, value);
234
+ return store;
235
+ }
236
+ /**
237
+ * Gets the number of entries in the map.
238
+ * @returns {number} The number of entries in the map.
239
+ */
240
+ get size() {
241
+ let size = 0;
242
+ for (const store of this._store) {
243
+ size += store.size;
244
+ }
245
+ return size;
246
+ }
247
+ };
248
+ // Annotate the CommonJS export names for ESM import in node:
249
+ 0 && (module.exports = {
250
+ BigMap,
251
+ defaultHashFunction,
252
+ djb2Hash
253
+ });
@@ -0,0 +1,149 @@
1
+ import { HookifiedOptions, Hookified } from 'hookified';
2
+
3
+ type MapInterfacee<K, V> = {
4
+ readonly size: number;
5
+ clear(): void;
6
+ delete(key: K): boolean;
7
+ forEach(callbackfn: (value: V, key: K, map: MapInterfacee<K, V>) => void, thisArg?: any): void;
8
+ entries(): IterableIterator<[K, V]>;
9
+ keys(): IterableIterator<K>;
10
+ values(): IterableIterator<V>;
11
+ [Symbol.iterator](): IterableIterator<[K, V]>;
12
+ get(key: K): V | undefined;
13
+ has(key: K): boolean;
14
+ set(key: K, value: V): Map<K, V>;
15
+ };
16
+ type StoreHashFunction = ((key: string, storeSize: number) => number);
17
+ declare function defaultHashFunction(key: string, storeSize: number): number;
18
+ declare function djb2Hash(string_: string, min?: number, max?: number): number;
19
+ type BigMapOptions<K, V> = {
20
+ /**
21
+ * Optional size of the store. The default is 4 maps objects.
22
+ * @default 4
23
+ */
24
+ storeSize?: number;
25
+ /**
26
+ * Optional hash function to use for storing keys.
27
+ * @default undefined
28
+ */
29
+ storeHashFunction?: StoreHashFunction;
30
+ } & HookifiedOptions;
31
+ declare class BigMap<K, V> extends Hookified implements MapInterfacee<K, V> {
32
+ private _storeSize;
33
+ private _store;
34
+ private _storeHashFunction?;
35
+ /**
36
+ * Creates an instance of BigMap.
37
+ * @param {BigMapOptions<K, V>} [options] - Optional configuration options for the BigMap.
38
+ */
39
+ constructor(options?: BigMapOptions<K, V>);
40
+ /**
41
+ * Gets the number of maps in the store.
42
+ * @returns {number} The number of maps in the store.
43
+ */
44
+ get storeSize(): number;
45
+ /**
46
+ * Sets the number of maps in the store. If the size is less than 1, an error is thrown.
47
+ * If you change the store size it will clear all entries.
48
+ * @param {number} size - The new size of the store.
49
+ * @throws {Error} If the size is less than 1.
50
+ */
51
+ set storeSize(size: number);
52
+ /**
53
+ * Gets the hash function used for storing keys.
54
+ * @returns {StoreHashFunction | undefined} The hash function used for storing keys, or undefined if not set.
55
+ */
56
+ get storeHashFunction(): StoreHashFunction | undefined;
57
+ /**
58
+ * Sets the hash function used for storing keys.
59
+ * @param {StoreHashFunction} hashFunction - The hash function to use for storing keys.
60
+ */
61
+ set storeHashFunction(hashFunction: StoreHashFunction | undefined);
62
+ /**
63
+ * Gets the store, which is an array of maps.
64
+ * @returns {Array<Map<K, V>>} The array of maps in the store.
65
+ */
66
+ get store(): Array<Map<K, V>>;
67
+ /**
68
+ * Gets the map at the specified index in the store.
69
+ * @param {number} index - The index of the map to retrieve.
70
+ * @returns {Map<K, V>} The map at the specified index.
71
+ */
72
+ getStoreMap(index: number): Map<K, V>;
73
+ /**
74
+ * Initializes the store with empty maps.
75
+ * This method is called when the BigMap instance is created.
76
+ */
77
+ initStore(): void;
78
+ /**
79
+ * Gets the store for a specific key.
80
+ * The store is determined by applying the hash function to the key and the store size.
81
+ * If the hash function is not set, it defaults to using the default hash function.
82
+ * @param key - The key for which to get the store.
83
+ * @returns The store for the specified key.
84
+ */
85
+ getStore(key: K): Map<K, V>;
86
+ /**
87
+ * Returns an iterable of key-value pairs in the map.
88
+ * @returns {IterableIterator<[K, V]>} An iterable of key-value pairs in the map.
89
+ */
90
+ entries(): IterableIterator<[K, V]>;
91
+ /**
92
+ * Returns an iterable of keys in the map.
93
+ * @returns {IterableIterator<K>} An iterable of keys in the map.
94
+ */
95
+ keys(): IterableIterator<K>;
96
+ /**
97
+ * Returns an iterable of values in the map.
98
+ * @returns {IterableIterator<V>} An iterable of values in the map.
99
+ */
100
+ values(): IterableIterator<V>;
101
+ /**
102
+ * Returns an iterator that iterates over the key-value pairs in the map.
103
+ * @returns {IterableIterator<[K, V]>} An iterator that iterates over the key-value pairs in the map.
104
+ */
105
+ [Symbol.iterator](): IterableIterator<[K, V]>;
106
+ /**
107
+ * Clears all entries in the map.
108
+ * @returns {void} This method does not return a value.
109
+ */
110
+ clear(): void;
111
+ /**
112
+ * Deletes a key-value pair from the map.
113
+ * @param {K} key - The key of the entry to delete.
114
+ * @returns {boolean} Returns true if the entry was deleted, false if the key was not found.
115
+ */
116
+ delete(key: K): boolean;
117
+ /**
118
+ * Calls a provided callback function once for each key-value pair in the map.
119
+ * @param {function} callbackfn - The function to execute for each key-value pair.
120
+ * @param {any} [thisArg] - An optional value to use as `this` when executing the callback.
121
+ */
122
+ forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
123
+ /**
124
+ * Gets the value associated with the specified key.
125
+ * @param {K} key - The key of the entry to get.
126
+ * @returns {V | undefined} The value associated with the key, or undefined if the key does not exist.
127
+ */
128
+ get(key: K): V | undefined;
129
+ /**
130
+ * Checks if the map contains a key.
131
+ * @param {K} key - The key to check for existence.
132
+ * @returns {boolean} Returns true if the key exists, false otherwise.
133
+ */
134
+ has(key: K): boolean;
135
+ /**
136
+ * Sets the value for a key in the map.
137
+ * @param {K} key - The key of the entry to set.
138
+ * @param {V} value - The value to set for the entry.
139
+ * @returns {Map<K, V>} The map instance.
140
+ */
141
+ set(key: K, value: V): Map<K, V>;
142
+ /**
143
+ * Gets the number of entries in the map.
144
+ * @returns {number} The number of entries in the map.
145
+ */
146
+ get size(): number;
147
+ }
148
+
149
+ export { BigMap, type BigMapOptions, type MapInterfacee, type StoreHashFunction, defaultHashFunction, djb2Hash };
@@ -0,0 +1,149 @@
1
+ import { HookifiedOptions, Hookified } from 'hookified';
2
+
3
+ type MapInterfacee<K, V> = {
4
+ readonly size: number;
5
+ clear(): void;
6
+ delete(key: K): boolean;
7
+ forEach(callbackfn: (value: V, key: K, map: MapInterfacee<K, V>) => void, thisArg?: any): void;
8
+ entries(): IterableIterator<[K, V]>;
9
+ keys(): IterableIterator<K>;
10
+ values(): IterableIterator<V>;
11
+ [Symbol.iterator](): IterableIterator<[K, V]>;
12
+ get(key: K): V | undefined;
13
+ has(key: K): boolean;
14
+ set(key: K, value: V): Map<K, V>;
15
+ };
16
+ type StoreHashFunction = ((key: string, storeSize: number) => number);
17
+ declare function defaultHashFunction(key: string, storeSize: number): number;
18
+ declare function djb2Hash(string_: string, min?: number, max?: number): number;
19
+ type BigMapOptions<K, V> = {
20
+ /**
21
+ * Optional size of the store. The default is 4 maps objects.
22
+ * @default 4
23
+ */
24
+ storeSize?: number;
25
+ /**
26
+ * Optional hash function to use for storing keys.
27
+ * @default undefined
28
+ */
29
+ storeHashFunction?: StoreHashFunction;
30
+ } & HookifiedOptions;
31
+ declare class BigMap<K, V> extends Hookified implements MapInterfacee<K, V> {
32
+ private _storeSize;
33
+ private _store;
34
+ private _storeHashFunction?;
35
+ /**
36
+ * Creates an instance of BigMap.
37
+ * @param {BigMapOptions<K, V>} [options] - Optional configuration options for the BigMap.
38
+ */
39
+ constructor(options?: BigMapOptions<K, V>);
40
+ /**
41
+ * Gets the number of maps in the store.
42
+ * @returns {number} The number of maps in the store.
43
+ */
44
+ get storeSize(): number;
45
+ /**
46
+ * Sets the number of maps in the store. If the size is less than 1, an error is thrown.
47
+ * If you change the store size it will clear all entries.
48
+ * @param {number} size - The new size of the store.
49
+ * @throws {Error} If the size is less than 1.
50
+ */
51
+ set storeSize(size: number);
52
+ /**
53
+ * Gets the hash function used for storing keys.
54
+ * @returns {StoreHashFunction | undefined} The hash function used for storing keys, or undefined if not set.
55
+ */
56
+ get storeHashFunction(): StoreHashFunction | undefined;
57
+ /**
58
+ * Sets the hash function used for storing keys.
59
+ * @param {StoreHashFunction} hashFunction - The hash function to use for storing keys.
60
+ */
61
+ set storeHashFunction(hashFunction: StoreHashFunction | undefined);
62
+ /**
63
+ * Gets the store, which is an array of maps.
64
+ * @returns {Array<Map<K, V>>} The array of maps in the store.
65
+ */
66
+ get store(): Array<Map<K, V>>;
67
+ /**
68
+ * Gets the map at the specified index in the store.
69
+ * @param {number} index - The index of the map to retrieve.
70
+ * @returns {Map<K, V>} The map at the specified index.
71
+ */
72
+ getStoreMap(index: number): Map<K, V>;
73
+ /**
74
+ * Initializes the store with empty maps.
75
+ * This method is called when the BigMap instance is created.
76
+ */
77
+ initStore(): void;
78
+ /**
79
+ * Gets the store for a specific key.
80
+ * The store is determined by applying the hash function to the key and the store size.
81
+ * If the hash function is not set, it defaults to using the default hash function.
82
+ * @param key - The key for which to get the store.
83
+ * @returns The store for the specified key.
84
+ */
85
+ getStore(key: K): Map<K, V>;
86
+ /**
87
+ * Returns an iterable of key-value pairs in the map.
88
+ * @returns {IterableIterator<[K, V]>} An iterable of key-value pairs in the map.
89
+ */
90
+ entries(): IterableIterator<[K, V]>;
91
+ /**
92
+ * Returns an iterable of keys in the map.
93
+ * @returns {IterableIterator<K>} An iterable of keys in the map.
94
+ */
95
+ keys(): IterableIterator<K>;
96
+ /**
97
+ * Returns an iterable of values in the map.
98
+ * @returns {IterableIterator<V>} An iterable of values in the map.
99
+ */
100
+ values(): IterableIterator<V>;
101
+ /**
102
+ * Returns an iterator that iterates over the key-value pairs in the map.
103
+ * @returns {IterableIterator<[K, V]>} An iterator that iterates over the key-value pairs in the map.
104
+ */
105
+ [Symbol.iterator](): IterableIterator<[K, V]>;
106
+ /**
107
+ * Clears all entries in the map.
108
+ * @returns {void} This method does not return a value.
109
+ */
110
+ clear(): void;
111
+ /**
112
+ * Deletes a key-value pair from the map.
113
+ * @param {K} key - The key of the entry to delete.
114
+ * @returns {boolean} Returns true if the entry was deleted, false if the key was not found.
115
+ */
116
+ delete(key: K): boolean;
117
+ /**
118
+ * Calls a provided callback function once for each key-value pair in the map.
119
+ * @param {function} callbackfn - The function to execute for each key-value pair.
120
+ * @param {any} [thisArg] - An optional value to use as `this` when executing the callback.
121
+ */
122
+ forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
123
+ /**
124
+ * Gets the value associated with the specified key.
125
+ * @param {K} key - The key of the entry to get.
126
+ * @returns {V | undefined} The value associated with the key, or undefined if the key does not exist.
127
+ */
128
+ get(key: K): V | undefined;
129
+ /**
130
+ * Checks if the map contains a key.
131
+ * @param {K} key - The key to check for existence.
132
+ * @returns {boolean} Returns true if the key exists, false otherwise.
133
+ */
134
+ has(key: K): boolean;
135
+ /**
136
+ * Sets the value for a key in the map.
137
+ * @param {K} key - The key of the entry to set.
138
+ * @param {V} value - The value to set for the entry.
139
+ * @returns {Map<K, V>} The map instance.
140
+ */
141
+ set(key: K, value: V): Map<K, V>;
142
+ /**
143
+ * Gets the number of entries in the map.
144
+ * @returns {number} The number of entries in the map.
145
+ */
146
+ get size(): number;
147
+ }
148
+
149
+ export { BigMap, type BigMapOptions, type MapInterfacee, type StoreHashFunction, defaultHashFunction, djb2Hash };
package/dist/index.js ADDED
@@ -0,0 +1,226 @@
1
+ // src/index.ts
2
+ import { Hookified } from "hookified";
3
+ function defaultHashFunction(key, storeSize) {
4
+ return djb2Hash(key, 0, storeSize - 1);
5
+ }
6
+ function djb2Hash(string_, min = 0, max = 10) {
7
+ let hash = 5381;
8
+ for (let i = 0; i < string_.length; i++) {
9
+ hash = hash * 33 ^ string_.charCodeAt(i);
10
+ }
11
+ const range = max - min + 1;
12
+ return min + Math.abs(hash) % range;
13
+ }
14
+ var BigMap = class extends Hookified {
15
+ _storeSize = 4;
16
+ _store = Array.from({ length: this._storeSize }, () => /* @__PURE__ */ new Map());
17
+ _storeHashFunction;
18
+ /**
19
+ * Creates an instance of BigMap.
20
+ * @param {BigMapOptions<K, V>} [options] - Optional configuration options for the BigMap.
21
+ */
22
+ constructor(options) {
23
+ super(options);
24
+ if (options?.storeSize !== void 0) {
25
+ if (options.storeSize < 1) {
26
+ throw new Error("Store size must be at least 1.");
27
+ }
28
+ this.storeSize = options.storeSize;
29
+ }
30
+ this.initStore();
31
+ this._storeHashFunction = options?.storeHashFunction ?? defaultHashFunction;
32
+ }
33
+ /**
34
+ * Gets the number of maps in the store.
35
+ * @returns {number} The number of maps in the store.
36
+ */
37
+ get storeSize() {
38
+ return this._storeSize;
39
+ }
40
+ /**
41
+ * Sets the number of maps in the store. If the size is less than 1, an error is thrown.
42
+ * If you change the store size it will clear all entries.
43
+ * @param {number} size - The new size of the store.
44
+ * @throws {Error} If the size is less than 1.
45
+ */
46
+ set storeSize(size) {
47
+ if (size < 1) {
48
+ throw new Error("Store size must be at least 1.");
49
+ }
50
+ this._storeSize = size;
51
+ this.clear();
52
+ this.initStore();
53
+ }
54
+ /**
55
+ * Gets the hash function used for storing keys.
56
+ * @returns {StoreHashFunction | undefined} The hash function used for storing keys, or undefined if not set.
57
+ */
58
+ get storeHashFunction() {
59
+ return this._storeHashFunction;
60
+ }
61
+ /**
62
+ * Sets the hash function used for storing keys.
63
+ * @param {StoreHashFunction} hashFunction - The hash function to use for storing keys.
64
+ */
65
+ set storeHashFunction(hashFunction) {
66
+ this._storeHashFunction = hashFunction ?? defaultHashFunction;
67
+ }
68
+ /**
69
+ * Gets the store, which is an array of maps.
70
+ * @returns {Array<Map<K, V>>} The array of maps in the store.
71
+ */
72
+ get store() {
73
+ return this._store;
74
+ }
75
+ /**
76
+ * Gets the map at the specified index in the store.
77
+ * @param {number} index - The index of the map to retrieve.
78
+ * @returns {Map<K, V>} The map at the specified index.
79
+ */
80
+ getStoreMap(index) {
81
+ if (index < 0 || index >= this._storeSize) {
82
+ throw new Error(`Index out of bounds: ${index}. Valid range is 0 to ${this._storeSize - 1}.`);
83
+ }
84
+ return this._store[index];
85
+ }
86
+ /**
87
+ * Initializes the store with empty maps.
88
+ * This method is called when the BigMap instance is created.
89
+ */
90
+ initStore() {
91
+ this._store = Array.from({ length: this._storeSize }, () => /* @__PURE__ */ new Map());
92
+ }
93
+ /**
94
+ * Gets the store for a specific key.
95
+ * The store is determined by applying the hash function to the key and the store size.
96
+ * If the hash function is not set, it defaults to using the default hash function.
97
+ * @param key - The key for which to get the store.
98
+ * @returns The store for the specified key.
99
+ */
100
+ getStore(key) {
101
+ if (this._storeSize === 1) {
102
+ return this.getStoreMap(0);
103
+ }
104
+ const storeSize = this._storeSize - 1;
105
+ const index = this._storeHashFunction ? this._storeHashFunction(String(key), storeSize) : defaultHashFunction(String(key), storeSize);
106
+ return this.getStoreMap(index);
107
+ }
108
+ /**
109
+ * Returns an iterable of key-value pairs in the map.
110
+ * @returns {IterableIterator<[K, V]>} An iterable of key-value pairs in the map.
111
+ */
112
+ entries() {
113
+ const entries = [];
114
+ for (const store of this._store) {
115
+ store.forEach((value, key) => entries.push([key, value]));
116
+ }
117
+ return entries[Symbol.iterator]();
118
+ }
119
+ /**
120
+ * Returns an iterable of keys in the map.
121
+ * @returns {IterableIterator<K>} An iterable of keys in the map.
122
+ */
123
+ keys() {
124
+ const keys = [];
125
+ for (const store of this._store) {
126
+ store.forEach((_, key) => keys.push(key));
127
+ }
128
+ return keys[Symbol.iterator]();
129
+ }
130
+ /**
131
+ * Returns an iterable of values in the map.
132
+ * @returns {IterableIterator<V>} An iterable of values in the map.
133
+ */
134
+ values() {
135
+ const values = [];
136
+ for (const store of this._store) {
137
+ store.forEach((value) => values.push(value));
138
+ }
139
+ return values[Symbol.iterator]();
140
+ }
141
+ /**
142
+ * Returns an iterator that iterates over the key-value pairs in the map.
143
+ * @returns {IterableIterator<[K, V]>} An iterator that iterates over the key-value pairs in the map.
144
+ */
145
+ [Symbol.iterator]() {
146
+ const entries = [];
147
+ for (const store of this._store) {
148
+ store.forEach((value, key) => entries.push([key, value]));
149
+ }
150
+ return entries[Symbol.iterator]();
151
+ }
152
+ /**
153
+ * Clears all entries in the map.
154
+ * @returns {void} This method does not return a value.
155
+ */
156
+ clear() {
157
+ for (const store of this._store) {
158
+ store.clear();
159
+ }
160
+ }
161
+ /**
162
+ * Deletes a key-value pair from the map.
163
+ * @param {K} key - The key of the entry to delete.
164
+ * @returns {boolean} Returns true if the entry was deleted, false if the key was not found.
165
+ */
166
+ delete(key) {
167
+ const store = this.getStore(key);
168
+ const deleted = store.delete(key);
169
+ return deleted;
170
+ }
171
+ /**
172
+ * Calls a provided callback function once for each key-value pair in the map.
173
+ * @param {function} callbackfn - The function to execute for each key-value pair.
174
+ * @param {any} [thisArg] - An optional value to use as `this` when executing the callback.
175
+ */
176
+ forEach(callbackfn, thisArg) {
177
+ this._store.forEach((store) => {
178
+ store.forEach(callbackfn, thisArg);
179
+ });
180
+ }
181
+ /**
182
+ * Gets the value associated with the specified key.
183
+ * @param {K} key - The key of the entry to get.
184
+ * @returns {V | undefined} The value associated with the key, or undefined if the key does not exist.
185
+ */
186
+ get(key) {
187
+ const store = this.getStore(key);
188
+ return store.get(key);
189
+ }
190
+ /**
191
+ * Checks if the map contains a key.
192
+ * @param {K} key - The key to check for existence.
193
+ * @returns {boolean} Returns true if the key exists, false otherwise.
194
+ */
195
+ has(key) {
196
+ const store = this.getStore(key);
197
+ return store.has(key);
198
+ }
199
+ /**
200
+ * Sets the value for a key in the map.
201
+ * @param {K} key - The key of the entry to set.
202
+ * @param {V} value - The value to set for the entry.
203
+ * @returns {Map<K, V>} The map instance.
204
+ */
205
+ set(key, value) {
206
+ const store = this.getStore(key);
207
+ store.set(key, value);
208
+ return store;
209
+ }
210
+ /**
211
+ * Gets the number of entries in the map.
212
+ * @returns {number} The number of entries in the map.
213
+ */
214
+ get size() {
215
+ let size = 0;
216
+ for (const store of this._store) {
217
+ size += store.size;
218
+ }
219
+ return size;
220
+ }
221
+ };
222
+ export {
223
+ BigMap,
224
+ defaultHashFunction,
225
+ djb2Hash
226
+ };
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@keyv/bigmap",
3
+ "version": "1.0.0",
4
+ "description": "Bigmap for Keyv",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "require": "./dist/index.cjs",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/jaredwray/keyv.git"
18
+ },
19
+ "keywords": [
20
+ "bigmap",
21
+ "keyv",
22
+ "key",
23
+ "value",
24
+ "store",
25
+ "cache",
26
+ "ttl"
27
+ ],
28
+ "author": "Jared Wray <me@jaredwray.com> (http://jaredwray.com)",
29
+ "license": "MIT",
30
+ "bugs": {
31
+ "url": "https://github.com/jaredwray/keyv/issues"
32
+ },
33
+ "homepage": "https://github.com/jaredwray/keyv",
34
+ "dependencies": {
35
+ "hookified": "^1.10.0"
36
+ },
37
+ "devDependencies": {
38
+ "@faker-js/faker": "^9.9.0",
39
+ "@vitest/coverage-v8": "^3.2.4",
40
+ "rimraf": "^6.0.1",
41
+ "tsd": "^0.32.0",
42
+ "vitest": "^3.2.4",
43
+ "xo": "^1.1.1"
44
+ },
45
+ "tsd": {
46
+ "directory": "test"
47
+ },
48
+ "engines": {
49
+ "node": ">= 20"
50
+ },
51
+ "files": [
52
+ "dist",
53
+ "LICENSE"
54
+ ],
55
+ "scripts": {
56
+ "build": "rimraf ./dist && tsup src/index.ts --format cjs,esm --dts --clean",
57
+ "test": "xo --fix && vitest run --coverage",
58
+ "test:ci": "xo && vitest --run --sequence.setupFiles=list --coverage",
59
+ "clean": "rimraf ./node_modules ./coverage ./dist"
60
+ }
61
+ }