@wireapp/lru-cache
Version:
Least Recently Used (LRU) Cache for JavaScript and TypeScript.
151 lines • 3.73 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LRUCache = void 0;
class LRUCache {
constructor(capacity = 100) {
this.capacity = capacity;
this.map = {};
this.head = null;
this.end = null;
}
delete(key) {
const node = this.map[key];
if (node) {
this.remove(node);
delete this.map[node.key];
return true;
}
return false;
}
deleteAll() {
this.map = {};
this.head = null;
this.end = null;
}
get(key) {
const node = this.map[key];
if (node) {
this.remove(node);
this.setHead(node);
return node.value;
}
return undefined;
}
getAll() {
return Object.keys(this.map).reduce((accumulator, id) => {
const node = this.map[id];
accumulator[id] = node.value;
return accumulator;
}, {});
}
keys() {
const keys = [];
let entry = this.head;
while (entry) {
keys.push(entry.key);
entry = entry.next;
}
return keys;
}
latest() {
if (this.head) {
return this.head.value;
}
return null;
}
oldest() {
if (this.end) {
return this.end.value;
}
return null;
}
remove(node) {
if (node.previous) {
node.previous.next = node.next;
}
else {
this.head = node.next;
}
if (node.next !== null) {
node.next.previous = node.previous;
}
else {
this.end = node.previous;
}
return node;
}
set(key, value) {
const matchedNode = this.map[key];
let removedNode;
if (matchedNode) {
const removedValue = matchedNode.value;
matchedNode.value = value;
this.remove(matchedNode);
this.setHead(matchedNode);
return removedValue;
}
const created = {
key,
next: null,
previous: null,
value,
};
const isOverCapacity = this.size() >= this.capacity;
if (isOverCapacity) {
if (this.end) {
delete this.map[this.end.key];
removedNode = this.remove(this.end);
}
}
if (this.capacity > 0) {
this.setHead(created);
this.map[key] = created;
}
if (removedNode) {
return removedNode.value;
}
return undefined;
}
setOnce(key, value) {
const matchedNode = this.map[key];
if (matchedNode) {
return undefined;
}
return this.set(key, value);
}
setHead(node) {
node.next = this.head;
node.previous = null;
if (this.head) {
this.head.previous = node;
}
this.head = node;
if (!this.end) {
this.end = this.head;
}
}
size() {
return Object.keys(this.map).length;
}
toString() {
let string = '(newest) ';
let entry = this.head;
while (entry) {
string += `${String(entry.key)}:${entry.value}`;
entry = entry.next;
if (entry) {
string += ' > ';
}
}
return `${string} (oldest)`;
}
*[Symbol.iterator]() {
let entry = this.head;
while (entry) {
yield entry.value;
entry = entry.next;
}
}
}
exports.LRUCache = LRUCache;
//# sourceMappingURL=LRUCache.js.map