atomic-fns
Version:
Like Lodash, but for ESNext and with types. Stop shipping code built for browsers from 2015.
127 lines (126 loc) • 3.67 kB
JavaScript
import { Mapping } from './abc.js';
/**
* Implements a Least Recently Used fixed-capacity cache which supports updating, removing, and accessing keys in O(1).
* @template K, V
*/
export class LRUCache extends Mapping {
items = new Map();
maxSize;
/**
* Creates a new instance of fixed size.
* @param {number} capacity
*/
constructor(capacity = 1024) {
super();
this.maxSize = capacity;
}
/**
* Adds a new element with a specified `key` and `value` to the cache. If an element with the same key already exists, the element will be updated.
* @param {K} key
* @param {V} value
* @returns {this}
*/
set(key, value) {
if (this.items.size === this.maxSize) {
// Because ES6 maps remember insertion order, we can evict the first key
const lastKey = this.items.keys().next().value;
this.items.delete(lastKey);
}
// Delete the previous key to update the new insertion order
this.items.delete(key);
this.items.set(key, value);
return this;
}
/**
* This is just an alias of {@link LRUCache.set}.
* @param {K} key The key to add (note value will be `undefined`)
* @returns {this}
*/
add(key) {
return this.set(key, undefined);
}
/**
* Returns `true` if the specified `key` is found on the cache.
* @param {K} key
* @returns {boolean}
*/
contains(key) {
return this.items.has(key);
}
/**
* Get the value associated with the specified `key`, or `undefined` it not found.
* @param {K} key
* @returns {?V} The associated value or `undefined`
*/
get(key) {
if (this.items.has(key)) {
const value = this.items.get(key);
// Delete the previous key to update the new insertion order
this.items.delete(key);
this.items.set(key, value);
return value;
}
}
/**
* Removes all keys and values from the cache.
* @returns {this}
*/
clear() {
this.items.clear();
return this;
}
/**
* Removes a key from the cache and returns `true` if the key existed or `false` otherwise.
* @param {K} key
* @returns {boolean} `true` if the key existed and was removed
*/
delete(key) {
return this.items.delete(key);
}
/**
* Removes the value associated with the specified `key` from the cache and returns the removed value if the key existed.
* @param {K} key
* @returns {?V} The value if it was removed or `undefined`.
*/
remove(key) {
const value = this.items.get(key);
this.items.delete(key);
return value;
}
/**
* Returns the total number of elements in the cache.
*/
get size() {
return this.items.size;
}
/**
* Returns the total capacity of the cache.
*/
get capacity() {
return this.maxSize;
}
/**
* Returns an iterable of all the keys in the cache, in insertion order.
* @returns {IterableIterator<K>}
*/
keys() {
return this.items.keys();
}
/**
* Returns an iterable of all the values in the cache, in insertion order.
* @returns {IterableIterator<V>}
*/
values() {
return this.items.values();
}
/**
* Returns an iterable of all the [key, value] pairs in the cache, in insertion order.
* @returns {IterableIterator<[K, V]>}
*/
entries() {
return this.items.entries();
}
[Symbol.iterator]() {
return this.entries();
}
}