"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Implements an LRUCache using the ES6 Map.prototype and not
* a custom doubly linked list.
*
* {@link https://en.wikipedia.org/wiki/Cache_replacement_policies Cache Strategies on Wikipedia}
*/
class LRUCache {
/**
* Creates a LRUCache.
* @time O(1)
* @constructs LRUCache
* @param {Object|Number} options object of options or number thats set on this.max.
*/
constructor(options) {
if (typeof options === "object") {
this.max = options.max;
}
else {
this.max = options;
}
this.store = new Map();
this.size = this.store.size;
}
/**
* Returns a value from the cache associated with a key.
* @time O(1)
* @param {*} key Can be objects or primitive values.
* @return {*} Can be objects and primitive values.
*/
get(key) {
const value = this.store.get(key);
if (!value) {
return undefined;
}
this.store.delete(key);
this.store.set(key, value);
return value;
}
/**
* Sets a key and its value in the cache at the most recent position/last index
* @time O(1)
* @param {*} key Can be objects or primitive values.
* @param {*} value Can be objects or primitive values.
* @return {LRUCache} this instance
*/
set(key, value) {
const oldValue = this.get(key);
if (oldValue === undefined) {
if (this.store.size === this.max) {
this.store.delete(this.store.entries().next().value[0]);
}
this.store.set(key, value);
}
this.size = this.store.size;
return this;
}
/**
* Deletes a key/value pair from any where in the cache.
* @time O(1)
* @return {LRUCache} this instance
*/
delete(key) {
this.store.delete(key);
this.size = this.store.size;
return this;
}
/**
* clears all keys and values from the store and sets size to 0
* @time O(1)
* @return {LRUCache} this instance
*/
clear() {
this.store.clear();
this.size = this.store.size;
return this;
}
/**
* Updates the max capacity of the cache. If the
* max capacity of the cache is less than the current max capacity
* and the cache is at max capacity, the cache will shed
* the older items.
* @time O(n)
* @param {number} newMax The value that will be the new max capacity for the cache.
* @return {LRUCache} This instance.
*/
updateMax(newMax) {
if (newMax === this.max || this.isZero(newMax) || this.isNegative(newMax)) {
return this;
}
if (newMax > this.max) {
this.max = newMax;
return this;
}
this.shedOlderEntries(this.max - newMax - (this.max - this.size));
this.max = newMax;
return this;
}
/**
* Checks if value is negative
* @private
* @param {number} num A positive or negative integer.
* @time O(1)
* @return {boolean}
*/
isNegative(num) {
return Math.sign(num) === -1;
}
/**
* Checks if value is zero
* @private
* @param {number} num A positive or negative integer.
* @time O(1)
* @return {boolean} boolean
*/
isZero(num) {
return Math.sign(num) === 0;
}
/**
* Deletes n oldest entries where n = numberOfEntries, from the store.
* @private
* @param {number} numberOfEntries Number of older entries to be deleted.
* @time O(n)
*/
shedOlderEntries(numberOfEntries) {
for (let i = numberOfEntries; i > 0; i--) {
const key = this.store.entries().next().value[0];
this.delete(key);
}
}
}
exports.default = LRUCache;
//# sourceMappingURL=LRUCache.js.map