|
|
|
;
|
|
|
|
!(function () {
|
|
|
|
BI.LRU = function (limit) {
|
|
|
|
this.size = 0;
|
|
|
|
this.limit = limit;
|
|
|
|
this.head = this.tail = undefined;
|
|
|
|
this._keymap = {};
|
|
|
|
};
|
|
|
|
|
|
|
|
var p = BI.LRU.prototype;
|
|
|
|
|
|
|
|
p.put = function (key, value) {
|
|
|
|
var removed;
|
|
|
|
if (this.size === this.limit) {
|
|
|
|
removed = this.shift();
|
|
|
|
}
|
|
|
|
|
|
|
|
var entry = this.get(key, true);
|
|
|
|
if (!entry) {
|
|
|
|
entry = {
|
|
|
|
key: key
|
|
|
|
};
|
|
|
|
this._keymap[key] = entry;
|
|
|
|
if (this.tail) {
|
|
|
|
this.tail.newer = entry;
|
|
|
|
entry.older = this.tail
|
|
|
|
} else {
|
|
|
|
this.head = entry
|
|
|
|
}
|
|
|
|
this.tail = entry;
|
|
|
|
this.size++;
|
|
|
|
}
|
|
|
|
entry.value = value;
|
|
|
|
|
|
|
|
return removed;
|
|
|
|
};
|
|
|
|
|
|
|
|
p.shift = function () {
|
|
|
|
var entry = this.head;
|
|
|
|
if (entry) {
|
|
|
|
this.head = this.head.newer;
|
|
|
|
this.head.older = undefined;
|
|
|
|
entry.newer = entry.older = undefined;
|
|
|
|
this._keymap[entry.key] = undefined;
|
|
|
|
this.size--;
|
|
|
|
}
|
|
|
|
return entry;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
p.get = function (key, returnEntry) {
|
|
|
|
var entry = this._keymap[key];
|
|
|
|
if (entry === undefined) return;
|
|
|
|
if (entry === this.tail) {
|
|
|
|
return returnEntry
|
|
|
|
? entry
|
|
|
|
: entry.value
|
|
|
|
}
|
|
|
|
// HEAD--------------TAIL
|
|
|
|
// <.older .newer>
|
|
|
|
// <--- add direction --
|
|
|
|
// A B C <D> E
|
|
|
|
if (entry.newer) {
|
|
|
|
if (entry === this.head) {
|
|
|
|
this.head = entry.newer
|
|
|
|
}
|
|
|
|
entry.newer.older = entry.older; // C <-- E.
|
|
|
|
}
|
|
|
|
if (entry.older) {
|
|
|
|
entry.older.newer = entry.newer; // C. --> E
|
|
|
|
}
|
|
|
|
entry.newer = undefined; // D --x
|
|
|
|
entry.older = this.tail; // D. --> E
|
|
|
|
if (this.tail) {
|
|
|
|
this.tail.newer = entry; // E. <-- D
|
|
|
|
}
|
|
|
|
this.tail = entry;
|
|
|
|
return returnEntry
|
|
|
|
? entry
|
|
|
|
: entry.value
|
|
|
|
};
|
|
|
|
|
|
|
|
p.has = function (key) {
|
|
|
|
return this._keymap[key] != null;
|
|
|
|
}
|
|
|
|
})();
|