Comparing version 0.0.25 to 0.0.26
@@ -1,2 +0,2 @@ | ||
/*! dw-cache v0.0.25 https://github.com/falsandtru/dw-cache | (c) 2021, falsandtru | (Apache-2.0 AND MPL-2.0) License */ | ||
/*! dw-cache v0.0.26 https://github.com/falsandtru/dw-cache | (c) 2021, falsandtru | (Apache-2.0 AND MPL-2.0) License */ | ||
require = function () { | ||
@@ -342,3 +342,2 @@ function r(e, n, t) { | ||
const global_1 = _dereq_('./global'); | ||
const alias_1 = _dereq_('./alias'); | ||
const clock_1 = _dereq_('./clock'); | ||
@@ -396,3 +395,2 @@ const invlist_1 = _dereq_('./invlist'); | ||
throw new Error(`Spica: Cache: Capacity must be 1 or more.`); | ||
this.frequency = (0, alias_1.max)(this.capacity / 100 | 0, 1); | ||
this.space = settings.space; | ||
@@ -434,20 +432,18 @@ this.life = this.capacity * settings.life; | ||
switch (true) { | ||
case LRU.length === 0: | ||
target = LFU.last; | ||
target = target !== skip ? target : target.prev; | ||
break; | ||
case lastIndex && lastIndex.clock < this.clock - this.life: | ||
case lastIndex && lastIndex.expiry !== global_1.Infinity && lastIndex.expiry < (0, clock_1.now)(): | ||
target = lastNode; | ||
target = lastNode.list === OVF ? lastNode.value.parent : lastNode; | ||
break; | ||
case LRU.length === 0: | ||
target = LFU.last !== skip ? LFU.last : LFU.last.prev; | ||
break; | ||
case LFU.length > this.capacity * this.ratio / 100: | ||
target = LFU.last; | ||
LRU.unshiftNode(target); | ||
target.value.overflow = OVF.unshift(target.value); | ||
LRU.unshiftNode(LFU.last); | ||
LRU.head.value.parent = LRU.head; | ||
LRU.head.value.overflow = OVF.unshift(LRU.head.value); | ||
default: | ||
target = LRU.last; | ||
target = target !== skip ? target : target.prev !== skip ? target.prev : LFU.last; | ||
target = LRU.last !== skip ? LRU.last : LRU.last.prev !== skip ? LRU.last.prev : LFU.last; | ||
} | ||
this.dispose(target, void 0, true); | ||
skip = (skip === null || skip === void 0 ? void 0 : skip.list) ? skip : void 0; | ||
skip = (skip === null || skip === void 0 ? void 0 : skip.list) && skip; | ||
size = (_c = skip === null || skip === void 0 ? void 0 : skip.value.size) !== null && _c !== void 0 ? _c : 0; | ||
@@ -560,6 +556,6 @@ } | ||
const {LRU, LFU} = this.stats; | ||
const {capacity, frequency, ratio, limit, indexes} = this; | ||
const {capacity, ratio, limit, indexes} = this; | ||
const window = capacity; | ||
LRU[0] + LFU[0] === window && this.stats.slide(); | ||
if ((LRU[0] + LFU[0]) % frequency || LRU[1] + LFU[1] === 0) | ||
if ((LRU[0] + LFU[0]) * 100 % capacity || LRU[1] + LFU[1] === 0) | ||
return; | ||
@@ -570,9 +566,10 @@ const lenR = indexes.LRU.length; | ||
const r = (lenF + lenV) * 1000 / (lenR + lenF) | 0; | ||
const rateR = rate(window, LRU[0], LRU[0] + LFU[0], LRU[1], LRU[1] + LFU[1]) * (1 + r); | ||
const rateF = rate(window, LFU[0], LRU[0] + LFU[0], LFU[1], LRU[1] + LFU[1]) * (1001 - r); | ||
if (ratio > 0 && rateR > rateF || ratio > 0 && rateF < rate(window, LFU[1], LRU[1] + LFU[1], LFU[0], LRU[0] + LFU[0]) * (1001 - r) * 0.95) { | ||
const rateR0 = rate(window, LRU[0], LRU[0] + LFU[0], LRU[1], LRU[1] + LFU[1], 0) * (1 + r); | ||
const rateF0 = rate(window, LFU[0], LRU[0] + LFU[0], LFU[1], LRU[1] + LFU[1], 0) * (1001 - r); | ||
const rateF1 = rate(window, LFU[1], LRU[1] + LFU[1], LFU[0], LRU[0] + LFU[0], 5) * (1001 - r); | ||
if (ratio > 0 && (rateR0 > rateF0 || rateF0 < rateF1 * 0.95)) { | ||
if (lenR >= capacity * (100 - ratio) / 100) { | ||
--this.ratio; | ||
} | ||
} else if (ratio < limit && rateF > rateR) { | ||
} else if (ratio < limit && rateF0 > rateR0) { | ||
if (lenF >= capacity * ratio / 100) { | ||
@@ -614,7 +611,8 @@ ++this.ratio; | ||
exports.Cache = Cache; | ||
function rate(window, currHits, currTotal, prevHits, prevTotal) { | ||
window = (0, alias_1.min)(currTotal + prevTotal, window); | ||
function rate(window, currHits, currTotal, prevHits, prevTotal, offset) { | ||
const prevRate = prevHits * 100 / prevTotal | 0; | ||
const currRatio = currTotal * 100 / window - offset | 0; | ||
if (currRatio <= 0) | ||
return prevRate * 100; | ||
const currRate = currHits * 100 / currTotal | 0; | ||
const currRatio = (0, alias_1.min)(currTotal * 100 / window | 0, 100); | ||
const prevRate = prevHits * 100 / prevTotal | 0; | ||
const prevRatio = 100 - currRatio; | ||
@@ -625,3 +623,2 @@ return currRate * currRatio + prevRate * prevRatio; | ||
{ | ||
'./alias': 3, | ||
'./assign': 5, | ||
@@ -628,0 +625,0 @@ './clock': 7, |
{ | ||
"name": "dw-cache", | ||
"version": "0.0.25", | ||
"version": "0.0.26", | ||
"description": "Dual window cache adaptively coordinates the ratio of LRU to LFU using the two sliding windows.", | ||
@@ -44,3 +44,3 @@ "private": false, | ||
"gulp-unassert": "^2.0.0", | ||
"karma": "^6.3.12", | ||
"karma": "^6.3.15", | ||
"karma-chrome-launcher": "^3.1.0", | ||
@@ -53,5 +53,5 @@ "karma-coverage-istanbul-instrumenter": "^1.0.4", | ||
"mocha": "^9.2.0", | ||
"npm-check-updates": "^12.2.1", | ||
"npm-check-updates": "^12.3.0", | ||
"power-assert": "^1.6.1", | ||
"spica": "0.0.506", | ||
"spica": "0.0.507", | ||
"tsify": "^5.0.4", | ||
@@ -58,0 +58,0 @@ "typescript": "4.5.5", |
@@ -21,39 +21,39 @@ # Dual Window Cache | ||
'Cache even 100' | ||
'LRU hit rate', 9.87 | ||
'DWC hit rate', 9.84 | ||
'DWC ratio', 0, 0 | ||
'LRU hit rate', 10.19 | ||
'DWC hit rate', 10.18 | ||
'DWC ratio', 16, 16 | ||
'DWC / LRU hit rate ratio', '99%' | ||
'Cache uneven 100' | ||
'LRU hit rate', 19.14 | ||
'DWC hit rate', 36.52 | ||
'DWC ratio', 95, 93 | ||
'DWC / LRU hit rate ratio', '190%' | ||
'LRU hit rate', 19.13 | ||
'DWC hit rate', 37.85 | ||
'DWC ratio', 95, 95 | ||
'DWC / LRU hit rate ratio', '197%' | ||
'Cache uneven 100 transitive distribution' | ||
'LRU hit rate', 17.74 | ||
'DWC hit rate', 37.15 | ||
'DWC ratio', 95, 95 | ||
'DWC / LRU hit rate ratio', '209%' | ||
'LRU hit rate', 18.5 | ||
'DWC hit rate', 37.4 | ||
'DWC ratio', 95, 94 | ||
'DWC / LRU hit rate ratio', '202%' | ||
'Cache uneven 100 transitive bias' | ||
'LRU hit rate', 10.99 | ||
'DWC hit rate', 11.02 | ||
'DWC ratio', 0, 1 | ||
'LRU hit rate', 11.12 | ||
'DWC hit rate', 11.12 | ||
'DWC ratio', 0, 0 | ||
'DWC / LRU hit rate ratio', '100%' | ||
'Cache uneven 100 sequential' | ||
'LRU hit rate', 13.47 | ||
'DWC hit rate', 37.53 | ||
'LRU hit rate', 14.26 | ||
'DWC hit rate', 38.19 | ||
'DWC ratio', 95, 95 | ||
'DWC / LRU hit rate ratio', '278%' | ||
'DWC / LRU hit rate ratio', '267%' | ||
'Cache uneven 100 adversarial' | ||
'LRU hit rate', 41.78 | ||
'DWC hit rate', 49.77 | ||
'DWC ratio', 94, 93 | ||
'DWC / LRU hit rate ratio', '119%' | ||
'LRU hit rate', 41.96 | ||
'DWC hit rate', 49.54 | ||
'DWC ratio', 91, 90 | ||
'DWC / LRU hit rate ratio', '118%' | ||
``` | ||
https://github.com/falsandtru/spica/runs/4998610954 | ||
https://github.com/falsandtru/spica/runs/5132749713 | ||
@@ -65,24 +65,24 @@ ### Benchmark | ||
``` | ||
'LRUCache simulation 100 x 4,248,360 ops/sec ±0.96% (64 runs sampled)' | ||
'LRUCache simulation 100 x 4,408,911 ops/sec ±0.50% (67 runs sampled)' | ||
'DW-Cache simulation 100 x 3,814,501 ops/sec ±0.71% (63 runs sampled)' | ||
'DW-Cache simulation 100 x 4,068,709 ops/sec ±0.35% (65 runs sampled)' | ||
'LRUCache simulation 1,000 x 3,160,547 ops/sec ±6.42% (51 runs sampled)' | ||
'LRUCache simulation 1,000 x 4,011,794 ops/sec ±0.35% (66 runs sampled)' | ||
'DW-Cache simulation 1,000 x 3,945,506 ops/sec ±1.11% (61 runs sampled)' | ||
'DW-Cache simulation 1,000 x 4,099,809 ops/sec ±0.35% (68 runs sampled)' | ||
'LRUCache simulation 10,000 x 2,485,636 ops/sec ±2.86% (57 runs sampled)' | ||
'LRUCache simulation 10,000 x 2,619,249 ops/sec ±2.96% (62 runs sampled)' | ||
'DW-Cache simulation 10,000 x 2,585,085 ops/sec ±3.09% (61 runs sampled)' | ||
'DW-Cache simulation 10,000 x 2,834,672 ops/sec ±3.40% (61 runs sampled)' | ||
'LRUCache simulation 100,000 x 1,334,175 ops/sec ±3.50% (56 runs sampled)' | ||
'LRUCache simulation 100,000 x 1,392,207 ops/sec ±3.19% (58 runs sampled)' | ||
'DW-Cache simulation 100,000 x 1,317,095 ops/sec ±6.04% (54 runs sampled)' | ||
'DW-Cache simulation 100,000 x 1,366,786 ops/sec ±6.48% (54 runs sampled)' | ||
'LRUCache simulation 1,000,000 x 837,846 ops/sec ±6.75% (55 runs sampled)' | ||
'LRUCache simulation 1,000,000 x 830,577 ops/sec ±7.29% (55 runs sampled)' | ||
'DW-Cache simulation 1,000,000 x 726,036 ops/sec ±8.35% (56 runs sampled)' | ||
'DW-Cache simulation 1,000,000 x 788,118 ops/sec ±6.14% (58 runs sampled)' | ||
``` | ||
https://github.com/falsandtru/spica/runs/4998624993 | ||
https://github.com/falsandtru/spica/runs/5132776032 | ||
@@ -96,3 +96,5 @@ ## API | ||
put(key: K, value: V, size?: number, age?: number): boolean; | ||
put(this: Cache<K, undefined>, key: K, value?: V, size?: number, age?: number): boolean; | ||
set(key: K, value: V, size?: number, age?: number): this; | ||
set(this: Cache<K, undefined>, key: K, value?: V, size?: number, age?: number): this; | ||
get(key: K): V | undefined; | ||
@@ -99,0 +101,0 @@ has(key: K): boolean; |
Sorry, the diff of this file is too big to display
489132
11939
119