2q-cache
Version:
Imlementation of 2Q Cache Algorithm
138 lines (120 loc) • 3.87 kB
text/typescript
import { CacheHeapElem} from "./cache_objects";
export class CacheHeap {
private count : number = 0;
private maxCount : number;
private data : Array<CacheHeapElem>;
constructor(maxCount : number) {
this.data = new Array(maxCount);
this.maxCount = maxCount;
this.count = 0;
}
setMaxSize(size : number) : Array<CacheHeapElem> {
this.maxCount = size;
let newData = new Array(this.maxCount);
this.count = 0;
for (let i = 0; i < Math.min(this.data.length, newData.length); i++) {
if (this.data[i]) {
newData[i] = this.data[i];
} else {
break;
}
}
let unusedElements : Array<CacheHeapElem> = [];
if (this.data.length > newData.length) {
for (let i = newData.length; i < this.data.length; i++) {
unusedElements.push(this.data[i]);
}
}
this.data = newData;
return unusedElements;
}
insert(elem : CacheHeapElem) : CacheHeapElem {
this.count++;
if (this.count > this.maxCount) {
this.count--;
let oldMin = this.data[0];
this.data[0] = elem;
elem.index = 0;
this.siftDown(0);
return oldMin;
} else {
elem.index = this.count - 1;
this.data[this.count - 1] = elem;
this.siftUp(this.count - 1);
return null;
}
}
increment(elem : CacheHeapElem) : void {
let i : number = elem.index;
this.data[i].count++;
this.siftDown(i);
}
delete(elem : CacheHeapElem) : CacheHeapElem {
let i : number = elem.index;
this.data[i].count = Infinity;
let pos = this.siftDown(i);
let elemToDelete = this.data[pos];
this.data[pos] = undefined;
if (this.data[pos + 1] != undefined) {
this.swap(pos, pos + 1);
}
this.count--;
return elemToDelete;
}
private siftDown(pos : number) : number {
let i : number = pos;
while (2 * i + 1 < this.count) {
let left : number = 2 * i + 1;
let right : number = 2 * i + 2;
let j = left;
if ((right < this.count) && (this.data[left].count > this.data[right].count)) {
j = right;
}
if (this.data[i].count <= this.data[j].count) break;
this.swap(i, j);
i = j;
}
return i;
}
private siftUp(pos : number) : number {
let i : number = pos;
while ((i != 0)
&& (this.data[i].count < this.data[Math.floor((i - 1) / 2)].count)
) {
this.swap(i, Math.floor((i - 1) / 2));
i = Math.floor((i - 1) / 2);
}
return i;
}
private swap(first : number, second : number) : void {
this.data[first].index = second;
this.data[second].index = first;
let temp : CacheHeapElem = this.data[first];
this.data[first] = this.data[second];
this.data[second] = temp;
}
toStringKeys() : String {
let keys = [];
for (let i = 0; i < this.count; i++) {
keys.push(this.data[i].key);
}
return keys.join(" ");
}
getData() : object {
let dataArray = [];
this.data.forEach((elem) => {
dataArray.push(elem.key);
})
return {
data : this.data,
count : this.count,
maxCount : this.maxCount
}
}
getCount() {
return this.count;
}
getMaxCount() {
return this.maxCount;
}
}