2q-cache
Version:
Imlementation of 2Q Cache Algorithm
136 lines (111 loc) • 3.71 kB
text/typescript
import { Cache } from "./cache";
import { CacheQueue } from "../utils/cache_queue";
import { CacheQueueElem, CacheMapElem } from "../utils/cache_objects";
export class SimpleCache implements Cache {
private searcher : Map<any, CacheMapElem>;
private queue : CacheQueue;
private type : string;
constructor(size, type : string = "lru") {
this.type = type;
this.searcher = new Map();
this.queue = new CacheQueue(size);
}
public set(key : any, value : any, ttl : number = 0) : boolean {
let newQueueElem = new CacheQueueElem();
newQueueElem.key = key;
let newMapElem = new CacheMapElem();
newMapElem.bucket = 2;
newMapElem.linkToList = newQueueElem;
newMapElem.data = value;
let repressedElem = this.type === "lru" ? this.queue.push(newQueueElem)
:this.queue.unshift(newQueueElem);
this.searcher.set(key, newMapElem);
if (ttl > 0) {
newMapElem.timeout = setTimeout(() => {
if (this.has(key)) this.delete(key)
}, ttl)
}
if (repressedElem != null) {
this.searcher.delete(repressedElem.key);
}
return true;
}
public get(key : any) : any {
let foundElem = this.searcher.get(key);
if (foundElem) {
let foundListElem = foundElem.linkToList;
this.queue.push(this.queue.unlink(foundListElem));
return foundElem.data;
} else {
return null;
}
}
public delete(key : any) : boolean {
let elemToDelete = this.searcher.get(key);
if (elemToDelete) {
clearTimeout(elemToDelete.timeout);
this.searcher.delete(key);
this.queue.unlink(elemToDelete.linkToList);
elemToDelete.linkToList = null;
return true;
} else {
return false;
}
}
public has(key : any) : boolean {
return this.searcher.has(key);
}
public clear() {
this.searcher.forEach(value => {
clearTimeout(value.timeout);
})
this.searcher.clear();
this.queue.clear();
}
public update(key : any, value : any, ttl : number = 0) : boolean {
let mapElem = this.searcher.get(key);
clearTimeout(mapElem.timeout);
if (ttl > 0) {
mapElem.timeout = setTimeout(() => {
this.delete(key);
}, ttl)
}
mapElem.data = value;
return true;
}
updateTtl(key : any, ttl : number = 0) : boolean {
let mapElem = this.searcher.get(key);
clearTimeout(mapElem.timeout);
if (ttl > 0) {
mapElem.timeout = setTimeout(() => {
this.delete(key);
}, ttl)
}
return true;
}
getSize() : number {
return this.queue.getSize();
}
getMaxSize() : number {
return this.queue.getMaxSize();
}
getSizeObject() : object {
return {
currentSize : this.queue.getSize(),
maxSize : this.queue.getMaxSize()
}
}
setSize(number : number) {
this.queue.setSize(number);
while (this.queue.getSize() > this.queue.getMaxSize()) {
let deletedElem = this.queue.pop();
this.searcher.delete(deletedElem.key);
}
}
getData() : object {
return {
searcher : this.searcher,
data : this.queue.getData()
}
}
}