You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							124 lines
						
					
					
						
							2.0 KiB
						
					
					
				
			
		
		
	
	
							124 lines
						
					
					
						
							2.0 KiB
						
					
					
				| 'use strict';
 | |
| 
 | |
| class QuickLRU {
 | |
| 	constructor(options = {}) {
 | |
| 		if (!(options.maxSize && options.maxSize > 0)) {
 | |
| 			throw new TypeError('`maxSize` must be a number greater than 0');
 | |
| 		}
 | |
| 
 | |
| 		this.maxSize = options.maxSize;
 | |
| 		this.onEviction = options.onEviction;
 | |
| 		this.cache = new Map();
 | |
| 		this.oldCache = new Map();
 | |
| 		this._size = 0;
 | |
| 	}
 | |
| 
 | |
| 	_set(key, value) {
 | |
| 		this.cache.set(key, value);
 | |
| 		this._size++;
 | |
| 
 | |
| 		if (this._size >= this.maxSize) {
 | |
| 			this._size = 0;
 | |
| 
 | |
| 			if (typeof this.onEviction === 'function') {
 | |
| 				for (const [key, value] of this.oldCache.entries()) {
 | |
| 					this.onEviction(key, value);
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			this.oldCache = this.cache;
 | |
| 			this.cache = new Map();
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	get(key) {
 | |
| 		if (this.cache.has(key)) {
 | |
| 			return this.cache.get(key);
 | |
| 		}
 | |
| 
 | |
| 		if (this.oldCache.has(key)) {
 | |
| 			const value = this.oldCache.get(key);
 | |
| 			this.oldCache.delete(key);
 | |
| 			this._set(key, value);
 | |
| 			return value;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	set(key, value) {
 | |
| 		if (this.cache.has(key)) {
 | |
| 			this.cache.set(key, value);
 | |
| 		} else {
 | |
| 			this._set(key, value);
 | |
| 		}
 | |
| 
 | |
| 		return this;
 | |
| 	}
 | |
| 
 | |
| 	has(key) {
 | |
| 		return this.cache.has(key) || this.oldCache.has(key);
 | |
| 	}
 | |
| 
 | |
| 	peek(key) {
 | |
| 		if (this.cache.has(key)) {
 | |
| 			return this.cache.get(key);
 | |
| 		}
 | |
| 
 | |
| 		if (this.oldCache.has(key)) {
 | |
| 			return this.oldCache.get(key);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	delete(key) {
 | |
| 		const deleted = this.cache.delete(key);
 | |
| 		if (deleted) {
 | |
| 			this._size--;
 | |
| 		}
 | |
| 
 | |
| 		return this.oldCache.delete(key) || deleted;
 | |
| 	}
 | |
| 
 | |
| 	clear() {
 | |
| 		this.cache.clear();
 | |
| 		this.oldCache.clear();
 | |
| 		this._size = 0;
 | |
| 	}
 | |
| 
 | |
| 	* keys() {
 | |
| 		for (const [key] of this) {
 | |
| 			yield key;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	* values() {
 | |
| 		for (const [, value] of this) {
 | |
| 			yield value;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	* [Symbol.iterator]() {
 | |
| 		for (const item of this.cache) {
 | |
| 			yield item;
 | |
| 		}
 | |
| 
 | |
| 		for (const item of this.oldCache) {
 | |
| 			const [key] = item;
 | |
| 			if (!this.cache.has(key)) {
 | |
| 				yield item;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	get size() {
 | |
| 		let oldCacheSize = 0;
 | |
| 		for (const key of this.oldCache.keys()) {
 | |
| 			if (!this.cache.has(key)) {
 | |
| 				oldCacheSize++;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return Math.min(this._size + oldCacheSize, this.maxSize);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| module.exports = QuickLRU;
 |