UNPKG

molstar

Version:

A comprehensive macromolecular library.

104 lines (103 loc) 3.02 kB
/** * Copyright (c) 2018-2025 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> * @author David Sehnal <david.sehnal@gmail.com> */ /** A `Map` instance with a `getDefault` method added. */ export function DefaultMap(valueCtor) { const map = new Map(); map.getDefault = (key) => { if (map.has(key)) return map.get(key); const value = valueCtor(); map.set(key, value); return value; }; return map; } // TODO currently not working, see https://github.com/Microsoft/TypeScript/issues/10853 // /** A `Map` with a `getDefault` method added. */ // export class DefaultMap<K, V> extends Map<K, V> { // constructor(private valueCtor: () => V, entries?: ReadonlyArray<[K, V]>) { // super(entries) // } // /** Return the value for `key` when available or the default value otherwise. */ // getDefault(key: K) { // if (this.has(key)) return this.get(key)! // const value = this.valueCtor() // this.set(key, value) // return value // } // } export function arrayMapAdd(map, key, value) { const a = map.get(key); if (a) { a.push(value); } else { map.set(key, [value]); } } export class HashMap { set(key, value) { const hashCode = this.hashCode(key); let bucket = this.buckets.get(hashCode); if (!bucket) { bucket = []; this.buckets.set(hashCode, bucket); } for (let i = 0; i < bucket.length; i++) { if (this.areEqual(bucket[i].key, key)) { bucket[i].value = value; return; } } bucket.push({ key, value }); } get(key) { const hashCode = this.hashCode(key); const bucket = this.buckets.get(hashCode); if (!bucket) { return undefined; } for (const entry of bucket) { if (this.areEqual(entry.key, key)) { return entry.value; } } return undefined; } delete(key) { const hashCode = this.hashCode(key); const bucket = this.buckets.get(hashCode); if (!bucket) { return false; } for (let i = 0; i < bucket.length; i++) { if (this.areEqual(bucket[i].key, key)) { bucket.splice(i, 1); if (bucket.length === 0) { this.buckets.delete(hashCode); } return true; } } return false; } forEach(cb) { for (const bucket of this.buckets.values()) { for (const entry of bucket) { cb(entry.value, entry.key); } } } clear() { this.buckets.clear(); } constructor(hashCode, areEqual) { this.hashCode = hashCode; this.areEqual = areEqual; this.buckets = new Map(); } }