UNPKG

@keyv/bigmap

Version:
227 lines (226 loc) 7 kB
// src/index.ts import { Hookified } from "hookified"; function defaultHashFunction(key, storeSize) { return djb2Hash(key, 0, storeSize - 1); } function djb2Hash(string_, min = 0, max = 10) { let hash = 5381; for (let i = 0; i < string_.length; i++) { hash = hash * 33 ^ string_.charCodeAt(i); } const range = max - min + 1; return min + Math.abs(hash) % range; } var BigMap = class extends Hookified { _storeSize = 4; _store = Array.from({ length: this._storeSize }, () => /* @__PURE__ */ new Map()); _storeHashFunction; /** * Creates an instance of BigMap. * @param {BigMapOptions<K, V>} [options] - Optional configuration options for the BigMap. */ constructor(options) { super(options); if (options?.storeSize !== void 0) { if (options.storeSize < 1) { throw new Error("Store size must be at least 1."); } this.storeSize = options.storeSize; } this.initStore(); this._storeHashFunction = options?.storeHashFunction ?? defaultHashFunction; } /** * Gets the number of maps in the store. * @returns {number} The number of maps in the store. */ get storeSize() { return this._storeSize; } /** * Sets the number of maps in the store. If the size is less than 1, an error is thrown. * If you change the store size it will clear all entries. * @param {number} size - The new size of the store. * @throws {Error} If the size is less than 1. */ set storeSize(size) { if (size < 1) { throw new Error("Store size must be at least 1."); } this._storeSize = size; this.clear(); this.initStore(); } /** * Gets the hash function used for storing keys. * @returns {StoreHashFunction | undefined} The hash function used for storing keys, or undefined if not set. */ get storeHashFunction() { return this._storeHashFunction; } /** * Sets the hash function used for storing keys. * @param {StoreHashFunction} hashFunction - The hash function to use for storing keys. */ set storeHashFunction(hashFunction) { this._storeHashFunction = hashFunction ?? defaultHashFunction; } /** * Gets the store, which is an array of maps. * @returns {Array<Map<K, V>>} The array of maps in the store. */ get store() { return this._store; } /** * Gets the map at the specified index in the store. * @param {number} index - The index of the map to retrieve. * @returns {Map<K, V>} The map at the specified index. */ getStoreMap(index) { if (index < 0 || index >= this._storeSize) { throw new Error(`Index out of bounds: ${index}. Valid range is 0 to ${this._storeSize - 1}.`); } return this._store[index]; } /** * Initializes the store with empty maps. * This method is called when the BigMap instance is created. */ initStore() { this._store = Array.from({ length: this._storeSize }, () => /* @__PURE__ */ new Map()); } /** * Gets the store for a specific key. * The store is determined by applying the hash function to the key and the store size. * If the hash function is not set, it defaults to using the default hash function. * @param key - The key for which to get the store. * @returns The store for the specified key. */ getStore(key) { if (this._storeSize === 1) { return this.getStoreMap(0); } const storeSize = this._storeSize - 1; const index = this._storeHashFunction ? this._storeHashFunction(String(key), storeSize) : defaultHashFunction(String(key), storeSize); return this.getStoreMap(index); } /** * Returns an iterable of key-value pairs in the map. * @returns {IterableIterator<[K, V]>} An iterable of key-value pairs in the map. */ entries() { const entries = []; for (const store of this._store) { store.forEach((value, key) => entries.push([key, value])); } return entries[Symbol.iterator](); } /** * Returns an iterable of keys in the map. * @returns {IterableIterator<K>} An iterable of keys in the map. */ keys() { const keys = []; for (const store of this._store) { store.forEach((_, key) => keys.push(key)); } return keys[Symbol.iterator](); } /** * Returns an iterable of values in the map. * @returns {IterableIterator<V>} An iterable of values in the map. */ values() { const values = []; for (const store of this._store) { store.forEach((value) => values.push(value)); } return values[Symbol.iterator](); } /** * Returns an iterator that iterates over the key-value pairs in the map. * @returns {IterableIterator<[K, V]>} An iterator that iterates over the key-value pairs in the map. */ [Symbol.iterator]() { const entries = []; for (const store of this._store) { store.forEach((value, key) => entries.push([key, value])); } return entries[Symbol.iterator](); } /** * Clears all entries in the map. * @returns {void} This method does not return a value. */ clear() { for (const store of this._store) { store.clear(); } } /** * Deletes a key-value pair from the map. * @param {K} key - The key of the entry to delete. * @returns {boolean} Returns true if the entry was deleted, false if the key was not found. */ delete(key) { const store = this.getStore(key); const deleted = store.delete(key); return deleted; } /** * Calls a provided callback function once for each key-value pair in the map. * @param {function} callbackfn - The function to execute for each key-value pair. * @param {any} [thisArg] - An optional value to use as `this` when executing the callback. */ forEach(callbackfn, thisArg) { this._store.forEach((store) => { store.forEach(callbackfn, thisArg); }); } /** * Gets the value associated with the specified key. * @param {K} key - The key of the entry to get. * @returns {V | undefined} The value associated with the key, or undefined if the key does not exist. */ get(key) { const store = this.getStore(key); return store.get(key); } /** * Checks if the map contains a key. * @param {K} key - The key to check for existence. * @returns {boolean} Returns true if the key exists, false otherwise. */ has(key) { const store = this.getStore(key); return store.has(key); } /** * Sets the value for a key in the map. * @param {K} key - The key of the entry to set. * @param {V} value - The value to set for the entry. * @returns {Map<K, V>} The map instance. */ set(key, value) { const store = this.getStore(key); store.set(key, value); return store; } /** * Gets the number of entries in the map. * @returns {number} The number of entries in the map. */ get size() { let size = 0; for (const store of this._store) { size += store.size; } return size; } }; export { BigMap, defaultHashFunction, djb2Hash };