Comparing version 0.0.26 to 0.0.27
@@ -1,2 +0,2 @@ | ||
/*! dw-cache v0.0.26 https://github.com/falsandtru/dw-cache | (c) 2021, falsandtru | (Apache-2.0 AND MPL-2.0) License */ | ||
/*! dw-cache v0.0.27 https://github.com/falsandtru/dw-cache | (c) 2021, falsandtru | (Apache-2.0 AND MPL-2.0) License */ | ||
require = function () { | ||
@@ -367,3 +367,3 @@ function r(e, n, t) { | ||
LFU: new invlist_1.List(), | ||
OVF: new invlist_1.List() | ||
OVL: new invlist_1.List() | ||
}; | ||
@@ -405,3 +405,3 @@ this.stats = { | ||
} | ||
dispose(node, record, callback) { | ||
evict(node, record, callback) { | ||
var _a, _b, _c; | ||
@@ -412,3 +412,3 @@ const index = node.value; | ||
node.delete(); | ||
(_a = node.value.overflow) === null || _a === void 0 ? void 0 : _a.delete(); | ||
(_a = node.value.overlap) === null || _a === void 0 ? void 0 : _a.delete(); | ||
this.memory.delete(index.key); | ||
@@ -427,5 +427,5 @@ this.SIZE -= index.size; | ||
return; | ||
const {LRU, LFU, OVF} = this.indexes; | ||
const {LRU, LFU, OVL} = this.indexes; | ||
while (this.length === this.capacity || this.size + margin - size > this.space) { | ||
const lastNode = (_b = OVF.last) !== null && _b !== void 0 ? _b : LFU.last; | ||
const lastNode = (_b = OVL.last) !== null && _b !== void 0 ? _b : LFU.last; | ||
const lastIndex = lastNode === null || lastNode === void 0 ? void 0 : lastNode.value; | ||
@@ -436,3 +436,3 @@ let target; | ||
case lastIndex && lastIndex.expiry !== global_1.Infinity && lastIndex.expiry < (0, clock_1.now)(): | ||
target = lastNode.list === OVF ? lastNode.value.parent : lastNode; | ||
target = lastNode.list === OVL ? lastNode.value.node : lastNode; | ||
break; | ||
@@ -443,9 +443,14 @@ case LRU.length === 0: | ||
case LFU.length > this.capacity * this.ratio / 100: | ||
LRU.unshiftNode(LFU.last); | ||
LRU.head.value.parent = LRU.head; | ||
LRU.head.value.overflow = OVF.unshift(LRU.head.value); | ||
target = LFU.last !== skip ? LFU.last : LFU.length >= 2 ? LFU.last.prev : skip; | ||
if (target !== skip) { | ||
if (this.ratio > 50) | ||
break; | ||
LRU.unshiftNode(target); | ||
LRU.head.value.node = LRU.head; | ||
LRU.head.value.overlap = OVL.unshift(LRU.head.value); | ||
} | ||
default: | ||
target = LRU.last !== skip ? LRU.last : LRU.last.prev !== skip ? LRU.last.prev : LFU.last; | ||
target = LRU.last !== skip ? LRU.last : LRU.length >= 2 ? LRU.last.prev : LFU.last; | ||
} | ||
this.dispose(target, void 0, true); | ||
this.evict(target, void 0, true); | ||
skip = (skip === null || skip === void 0 ? void 0 : skip.list) && skip; | ||
@@ -472,3 +477,3 @@ size = (_c = skip === null || skip === void 0 ? void 0 : skip.value.size) !== null && _c !== void 0 ? _c : 0; | ||
this.ensure(size, node); | ||
index.clock = ++this.clockR; | ||
index.clock = index.region === 'LRU' ? ++this.clockR : ++this.clock; | ||
index.expiry = expiry; | ||
@@ -490,3 +495,3 @@ this.SIZE += size - index.size; | ||
expiry, | ||
stat: this.stats.LRU | ||
region: 'LRU' | ||
}), | ||
@@ -508,3 +513,3 @@ value | ||
if (expiry !== global_1.Infinity && expiry < (0, clock_1.now)()) { | ||
this.dispose(node, record, true); | ||
this.evict(node, record, true); | ||
return; | ||
@@ -524,3 +529,3 @@ } | ||
if (expiry !== global_1.Infinity && expiry < (0, clock_1.now)()) { | ||
this.dispose(record.index, record, true); | ||
this.evict(record.index, record, true); | ||
return false; | ||
@@ -534,3 +539,3 @@ } | ||
return false; | ||
this.dispose(record.index, record, this.settings.capture.delete === true); | ||
this.evict(record.index, record, this.settings.capture.delete === true); | ||
return true; | ||
@@ -544,3 +549,3 @@ } | ||
this.indexes.LFU.clear(); | ||
this.indexes.OVF.clear(); | ||
this.indexes.OVL.clear(); | ||
if (!this.settings.disposer || !this.settings.capture.clear) | ||
@@ -572,3 +577,3 @@ return void this.memory.clear(); | ||
const lenF = indexes.LFU.length; | ||
const lenV = indexes.OVF.length; | ||
const lenV = indexes.OVL.length; | ||
const r = (lenF + lenV) * 1000 / (lenR + lenF) | 0; | ||
@@ -595,4 +600,4 @@ const rateR0 = rate(window, LRU[0], LRU[0] + LFU[0], LRU[1], LRU[1] + LFU[1], 0) * (1 + r); | ||
const {LRU, LFU} = this.indexes; | ||
++index.stat[0]; | ||
if (!index.overflow && index.clock >= this.clockR - LRU.length / 3 && this.capacity > 3) { | ||
++this.stats[index.region][0]; | ||
if (!index.overlap && index.clock >= this.clockR - LRU.length / 3 && this.capacity > 3) { | ||
index.clock = ++this.clockR; | ||
@@ -603,4 +608,4 @@ node.moveToHead(); | ||
index.clock = ++this.clock; | ||
index.stat = this.stats.LFU; | ||
(_a = index.overflow) === null || _a === void 0 ? void 0 : _a.delete(); | ||
index.region = 'LFU'; | ||
(_a = index.overlap) === null || _a === void 0 ? void 0 : _a.delete(); | ||
LFU.unshiftNode(node); | ||
@@ -614,3 +619,3 @@ return true; | ||
return false; | ||
++index.stat[0]; | ||
++this.stats[index.region][0]; | ||
index.clock = ++this.clock; | ||
@@ -722,8 +727,12 @@ node.moveToHead(); | ||
k2 = k; | ||
Object.defineProperty(o, k2, { | ||
enumerable: true, | ||
get: function () { | ||
return m[k]; | ||
} | ||
}); | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ('get' in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { | ||
enumerable: true, | ||
get: function () { | ||
return m[k]; | ||
} | ||
}; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
} : function (o, m, k, k2) { | ||
@@ -986,8 +995,12 @@ if (k2 === undefined) | ||
k2 = k; | ||
Object.defineProperty(o, k2, { | ||
enumerable: true, | ||
get: function () { | ||
return m[k]; | ||
} | ||
}); | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ('get' in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { | ||
enumerable: true, | ||
get: function () { | ||
return m[k]; | ||
} | ||
}; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
} : function (o, m, k, k2) { | ||
@@ -994,0 +1007,0 @@ if (k2 === undefined) |
{ | ||
"name": "dw-cache", | ||
"version": "0.0.26", | ||
"version": "0.0.27", | ||
"description": "Dual window cache adaptively coordinates the ratio of LRU to LFU using the two sliding windows.", | ||
@@ -31,3 +31,3 @@ "private": false, | ||
"devDependencies": { | ||
"@types/lru-cache": "5.1.1", | ||
"@types/lru-cache": "7.6.1", | ||
"@types/mocha": "9.1.0", | ||
@@ -45,4 +45,4 @@ "@types/power-assert": "1.5.8", | ||
"gulp-unassert": "^2.0.0", | ||
"karma": "^6.3.15", | ||
"karma-chrome-launcher": "^3.1.0", | ||
"karma": "^6.3.17", | ||
"karma-chrome-launcher": "^3.1.1", | ||
"karma-coverage-istanbul-instrumenter": "^1.0.4", | ||
@@ -53,8 +53,8 @@ "karma-coverage-istanbul-reporter": "^3.0.3", | ||
"karma-mocha": "^2.0.1", | ||
"mocha": "^9.2.0", | ||
"npm-check-updates": "^12.3.0", | ||
"mocha": "^9.2.2", | ||
"npm-check-updates": "^12.5.8", | ||
"power-assert": "^1.6.1", | ||
"spica": "0.0.507", | ||
"spica": "0.0.516", | ||
"tsify": "^5.0.4", | ||
"typescript": "4.5.5", | ||
"typescript": "4.6.3", | ||
"vinyl-buffer": "^1.0.1", | ||
@@ -61,0 +61,0 @@ "vinyl-source-stream": "^2.0.0" |
@@ -21,22 +21,22 @@ # Dual Window Cache | ||
'Cache even 100' | ||
'LRU hit rate', 10.19 | ||
'DWC hit rate', 10.18 | ||
'DWC ratio', 16, 16 | ||
'LRU hit rate', 10.03 | ||
'DWC hit rate', 10.01 | ||
'DWC ratio', 8, 8 | ||
'DWC / LRU hit rate ratio', '99%' | ||
'Cache uneven 100' | ||
'LRU hit rate', 19.13 | ||
'DWC hit rate', 37.85 | ||
'LRU hit rate', 18.74 | ||
'DWC hit rate', 36.53 | ||
'DWC ratio', 95, 95 | ||
'DWC / LRU hit rate ratio', '197%' | ||
'DWC / LRU hit rate ratio', '194%' | ||
'Cache uneven 100 transitive distribution' | ||
'LRU hit rate', 18.5 | ||
'DWC hit rate', 37.4 | ||
'LRU hit rate', 18.39 | ||
'DWC hit rate', 38.27 | ||
'DWC ratio', 95, 94 | ||
'DWC / LRU hit rate ratio', '202%' | ||
'DWC / LRU hit rate ratio', '208%' | ||
'Cache uneven 100 transitive bias' | ||
'LRU hit rate', 11.12 | ||
'DWC hit rate', 11.12 | ||
'LRU hit rate', 10.7 | ||
'DWC hit rate', 10.71 | ||
'DWC ratio', 0, 0 | ||
@@ -46,19 +46,19 @@ 'DWC / LRU hit rate ratio', '100%' | ||
'Cache uneven 100 sequential' | ||
'LRU hit rate', 14.26 | ||
'DWC hit rate', 38.19 | ||
'LRU hit rate', 13.65 | ||
'DWC hit rate', 37.51 | ||
'DWC ratio', 95, 95 | ||
'DWC / LRU hit rate ratio', '267%' | ||
'DWC / LRU hit rate ratio', '274%' | ||
'Cache uneven 100 adversarial' | ||
'LRU hit rate', 41.96 | ||
'DWC hit rate', 49.54 | ||
'DWC ratio', 91, 90 | ||
'LRU hit rate', 41.81 | ||
'DWC hit rate', 49.61 | ||
'DWC ratio', 93, 92 | ||
'DWC / LRU hit rate ratio', '118%' | ||
``` | ||
https://github.com/falsandtru/spica/runs/5132749713 | ||
https://github.com/falsandtru/spica/runs/5989250278 | ||
### Benchmark | ||
±10% speed of [lru-cache](https://www.npmjs.com/package/lru-cache). | ||
±10% speed of [lru-cache](https://www.npmjs.com/package/lru-cache)@6(basic implementation using a linked list). | ||
@@ -89,2 +89,28 @@ ``` | ||
Slower x2.0 of [lru-cache](https://www.npmjs.com/package/lru-cache)@7(optimized implementation using an indexed list). | ||
``` | ||
'LRUCache simulation 100 x 5,666,841 ops/sec ±1.28% (64 runs sampled)' | ||
'DW-Cache simulation 100 x 4,626,708 ops/sec ±0.41% (68 runs sampled)' | ||
'LRUCache simulation 1,000 x 5,839,056 ops/sec ±0.76% (68 runs sampled)' | ||
'DW-Cache simulation 1,000 x 3,705,258 ops/sec ±4.05% (60 runs sampled)' | ||
'LRUCache simulation 10,000 x 5,319,518 ops/sec ±1.70% (64 runs sampled)' | ||
'DW-Cache simulation 10,000 x 2,795,605 ops/sec ±3.43% (60 runs sampled)' | ||
'LRUCache simulation 100,000 x 3,085,476 ops/sec ±1.79% (56 runs sampled)' | ||
'DW-Cache simulation 100,000 x 1,300,118 ops/sec ±6.17% (55 runs sampled)' | ||
'LRUCache simulation 1,000,000 x 1,248,436 ops/sec ±3.81% (55 runs sampled)' | ||
'DW-Cache simulation 1,000,000 x 717,300 ops/sec ±11.12% (55 runs sampled)' | ||
``` | ||
https://github.com/falsandtru/spica/runs/5989284811 | ||
## API | ||
@@ -91,0 +117,0 @@ |
Sorry, the diff of this file is too big to display
493767
12021
145