Comparing version 0.0.1 to 0.0.2
@@ -1,2 +0,2 @@ | ||
/*! dw-cache v0.0.1 https://github.com/falsandtru/dw-cache | (c) 2021, falsandtru | (Apache-2.0 AND MPL-2.0) License */ | ||
/*! dw-cache v0.0.2 https://github.com/falsandtru/dw-cache | (c) 2021, falsandtru | (Apache-2.0 AND MPL-2.0) License */ | ||
require = function () { | ||
@@ -200,3 +200,3 @@ function r(e, n, t) { | ||
}, | ||
{ './global': 8 } | ||
{ './global': 10 } | ||
], | ||
@@ -333,4 +333,4 @@ 5: [ | ||
'./array': 4, | ||
'./global': 8, | ||
'./type': 12 | ||
'./global': 10, | ||
'./type': 16 | ||
} | ||
@@ -346,3 +346,4 @@ ], | ||
const alias_1 = _dereq_('./alias'); | ||
const ilist_1 = _dereq_('./ilist'); | ||
const clock_1 = _dereq_('./clock'); | ||
const ixlist_1 = _dereq_('./ixlist'); | ||
const assign_1 = _dereq_('./assign'); | ||
@@ -369,4 +370,4 @@ const tuple_1 = _dereq_('./tuple'); | ||
this.indexes = { | ||
LRU: new ilist_1.IList(this.capacity, true), | ||
LFU: new ilist_1.IList(this.capacity, true) | ||
LRU: new ixlist_1.IxList(this.capacity), | ||
LFU: new ixlist_1.IxList(this.capacity) | ||
}; | ||
@@ -389,2 +390,8 @@ this.stats = { | ||
} | ||
dispose(key, {target, index, value, size}, disposer) { | ||
this.indexes[target].delete(key, index); | ||
this.memory.delete(key); | ||
this.space && (this[SIZE] -= size); | ||
disposer === null || disposer === void 0 ? void 0 : disposer(key, value); | ||
} | ||
secure(margin, target) { | ||
@@ -394,16 +401,15 @@ if (margin <= 0) | ||
const {LRU, LFU} = this.indexes; | ||
let updatable = arguments.length === 1 ? false : void 0; | ||
let updatable = target ? void 0 : false; | ||
while (this.length === this.capacity || this.space && this.size + margin > this.space) { | ||
const {key} = false || LRU.length === 0 || LFU.length > this.capacity * this.ratio / 100 || LFU.length > this.capacity / 2 && LFU.peek(-1).value < this.clock - this.capacity * 8 ? LFU.peek(-1) : LRU.peek(-1); | ||
updatable !== null && updatable !== void 0 ? updatable : updatable = !(0, compare_1.equal)(key, target) && updatable; | ||
this.dispose(key, this.memory.get(key), this.settings.disposer); | ||
const {key} = false || LRU.length === 0 || LFU.length > this.capacity * this.ratio / 100 || LFU.length > this.capacity / 2 && LFU.last.value < this.clock - this.capacity * 8 ? LFU.last : LRU.last; | ||
if (updatable !== null && updatable !== void 0 ? updatable : (0, compare_1.equal)(key, target.key)) { | ||
updatable = false; | ||
margin += target.record.size; | ||
this.dispose(key, target.record, this.settings.disposer); | ||
} else { | ||
this.dispose(key, this.memory.get(key), this.settings.disposer); | ||
} | ||
} | ||
return updatable !== null && updatable !== void 0 ? updatable : true; | ||
} | ||
dispose(key, {target, index, size, value}, disposer) { | ||
this.indexes[target].delete(key, index); | ||
this.memory.delete(key); | ||
this.space && (this[SIZE] -= size); | ||
disposer === null || disposer === void 0 ? void 0 : disposer(key, value); | ||
} | ||
put(key, value, size = 1, age = this.settings.age) { | ||
@@ -419,5 +425,8 @@ var _b, _c; | ||
} | ||
const expiry = age === global_1.Infinity ? global_1.Infinity : global_1.Date.now() + age; | ||
const expiry = age === global_1.Infinity ? global_1.Infinity : (0, clock_1.now)() + age; | ||
const record = this.memory.get(key); | ||
if (record && this.secure(size - record.size, key)) { | ||
if (record && this.secure(size - record.size, { | ||
key, | ||
record | ||
})) { | ||
this.space && (this[SIZE] += size - record.size); | ||
@@ -428,4 +437,5 @@ record.value = value; | ||
return true; | ||
} else if (!record) { | ||
this.secure(size); | ||
} | ||
this.secure(size); | ||
const {LRU} = this.indexes; | ||
@@ -450,3 +460,3 @@ this.space && (this[SIZE] += size); | ||
return; | ||
if (record.expiry !== global_1.Infinity && record.expiry <= global_1.Date.now()) { | ||
if (record.expiry !== global_1.Infinity && record.expiry <= (0, clock_1.now)()) { | ||
this.dispose(key, record, this.settings.disposer); | ||
@@ -463,3 +473,3 @@ return; | ||
return false; | ||
if (record.expiry !== global_1.Infinity && record.expiry <= global_1.Date.now()) { | ||
if (record.expiry !== global_1.Infinity && record.expiry <= (0, clock_1.now)()) { | ||
this.dispose(key, record, this.settings.disposer); | ||
@@ -492,8 +502,8 @@ return false; | ||
}; | ||
if (!this.settings.disposer || !this.settings.capture.clear) | ||
return void this.memory.clear(); | ||
const memory = this.memory; | ||
this.memory = new global_1.Map(); | ||
if (this.settings.disposer && this.settings.capture.clear) { | ||
for (const [key, {value}] of memory) { | ||
this.settings.disposer(key, value); | ||
} | ||
for (const [key, {value}] of memory) { | ||
this.settings.disposer(key, value); | ||
} | ||
@@ -586,6 +596,7 @@ } | ||
'./assign': 5, | ||
'./compare': 7, | ||
'./global': 8, | ||
'./ilist': 9, | ||
'./tuple': 11 | ||
'./clock': 7, | ||
'./compare': 8, | ||
'./global': 10, | ||
'./ixlist': 11, | ||
'./tuple': 15 | ||
} | ||
@@ -597,2 +608,58 @@ ], | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
exports.tick = exports.wait = exports.clock = exports.now = void 0; | ||
const global_1 = _dereq_('./global'); | ||
const alias_1 = _dereq_('./alias'); | ||
const promise_1 = _dereq_('./promise'); | ||
const exception_1 = _dereq_('./exception'); | ||
let now_; | ||
function now() { | ||
if (now_ !== void 0) | ||
return now_; | ||
tick(() => now_ = void 0); | ||
return now_ = global_1.Date.now(); | ||
} | ||
exports.now = now; | ||
exports.clock = Promise.resolve(undefined); | ||
function wait(ms) { | ||
return ms === 0 ? promise_1.AtomicPromise.resolve(exports.clock) : new promise_1.AtomicPromise(resolve => void (0, global_1.setTimeout)(resolve, ms)); | ||
} | ||
exports.wait = wait; | ||
let queue = []; | ||
let jobs = []; | ||
let index = 0; | ||
const scheduler = Promise.resolve(); | ||
function tick(cb) { | ||
index === 0 && scheduler.then(run); | ||
index++ === queue.length ? queue.push(cb) : queue[index - 1] = cb; | ||
} | ||
exports.tick = tick; | ||
function run() { | ||
const count = index; | ||
[index, queue, jobs] = [ | ||
0, | ||
jobs, | ||
queue | ||
]; | ||
for (let i = 0; i < count; ++i) { | ||
try { | ||
jobs[i](); | ||
jobs[i] = void 0; | ||
} catch (reason) { | ||
(0, exception_1.causeAsyncException)(reason); | ||
} | ||
} | ||
jobs.length > 1000 && count < jobs.length * 0.5 && jobs.splice((0, alias_1.floor)(jobs.length * 0.9), jobs.length); | ||
} | ||
}, | ||
{ | ||
'./alias': 3, | ||
'./exception': 9, | ||
'./global': 10, | ||
'./promise': 14 | ||
} | ||
], | ||
8: [ | ||
function (_dereq_, module, exports) { | ||
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
exports.equal = void 0; | ||
@@ -606,5 +673,17 @@ function equal(a, b) { | ||
], | ||
8: [ | ||
9: [ | ||
function (_dereq_, module, exports) { | ||
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
exports.causeAsyncException = void 0; | ||
function causeAsyncException(reason) { | ||
void Promise.reject(reason); | ||
} | ||
exports.causeAsyncException = causeAsyncException; | ||
}, | ||
{} | ||
], | ||
10: [ | ||
function (_dereq_, module, exports) { | ||
'use strict'; | ||
const global = void 0 || typeof globalThis !== 'undefined' && globalThis || typeof self !== 'undefined' && self || Function('return this')(); | ||
@@ -616,3 +695,3 @@ eval('global.global = global'); | ||
], | ||
9: [ | ||
11: [ | ||
function (_dereq_, module, exports) { | ||
@@ -640,23 +719,25 @@ 'use strict'; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
__exportStar(_dereq_('./list/ilist'), exports); | ||
__exportStar(_dereq_('./list/ixlist'), exports); | ||
}, | ||
{ './list/ilist': 10 } | ||
{ './list/ixlist': 12 } | ||
], | ||
10: [ | ||
12: [ | ||
function (_dereq_, module, exports) { | ||
'use strict'; | ||
var _a; | ||
var _a, _b, _c; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
exports.IList = void 0; | ||
exports.IxList = void 0; | ||
const compare_1 = _dereq_('../compare'); | ||
const HEAD = Symbol('head'); | ||
const CURSOR = Symbol('cursor'); | ||
const LENGTH = Symbol('length'); | ||
class IList { | ||
constructor(capacity, strict = false) { | ||
class IxList { | ||
constructor(capacity, index) { | ||
this.capacity = capacity; | ||
this.strict = strict; | ||
this.index = index; | ||
this.nodes = []; | ||
this.empties = []; | ||
this.head = 0; | ||
this.cursor = 0; | ||
this.buffers = []; | ||
this[_a] = 0; | ||
this[_b] = 0; | ||
this[_c] = 0; | ||
} | ||
@@ -666,15 +747,54 @@ get length() { | ||
} | ||
get head() { | ||
const node = this.nodes[this[HEAD]]; | ||
return node && { | ||
index: node.index, | ||
key: node.key, | ||
value: node.value | ||
}; | ||
} | ||
get last() { | ||
var _d; | ||
const node = (_d = this.nodes[this[HEAD]]) === null || _d === void 0 ? void 0 : _d.prev; | ||
return node && { | ||
index: node.index, | ||
key: node.key, | ||
value: node.value | ||
}; | ||
} | ||
node(index) { | ||
const node = this.nodes[index]; | ||
if (!node) | ||
throw new Error(`Spica: IxList: Invalid index.`); | ||
return { | ||
index: node.index, | ||
key: node.key, | ||
value: node.value | ||
}; | ||
} | ||
next(index) { | ||
var _d, _e; | ||
return this.node((_e = (_d = this.nodes[index]) === null || _d === void 0 ? void 0 : _d.next.index) !== null && _e !== void 0 ? _e : this.capacity); | ||
} | ||
prev(index) { | ||
var _d, _e; | ||
return this.node((_e = (_d = this.nodes[index]) === null || _d === void 0 ? void 0 : _d.prev.index) !== null && _e !== void 0 ? _e : this.capacity); | ||
} | ||
clear() { | ||
var _d; | ||
this.nodes = []; | ||
this.empties = []; | ||
this.head = 0; | ||
this.cursor = 0; | ||
this.buffers = []; | ||
(_d = this.index) === null || _d === void 0 ? void 0 : _d.clear(); | ||
this[HEAD] = 0; | ||
this[CURSOR] = 0; | ||
this[LENGTH] = 0; | ||
} | ||
add(key, value) { | ||
var _d, _e; | ||
const nodes = this.nodes; | ||
const head = nodes[this.head]; | ||
const head = nodes[this[HEAD]]; | ||
if (!head) { | ||
const index = this.head = this.cursor = this.empties.length > 0 ? this.empties.shift() : this.length; | ||
const index = this[HEAD] = this[CURSOR] = this.buffers.length > 0 ? this.buffers.shift() : this.length; | ||
++this[LENGTH]; | ||
(_d = this.index) === null || _d === void 0 ? void 0 : _d.set(key, index); | ||
nodes[index] = new Node(index, key, value, head, head); | ||
@@ -684,11 +804,16 @@ return index; | ||
if (this.length < this.capacity) { | ||
const index = this.head = this.cursor = this.empties.length > 0 ? this.empties.shift() : this.length; | ||
const index = this[HEAD] = this[CURSOR] = this.buffers.length > 0 ? this.buffers.shift() : this.length; | ||
++this[LENGTH]; | ||
(_e = this.index) === null || _e === void 0 ? void 0 : _e.set(key, index); | ||
nodes[index] = head.prev = head.prev.next = new Node(index, key, value, head, head.prev); | ||
return index; | ||
} else { | ||
const garbage = head.prev; | ||
const index = this.head = this.cursor = garbage.index; | ||
nodes[index] = head.prev = head.prev.prev.next = new Node(index, key, value, head, head.prev.prev); | ||
garbage.key = garbage.value = garbage.prev = garbage.next = void 0; | ||
const node = head.prev; | ||
const index = this[HEAD] = this[CURSOR] = node.index; | ||
if (this.index && !(0, compare_1.equal)(key, node.key)) { | ||
this.index.delete(node.key, node.index); | ||
this.index.set(key, index); | ||
} | ||
node.key = key; | ||
node.value = value; | ||
return index; | ||
@@ -698,3 +823,3 @@ } | ||
put(key, value, index) { | ||
const node = this.seek(key, index); | ||
const node = this.search(key, index); | ||
if (!node) | ||
@@ -705,27 +830,20 @@ return this.add(key, value); | ||
} | ||
shift() { | ||
const node = this.nodes[this.head]; | ||
return node && this.delete(node.key, node.index); | ||
} | ||
pop() { | ||
var _b; | ||
const node = (_b = this.nodes[this.head]) === null || _b === void 0 ? void 0 : _b.prev; | ||
return node && this.delete(node.key, node.index); | ||
} | ||
delete(key, index) { | ||
const cursor = this.cursor; | ||
const node = this.seek(key, index); | ||
var _d; | ||
const cursor = this[CURSOR]; | ||
const node = this.search(key, index); | ||
if (!node) | ||
return; | ||
this.cursor = cursor; | ||
this[CURSOR] = cursor; | ||
--this[LENGTH]; | ||
this.empties.push(node.index); | ||
this.buffers.push(node.index); | ||
(_d = this.index) === null || _d === void 0 ? void 0 : _d.delete(node.key, node.index); | ||
const {prev, next, value} = node; | ||
prev.next = next; | ||
next.prev = prev; | ||
if (this.head === node.index) { | ||
this.head = next.index; | ||
if (this[HEAD] === node.index) { | ||
this[HEAD] = next.index; | ||
} | ||
if (this.cursor === node.index) { | ||
this.cursor = next.index; | ||
if (this[CURSOR] === node.index) { | ||
this[CURSOR] = next.index; | ||
} | ||
@@ -738,52 +856,54 @@ this.nodes[node.index] = node.key = node.value = node.prev = node.next = void 0; | ||
} | ||
peek(at) { | ||
var _b; | ||
const node = at ? (_b = this.nodes[this.head]) === null || _b === void 0 ? void 0 : _b.prev : this.nodes[this.head]; | ||
return node && { | ||
index: node.index, | ||
key: node.key, | ||
value: node.value | ||
}; | ||
unshift(key, value) { | ||
return this.add(key, value); | ||
} | ||
node(index) { | ||
const node = this.nodes[index]; | ||
if (!node) | ||
throw new Error(`Spica: IList: Invalid index.`); | ||
return { | ||
index: node.index, | ||
key: node.key, | ||
value: node.value | ||
}; | ||
shift() { | ||
const node = this.nodes[this[HEAD]]; | ||
return node && this.delete(node.key, node.index); | ||
} | ||
next(index) { | ||
var _b, _c; | ||
return this.node((_c = (_b = this.nodes[index]) === null || _b === void 0 ? void 0 : _b.next.index) !== null && _c !== void 0 ? _c : this.capacity); | ||
push(key, value) { | ||
const h = this[HEAD]; | ||
const i = this.add(key, value); | ||
this[HEAD] = h; | ||
return i; | ||
} | ||
prev(index) { | ||
var _b, _c; | ||
return this.node((_c = (_b = this.nodes[index]) === null || _b === void 0 ? void 0 : _b.prev.index) !== null && _c !== void 0 ? _c : this.capacity); | ||
pop() { | ||
var _d; | ||
const node = (_d = this.nodes[this[HEAD]]) === null || _d === void 0 ? void 0 : _d.prev; | ||
return node && this.delete(node.key, node.index); | ||
} | ||
search(key, cursor = this[CURSOR]) { | ||
var _d; | ||
let node; | ||
node = this.nodes[cursor]; | ||
if (node && (0, compare_1.equal)(node.key, key)) | ||
return this[CURSOR] = cursor, node; | ||
if (!this.index) | ||
throw new Error(`Spica: IxList: Invalid index.`); | ||
node = this.nodes[cursor = (_d = this.index.get(key)) !== null && _d !== void 0 ? _d : this.capacity]; | ||
if (node && (0, compare_1.equal)(node.key, key)) | ||
return this[CURSOR] = cursor, node; | ||
} | ||
find(key, index) { | ||
var _b; | ||
if (this.strict) | ||
throw new Error(`Spica: IList: Invalid cursor.`); | ||
return (_b = this.seek(key, index)) === null || _b === void 0 ? void 0 : _b.value; | ||
var _d; | ||
if (!this.index) | ||
throw new Error(`Spica: IxList: No index.`); | ||
return (_d = this.search(key, index)) === null || _d === void 0 ? void 0 : _d.value; | ||
} | ||
findIndex(key, index) { | ||
var _b; | ||
if (this.strict) | ||
throw new Error(`Spica: IList: Invalid cursor.`); | ||
return (_b = this.seek(key, index)) === null || _b === void 0 ? void 0 : _b.index; | ||
var _d; | ||
if (!this.index) | ||
throw new Error(`Spica: IxList: No index.`); | ||
return (_d = this.search(key, index)) === null || _d === void 0 ? void 0 : _d.index; | ||
} | ||
has(key, index) { | ||
if (this.strict) | ||
throw new Error(`Spica: IList: Invalid cursor.`); | ||
return !!this.seek(key, index); | ||
if (!this.index) | ||
throw new Error(`Spica: IxList: No index.`); | ||
return this.search(key, index) !== void 0; | ||
} | ||
*[(_a = LENGTH, Symbol.iterator)]() { | ||
for (let node = this.nodes[this.head], i = 0; node && i < this.length; (node = node.next) && ++i) { | ||
*[(_a = HEAD, _b = CURSOR, _c = LENGTH, Symbol.iterator)]() { | ||
for (let node = this.nodes[this[HEAD]], i = 0; node && i < this.length; (node = node.next) && ++i) { | ||
yield [ | ||
node.key, | ||
node.value, | ||
node.index | ||
node.value | ||
]; | ||
@@ -793,36 +913,22 @@ } | ||
} | ||
seek(key, cursor = this.cursor) { | ||
let node; | ||
node = this.nodes[cursor]; | ||
if (!node) | ||
return; | ||
if ((0, compare_1.equal)(node.key, key)) | ||
return this.cursor = cursor, node; | ||
if (this.strict) | ||
throw new Error(`Spica: IList: Invalid cursor.`); | ||
for (let i = 1; i < this.length && (node = node.next); ++i) { | ||
if ((0, compare_1.equal)(node.key, key)) | ||
return this.cursor = node.index, node; | ||
} | ||
} | ||
insert(index, before) { | ||
if (index === before) | ||
return false; | ||
const a1 = this.nodes[before]; | ||
const a1 = this.nodes[index]; | ||
if (!a1) | ||
return false; | ||
const b1 = this.nodes[index]; | ||
const b1 = this.nodes[before]; | ||
if (!b1) | ||
return false; | ||
if (b1.next === a1) | ||
if (a1.next === b1) | ||
return false; | ||
const b0 = b1.prev; | ||
const a0 = a1.prev; | ||
const b0 = b1.prev; | ||
const b2 = b1.next; | ||
a0.next = b1; | ||
b1.next = a1; | ||
a1.prev = b1; | ||
b1.prev = a0; | ||
b0.next = b2; | ||
b2.prev = b0; | ||
const a2 = a1.next; | ||
b0.next = a1; | ||
a1.next = b1; | ||
b1.prev = a1; | ||
a1.prev = b0; | ||
a0.next = a2; | ||
a2.prev = a0; | ||
return true; | ||
@@ -833,3 +939,3 @@ } | ||
return false; | ||
if (index === this.head) | ||
if (index === this[HEAD]) | ||
return false; | ||
@@ -839,4 +945,4 @@ const node = this.nodes[index]; | ||
return false; | ||
this.insert(index, this.head); | ||
this.head = index; | ||
this.insert(index, this[HEAD]); | ||
this[HEAD] = index; | ||
return true; | ||
@@ -847,3 +953,3 @@ } | ||
return false; | ||
if (index === this.head) | ||
if (index === this[HEAD]) | ||
return false; | ||
@@ -854,4 +960,4 @@ const node = this.nodes[index]; | ||
this.insert(node.index, node.prev.index); | ||
if (node.next.index === this.head) { | ||
this.head = node.index; | ||
if (node.next.index === this[HEAD]) { | ||
this[HEAD] = node.index; | ||
} | ||
@@ -876,8 +982,8 @@ return true; | ||
this.insert(node1.index, node3.index); | ||
switch (this.head) { | ||
switch (this[HEAD]) { | ||
case node1.index: | ||
this.head = node2.index; | ||
this[HEAD] = node2.index; | ||
break; | ||
case node2.index: | ||
this.head = node1.index; | ||
this[HEAD] = node1.index; | ||
break; | ||
@@ -888,3 +994,3 @@ } | ||
} | ||
exports.IList = IList; | ||
exports.IxList = IxList; | ||
class Node { | ||
@@ -906,8 +1012,339 @@ constructor(index, key, value, next, prev) { | ||
}, | ||
{ '../compare': 7 } | ||
{ '../compare': 8 } | ||
], | ||
11: [ | ||
13: [ | ||
function (_dereq_, module, exports) { | ||
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
exports.noop = void 0; | ||
function noop() { | ||
} | ||
exports.noop = noop; | ||
}, | ||
{} | ||
], | ||
14: [ | ||
function (_dereq_, module, exports) { | ||
'use strict'; | ||
var _a, _b; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
exports.never = exports.isPromiseLike = exports.Internal = exports.AtomicPromise = void 0; | ||
const global_1 = _dereq_('./global'); | ||
const alias_1 = _dereq_('./alias'); | ||
const noop_1 = _dereq_('./noop'); | ||
const internal = Symbol.for('spica/promise::internal'); | ||
class AtomicPromise { | ||
constructor(executor) { | ||
this[_a] = 'Promise'; | ||
this[_b] = new Internal(); | ||
try { | ||
executor(value => void this[internal].resolve(value), reason => void this[internal].reject(reason)); | ||
} catch (reason) { | ||
this[internal].reject(reason); | ||
} | ||
} | ||
static get [Symbol.species]() { | ||
return AtomicPromise; | ||
} | ||
static all(vs) { | ||
return new AtomicPromise((resolve, reject) => { | ||
const values = (0, alias_1.isArray)(vs) ? vs : [...vs]; | ||
const results = (0, global_1.Array)(values.length); | ||
let count = 0; | ||
for (let i = 0; i < values.length; ++i) { | ||
const value = values[i]; | ||
if (!isPromiseLike(value)) { | ||
results[i] = value; | ||
++count; | ||
continue; | ||
} | ||
if (isAtomicPromiseLike(value)) { | ||
const {status} = value[internal]; | ||
switch (status.state) { | ||
case 2: | ||
results[i] = status.value; | ||
++count; | ||
continue; | ||
case 3: | ||
reject(status.reason); | ||
i = values.length; | ||
continue; | ||
} | ||
} | ||
value.then(value => { | ||
results[i] = value; | ||
++count; | ||
count === values.length && resolve(results); | ||
}, reason => { | ||
reject(reason); | ||
i = values.length; | ||
}); | ||
} | ||
count === values.length && resolve(results); | ||
}); | ||
} | ||
static race(vs) { | ||
return new AtomicPromise((resolve, reject) => { | ||
const values = (0, alias_1.isArray)(vs) ? vs : [...vs]; | ||
for (let i = 0; i < values.length; ++i) { | ||
const value = values[i]; | ||
if (!isPromiseLike(value)) { | ||
return resolve(value); | ||
} | ||
if (isAtomicPromiseLike(value)) { | ||
const {status} = value[internal]; | ||
switch (status.state) { | ||
case 2: | ||
return resolve(status.value); | ||
case 3: | ||
return reject(status.reason); | ||
} | ||
} | ||
} | ||
let done = false; | ||
for (let i = 0; i < values.length; ++i) { | ||
const value = values[i]; | ||
value.then(value => { | ||
resolve(value); | ||
done = true; | ||
}, reason => { | ||
reject(reason); | ||
done = true; | ||
}); | ||
if (done) | ||
return; | ||
} | ||
}); | ||
} | ||
static allSettled(vs) { | ||
return new AtomicPromise(resolve => { | ||
const values = (0, alias_1.isArray)(vs) ? vs : [...vs]; | ||
const results = (0, global_1.Array)(values.length); | ||
let count = 0; | ||
for (let i = 0; i < values.length; ++i) { | ||
const value = values[i]; | ||
if (!isPromiseLike(value)) { | ||
results[i] = { | ||
status: 'fulfilled', | ||
value: value | ||
}; | ||
++count; | ||
continue; | ||
} | ||
if (isAtomicPromiseLike(value)) { | ||
const {status} = value[internal]; | ||
switch (status.state) { | ||
case 2: | ||
results[i] = { | ||
status: 'fulfilled', | ||
value: status.value | ||
}; | ||
++count; | ||
continue; | ||
case 3: | ||
results[i] = { | ||
status: 'rejected', | ||
reason: status.reason | ||
}; | ||
++count; | ||
continue; | ||
} | ||
} | ||
value.then(value => { | ||
results[i] = { | ||
status: 'fulfilled', | ||
value: value | ||
}; | ||
++count; | ||
count === values.length && resolve(results); | ||
}, reason => { | ||
results[i] = { | ||
status: 'rejected', | ||
reason | ||
}; | ||
++count; | ||
count === values.length && resolve(results); | ||
}); | ||
} | ||
count === values.length && resolve(results); | ||
}); | ||
} | ||
static resolve(value) { | ||
return new AtomicPromise(resolve => resolve(value)); | ||
} | ||
static reject(reason) { | ||
return new AtomicPromise((_, reject) => reject(reason)); | ||
} | ||
then(onfulfilled, onrejected) { | ||
return new AtomicPromise((resolve, reject) => this[internal].then(resolve, reject, onfulfilled, onrejected)); | ||
} | ||
catch(onrejected) { | ||
return this.then(void 0, onrejected); | ||
} | ||
finally(onfinally) { | ||
return this.then(onfinally, onfinally).then(() => this); | ||
} | ||
} | ||
exports.AtomicPromise = AtomicPromise; | ||
_a = Symbol.toStringTag, _b = internal; | ||
class Internal { | ||
constructor() { | ||
this.status = { state: 0 }; | ||
this.fulfillReactions = []; | ||
this.rejectReactions = []; | ||
} | ||
get isPending() { | ||
return this.status.state === 0; | ||
} | ||
resolve(value) { | ||
if (this.status.state !== 0) | ||
return; | ||
if (!isPromiseLike(value)) { | ||
this.status = { | ||
state: 2, | ||
value: value | ||
}; | ||
return this.resume(); | ||
} | ||
if (isAtomicPromiseLike(value)) { | ||
const core = value[internal]; | ||
switch (core.status.state) { | ||
case 2: | ||
case 3: | ||
this.status = core.status; | ||
return this.resume(); | ||
default: | ||
return core.then(() => (this.status = core.status, this.resume()), () => (this.status = core.status, this.resume())); | ||
} | ||
} | ||
this.status = { | ||
state: 1, | ||
promise: value | ||
}; | ||
return void value.then(value => { | ||
this.status = { | ||
state: 2, | ||
value | ||
}; | ||
this.resume(); | ||
}, reason => { | ||
this.status = { | ||
state: 3, | ||
reason | ||
}; | ||
this.resume(); | ||
}); | ||
} | ||
reject(reason) { | ||
if (this.status.state !== 0) | ||
return; | ||
this.status = { | ||
state: 3, | ||
reason | ||
}; | ||
return this.resume(); | ||
} | ||
then(resolve, reject, onfulfilled, onrejected) { | ||
const {status, fulfillReactions, rejectReactions} = this; | ||
switch (status.state) { | ||
case 2: | ||
if (fulfillReactions.length !== 0) | ||
break; | ||
return this.call(resolve, reject, resolve, onfulfilled, status.value); | ||
case 3: | ||
if (rejectReactions.length !== 0) | ||
break; | ||
return this.call(resolve, reject, reject, onrejected, status.reason); | ||
} | ||
fulfillReactions.push([ | ||
resolve, | ||
reject, | ||
resolve, | ||
onfulfilled | ||
]); | ||
rejectReactions.push([ | ||
resolve, | ||
reject, | ||
reject, | ||
onrejected | ||
]); | ||
} | ||
resume() { | ||
const {status, fulfillReactions, rejectReactions} = this; | ||
switch (status.state) { | ||
case 0: | ||
case 1: | ||
return; | ||
case 2: | ||
if (rejectReactions.length > 0) { | ||
this.rejectReactions = []; | ||
} | ||
if (fulfillReactions.length === 0) | ||
return; | ||
this.react(fulfillReactions, status.value); | ||
this.fulfillReactions = []; | ||
return; | ||
case 3: | ||
if (fulfillReactions.length > 0) { | ||
this.fulfillReactions = []; | ||
} | ||
if (rejectReactions.length === 0) | ||
return; | ||
this.react(rejectReactions, status.reason); | ||
this.rejectReactions = []; | ||
return; | ||
} | ||
} | ||
react(reactions, param) { | ||
for (let i = 0; i < reactions.length; ++i) { | ||
const reaction = reactions[i]; | ||
this.call(reaction[0], reaction[1], reaction[2], reaction[3], param); | ||
} | ||
} | ||
call(resolve, reject, cont, callback, param) { | ||
if (!callback) | ||
return cont(param); | ||
try { | ||
resolve(callback(param)); | ||
} catch (reason) { | ||
reject(reason); | ||
} | ||
} | ||
} | ||
exports.Internal = Internal; | ||
function isPromiseLike(value) { | ||
return value !== null && typeof value === 'object' && typeof value.then === 'function'; | ||
} | ||
exports.isPromiseLike = isPromiseLike; | ||
function isAtomicPromiseLike(value) { | ||
return internal in value; | ||
} | ||
exports.never = new class Never extends Promise { | ||
static get [Symbol.species]() { | ||
return Never; | ||
} | ||
constructor() { | ||
super(noop_1.noop); | ||
} | ||
then() { | ||
return this; | ||
} | ||
catch() { | ||
return this; | ||
} | ||
finally() { | ||
return this; | ||
} | ||
}(); | ||
}, | ||
{ | ||
'./alias': 3, | ||
'./global': 10, | ||
'./noop': 13 | ||
} | ||
], | ||
15: [ | ||
function (_dereq_, module, exports) { | ||
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
exports.tuple = void 0; | ||
@@ -921,3 +1358,3 @@ function tuple(...as) { | ||
], | ||
12: [ | ||
16: [ | ||
function (_dereq_, module, exports) { | ||
@@ -924,0 +1361,0 @@ 'use strict'; |
@@ -1,2 +0,2 @@ | ||
/*! dw-cache v0.0.1 https://github.com/falsandtru/dw-cache | (c) 2021, falsandtru | (Apache-2.0 AND MPL-2.0) License */ | ||
require=function(){return function e(t,i,r){function s(o,c){if(!i[o]){if(!t[o]){var a="function"==typeof require&&require;if(!c&&a)return a(o,!0);if(n)return n(o,!0);var h=new Error("Cannot find module '"+o+"'");throw h.code="MODULE_NOT_FOUND",h}var u=i[o]={exports:{}};t[o][0].call(u.exports,function(e){return s(t[o][1][e]||e)},u,u.exports,e,t,i,r)}return i[o].exports}for(var n="function"==typeof require&&require,o=0;o<r.length;o++)s(r[o]);return s}}()({1:[function(e,t,i){},{}],2:[function(e,t,i){arguments[4][1][0].apply(i,arguments)},{dup:1}],3:[function(e,t,i){"use strict";Object.defineProperty(i,"__esModule",{value:!0}),i.isArray=i.ObjectValues=i.ObjectSetPrototypeOf=i.ObjectSeal=i.ObjectPreventExtensions=i.ObjectKeys=i.isSealed=i.isFrozen=i.isExtensible=i.ObjectIs=i.ObjectGetPrototypeOf=i.ObjectGetOwnPropertySymbols=i.ObjectGetOwnPropertyNames=i.ObjectGetOwnPropertyDescriptors=i.ObjectGetOwnPropertyDescriptor=i.ObjectFromEntries=i.ObjectFreeze=i.ObjectEntries=i.ObjectDefineProperty=i.ObjectDefineProperties=i.ObjectCreate=i.ObjectAssign=i.toString=i.isEnumerable=i.isPrototypeOf=i.hasOwnProperty=i.SymbolKeyFor=i.SymbolFor=i.sign=i.round=i.random=i.min=i.max=i.floor=i.ceil=i.abs=i.parseInt=i.parseFloat=i.isSafeInteger=i.isNaN=i.isInteger=i.isFinite=i.NaN=void 0,i.NaN=Number.NaN,i.isFinite=Number.isFinite,i.isInteger=Number.isInteger,i.isNaN=Number.isNaN,i.isSafeInteger=Number.isSafeInteger,i.parseFloat=Number.parseFloat,i.parseInt=Number.parseInt,i.abs=Math.abs,i.ceil=Math.ceil,i.floor=Math.floor,i.max=Math.max,i.min=Math.min,i.random=Math.random,i.round=Math.round,i.sign=Math.sign,i.SymbolFor=Symbol.for,i.SymbolKeyFor=Symbol.keyFor,i.hasOwnProperty=Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty),i.isPrototypeOf=Object.prototype.isPrototypeOf.call.bind(Object.prototype.isPrototypeOf),i.isEnumerable=Object.prototype.propertyIsEnumerable.call.bind(Object.prototype.propertyIsEnumerable),i.toString=Object.prototype.toString.call.bind(Object.prototype.toString),i.ObjectAssign=Object.assign,i.ObjectCreate=Object.create,i.ObjectDefineProperties=Object.defineProperties,i.ObjectDefineProperty=Object.defineProperty,i.ObjectEntries=Object.entries,i.ObjectFreeze=Object.freeze,i.ObjectFromEntries=Object.fromEntries,i.ObjectGetOwnPropertyDescriptor=Object.getOwnPropertyDescriptor,i.ObjectGetOwnPropertyDescriptors=Object.getOwnPropertyDescriptors,i.ObjectGetOwnPropertyNames=Object.getOwnPropertyNames,i.ObjectGetOwnPropertySymbols=Object.getOwnPropertySymbols,i.ObjectGetPrototypeOf=Object.getPrototypeOf,i.ObjectIs=Object.is,i.isExtensible=Object.isExtensible,i.isFrozen=Object.isFrozen,i.isSealed=Object.isSealed,i.ObjectKeys=Object.keys,i.ObjectPreventExtensions=Object.preventExtensions,i.ObjectSeal=Object.seal,i.ObjectSetPrototypeOf=Object.setPrototypeOf,i.ObjectValues=Object.values,i.isArray=Array.isArray},{}],4:[function(e,t,i){"use strict";Object.defineProperty(i,"__esModule",{value:!0}),i.join=i.splice=i.pop=i.push=i.shift=i.unshift=i.indexOf=void 0;const r=e("./global");function s(e,t){if("length"in e)for(let i=e.length-1;i>=0;--i)t.unshift(e[i]);else t.unshift(...e);return t}function n(e,t){if("length"in t)for(let i=0,r=t.length;i<r;++i)e.push(t[i]);else for(const i of t)e.push(i);return e}function o(e,t,i,...c){if(0===i&&0===c.length)return[];switch(i=i>e.length?e.length:i,t){case 0:switch(i){case 0:return[[],s(c,e)][0];case 1:return 0===e.length?[[],s(c,e)][0]:[[e.shift()],s(c,e)][0];case void 0:if(e.length>1||arguments.length>2)break;return 0===e.length?[]:o(e,t,1)}break;case-1:case e.length-1:switch(i){case 1:return 0===e.length?[[],n(e,c)][0]:[[e.pop()],n(e,c)][0];case void 0:if(e.length>1||arguments.length>2)break;return 0===e.length?[]:o(e,t,1)}break;case e.length:case r.Infinity:return[[],n(e,c)][0]}return arguments.length>2?e.splice(t,i,...c):e.splice(t)}i.indexOf=function(e,t){return 0===e.length?-1:t==t?e.indexOf(t):e.findIndex(e=>e!=e)},i.unshift=s,i.shift=function(e,t){if(t<0)throw new Error("Unexpected negative number");return void 0===t?[e.shift(),e]:[o(e,0,t),e]},i.push=n,i.pop=function(e,t){if(t<0)throw new Error("Unexpected negative number");return void 0===t?[e,e.pop()]:[e,o(e,e.length-t,t)]},i.splice=o,i.join=function(e,t=""){let i="";for(let r=0;r<e.length;++r)i+=0===r?e[r]:t+e[r];return i}},{"./global":8}],5:[function(e,t,i){"use strict";Object.defineProperty(i,"__esModule",{value:!0}),i.template=i.overwrite=i.inherit=i.merge=i.extend=i.clone=i.assign=void 0;const r=e("./global"),s=e("./alias"),n=e("./type"),o=e("./array");function c(e){return function(t,...i){if((0,n.isPrimitive)(t))return t;for(let r=0;r<i.length;++r){const o=i[r];if(o===t)continue;if((0,n.isPrimitive)(o))continue;const c=(0,s.ObjectKeys)(o);for(let i=0;i<c.length;++i)e(c[i],t,o)}return t}}function a(e){switch((0,n.type)(e)){case"Array":return[];case"Object":return e instanceof r.Object?{}:(0,s.ObjectCreate)(null);default:return e}}i.assign=c((e,t,i)=>t[e]=i[e]),i.clone=c((e,t,r)=>{switch((0,n.type)(r[e])){case"Array":return t[e]=r[e].slice();case"Object":switch((0,n.type)(t[e])){case"Object":return t[e]=(0,i.clone)(a(r[e]),r[e]);default:return t[e]=r[e]}default:return t[e]=r[e]}}),i.extend=c((e,t,r)=>{switch((0,n.type)(r[e])){case"undefined":return;case"Array":return t[e]=r[e];case"Object":switch((0,n.type)(t[e])){case"Object":return t[e]=(0,i.extend)(t[e],r[e]);default:return t[e]=(0,i.extend)(a(r[e]),r[e])}default:return t[e]=r[e]}}),i.merge=c((e,t,r)=>{switch((0,n.type)(r[e])){case"undefined":return;case"Array":switch((0,n.type)(t[e])){case"Array":return t[e]=(0,o.push)(t[e],r[e]);default:return t[e]=r[e].slice()}case"Object":switch((0,n.type)(t[e])){case"Object":return t[e]=(0,i.merge)(t[e],r[e]);default:return t[e]=(0,i.merge)(a(r[e]),r[e])}default:return t[e]=r[e]}}),i.inherit=c((e,t,r)=>{switch((0,n.type)(r[e])){case"undefined":return;case"Array":return t[e]=r[e].slice();case"Object":switch((0,n.type)(t[e])){case"Object":return t[e]=(0,s.hasOwnProperty)(t,e)?(0,i.inherit)(t[e],r[e]):(0,i.inherit)((0,s.ObjectCreate)(t[e]),r[e]);default:return t[e]=(0,s.ObjectCreate)(r[e])}default:return t[e]=r[e]}}),i.overwrite=c((e,t,r)=>{switch((0,n.type)(r[e])){case"Array":return t[e]=r[e];case"Object":switch((0,n.type)(t[e])){case"Object":return t[e]=(0,i.overwrite)(t[e],r[e]);default:return t[e]=(0,i.overwrite)(a(r[e]),r[e])}default:return t[e]=r[e]}}),i.template=c},{"./alias":3,"./array":4,"./global":8,"./type":12}],6:[function(e,t,i){"use strict";var r;Object.defineProperty(i,"__esModule",{value:!0}),i.Cache=void 0;const s=e("./global"),n=e("./alias"),o=e("./ilist"),c=e("./assign"),a=e("./tuple"),h=e("./compare"),u=Symbol("size");function l(e,t,i,r,s){e=(0,n.min)(i+s,e);const o=100*t/i|0,c=(0,n.min)(100*i/e|0,100);return o*c+(100*r/s|0)*(100-c)|0}i.Cache=class{constructor(e,t={}){if(this.capacity=e,this.settings={space:0,age:s.Infinity,capture:{delete:!0,clear:!0}},this[r]=0,this.clock=0,this.clockR=0,this.memory=new s.Map,this.indexes={LRU:new o.IList(this.capacity,!0),LFU:new o.IList(this.capacity,!0)},this.stats={LRU:(0,a.tuple)(0,0),LFU:(0,a.tuple)(0,0)},this.ratio=50,e<1)throw new Error("Spica: Cache: Capacity must be 1 or more.");(0,c.extend)(this.settings,t),this.space=this.settings.space}get length(){return this.indexes.LRU.length+this.indexes.LFU.length}get size(){return this[u]}secure(e,t){if(e<=0)return!0;const{LRU:i,LFU:r}=this.indexes;let s=1!==arguments.length&&void 0;for(;this.length===this.capacity||this.space&&this.size+e>this.space;){const{key:e}=0===i.length||r.length>this.capacity*this.ratio/100||r.length>this.capacity/2&&r.peek(-1).value<this.clock-8*this.capacity?r.peek(-1):i.peek(-1);null!=s||(s=!(0,h.equal)(e,t)&&s),this.dispose(e,this.memory.get(e),this.settings.disposer)}return null==s||s}dispose(e,{target:t,index:i,size:r,value:s},n){this.indexes[t].delete(e,i),this.memory.delete(e),this.space&&(this[u]-=r),null==n||n(e,s)}put(e,t,i=1,r=this.settings.age){var n,o;if(i<1)throw new Error("Spica: Cache: Size must be 1 or more.");if(r<1)throw new Error("Spica: Cache: Age must be 1 or more.");if(this.space&&i>this.space/this.capacity*10||r<=0)return null===(o=(n=this.settings).disposer)||void 0===o||o.call(n,e,t),!1;const c=r===s.Infinity?s.Infinity:s.Date.now()+r,a=this.memory.get(e);if(a&&this.secure(i-a.size,e))return this.space&&(this[u]+=i-a.size),a.value=t,a.size=i,a.expiry=c,!0;this.secure(i);const{LRU:h}=this.indexes;return this.space&&(this[u]+=i),this.memory.set(e,{target:"LRU",index:h.add(e,++this.clockR),value:t,size:i,expiry:c}),!1}set(e,t,i,r){return this.put(e,t,i,r),this}get(e){const t=this.memory.get(e);if(t){if(!(t.expiry!==s.Infinity&&t.expiry<=s.Date.now()))return this.access(e,t),this.slide(),t.value;this.dispose(e,t,this.settings.disposer)}}has(e){const t=this.memory.get(e);return!(!t||t.expiry!==s.Infinity&&t.expiry<=s.Date.now()&&(this.dispose(e,t,this.settings.disposer),1))}delete(e){const t=this.memory.get(e);return!!t&&(this.dispose(e,t,this.settings.capture.delete?this.settings.disposer:void 0),!0)}clear(){this[u]=0,this.ratio=50,this.indexes.LRU.clear(),this.indexes.LFU.clear(),this.stats={LRU:[0,0],LFU:[0,0]};const e=this.memory;if(this.memory=new s.Map,this.settings.disposer&&this.settings.capture.clear)for(const[t,{value:i}]of e)this.settings.disposer(t,i)}*[(r=u,Symbol.iterator)](){for(const[e,{value:t}]of this.memory)yield[e,t]}slide(){const{LRU:e,LFU:t}=this.stats,{capacity:i,ratio:r,indexes:s}=this;if((e[0]+t[0])%(0,n.max)(i/100|0,1))return;const o=i,c=e[1]+t[1]>0,a=l(o,e[0],e[0]+t[0],e[1],e[1]+t[1]),h=l(o,t[0],e[0]+t[0],t[1],e[1]+t[1])*s.LRU.length/s.LFU.length|0,u=s.LRU.length>=i*(100-r)/100,d=s.LFU.length>=i*r/100;c&&r<100&&d&&h>a?this.ratio+=1:c&&r>10&&u&&a>h&&(this.ratio-=1),e[0]+t[0]>=o&&(this.stats={LRU:[0,e[0]],LFU:[0,t[0]]})}access(e,t){return this.accessLFU(e,t)||this.accessLRU(e,t)}accessLRU(e,t){if("LRU"!==t.target)return!1;const{LRU:i,LFU:r}=this.indexes,{index:s}=t;return++this.stats.LRU[0],++this.clock,++this.clockR,i.node(s).value+i.length/3>this.clockR?(i.put(e,this.clockR,s),i.moveToHead(s),!0):(i.delete(e,s),t.target="LFU",t.index=r.add(e,this.clock),!0)}accessLFU(e,t){if("LFU"!==t.target)return!1;const{LFU:i}=this.indexes,{index:r}=t;return++this.stats.LFU[0],++this.clock,i.put(e,this.clock,r),i.moveToHead(r),!0}}},{"./alias":3,"./assign":5,"./compare":7,"./global":8,"./ilist":9,"./tuple":11}],7:[function(e,t,i){"use strict";Object.defineProperty(i,"__esModule",{value:!0}),i.equal=void 0,i.equal=function(e,t){return e==e?e===t:t!=t}},{}],8:[function(_dereq_,module,exports){"use strict";const global="undefined"!=typeof globalThis&&globalThis||"undefined"!=typeof self&&self||Function("return this")();eval("global.global = global"),module.exports=global},{}],9:[function(e,t,i){"use strict";var r=this&&this.__createBinding||(Object.create?function(e,t,i,r){void 0===r&&(r=i),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[i]}})}:function(e,t,i,r){void 0===r&&(r=i),e[r]=t[i]}),s=this&&this.__exportStar||function(e,t){for(var i in e)"default"===i||Object.prototype.hasOwnProperty.call(t,i)||r(t,e,i)};Object.defineProperty(i,"__esModule",{value:!0}),s(e("./list/ilist"),i)},{"./list/ilist":10}],10:[function(e,t,i){"use strict";var r;Object.defineProperty(i,"__esModule",{value:!0}),i.IList=void 0;const s=e("../compare"),n=Symbol("length");i.IList=class{constructor(e,t=!1){this.capacity=e,this.strict=t,this.nodes=[],this.empties=[],this.head=0,this.cursor=0,this[r]=0}get length(){return this[n]}clear(){this.nodes=[],this.empties=[],this.head=0,this.cursor=0,this[n]=0}add(e,t){const i=this.nodes,r=i[this.head];if(!r){const s=this.head=this.cursor=this.empties.length>0?this.empties.shift():this.length;return++this[n],i[s]=new o(s,e,t,r,r),s}if(this.length<this.capacity){const s=this.head=this.cursor=this.empties.length>0?this.empties.shift():this.length;return++this[n],i[s]=r.prev=r.prev.next=new o(s,e,t,r,r.prev),s}{const s=r.prev,n=this.head=this.cursor=s.index;return i[n]=r.prev=r.prev.prev.next=new o(n,e,t,r,r.prev.prev),s.key=s.value=s.prev=s.next=void 0,n}}put(e,t,i){const r=this.seek(e,i);return r?(r.value=t,r.index):this.add(e,t)}shift(){const e=this.nodes[this.head];return e&&this.delete(e.key,e.index)}pop(){var e;const t=null===(e=this.nodes[this.head])||void 0===e?void 0:e.prev;return t&&this.delete(t.key,t.index)}delete(e,t){const i=this.cursor,r=this.seek(e,t);if(!r)return;this.cursor=i,--this[n],this.empties.push(r.index);const{prev:s,next:o,value:c}=r;return s.next=o,o.prev=s,this.head===r.index&&(this.head=o.index),this.cursor===r.index&&(this.cursor=o.index),this.nodes[r.index]=r.key=r.value=r.prev=r.next=void 0,{key:e,value:c}}peek(e){var t;const i=e?null===(t=this.nodes[this.head])||void 0===t?void 0:t.prev:this.nodes[this.head];return i&&{index:i.index,key:i.key,value:i.value}}node(e){const t=this.nodes[e];if(!t)throw new Error("Spica: IList: Invalid index.");return{index:t.index,key:t.key,value:t.value}}next(e){var t,i;return this.node(null!==(i=null===(t=this.nodes[e])||void 0===t?void 0:t.next.index)&&void 0!==i?i:this.capacity)}prev(e){var t,i;return this.node(null!==(i=null===(t=this.nodes[e])||void 0===t?void 0:t.prev.index)&&void 0!==i?i:this.capacity)}find(e,t){var i;if(this.strict)throw new Error("Spica: IList: Invalid cursor.");return null===(i=this.seek(e,t))||void 0===i?void 0:i.value}findIndex(e,t){var i;if(this.strict)throw new Error("Spica: IList: Invalid cursor.");return null===(i=this.seek(e,t))||void 0===i?void 0:i.index}has(e,t){if(this.strict)throw new Error("Spica: IList: Invalid cursor.");return!!this.seek(e,t)}*[(r=n,Symbol.iterator)](){for(let e=this.nodes[this.head],t=0;e&&t<this.length;(e=e.next)&&++t)yield[e.key,e.value,e.index]}seek(e,t=this.cursor){let i;if(i=this.nodes[t]){if((0,s.equal)(i.key,e))return this.cursor=t,i;if(this.strict)throw new Error("Spica: IList: Invalid cursor.");for(let t=1;t<this.length&&(i=i.next);++t)if((0,s.equal)(i.key,e))return this.cursor=i.index,i}}insert(e,t){if(e===t)return!1;const i=this.nodes[t];if(!i)return!1;const r=this.nodes[e];if(!r)return!1;if(r.next===i)return!1;const s=i.prev,n=r.prev,o=r.next;return s.next=r,r.next=i,i.prev=r,r.prev=s,n.next=o,o.prev=n,!0}moveToHead(e){return!(this.length<=1)&&(e!==this.head&&(!!this.nodes[e]&&(this.insert(e,this.head),this.head=e,!0)))}moveToPrev(e){if(this.length<=1)return!1;if(e===this.head)return!1;const t=this.nodes[e];return!!t&&(this.insert(t.index,t.prev.index),t.next.index===this.head&&(this.head=t.index),!0)}swap(e,t){if(this.length<=1)return!1;if(e===t)return!1;const i=this.nodes[e],r=this.nodes[t];if(!i||!r)return!1;if(i.next===r)return this.moveToPrev(t);if(r.next===i)return this.moveToPrev(e);const s=r.next;switch(this.insert(r.index,i.index),this.insert(i.index,s.index),this.head){case i.index:this.head=r.index;break;case r.index:this.head=i.index}return!0}};class o{constructor(e,t,i,r,s){this.index=e,this.key=t,this.value=i,this.next=r,this.prev=s,r&&r.index!==e||(this.next=this),s&&s.index!==e||(this.prev=this)}}},{"../compare":7}],11:[function(e,t,i){"use strict";Object.defineProperty(i,"__esModule",{value:!0}),i.tuple=void 0,i.tuple=function(...e){return e}},{}],12:[function(e,t,i){"use strict";Object.defineProperty(i,"__esModule",{value:!0}),i.isPrimitive=i.isType=i.type=void 0;const r=e("./alias"),s=Object.prototype.toString.call.bind(Object.prototype.toString),n=Object.prototype,o=Array.prototype;function c(e){if(void 0===e)return"undefined";if(null===e)return"null";const t=typeof e;if("object"===t){const t=(0,r.ObjectGetPrototypeOf)(e);return t===n||null===t?"Object":t===o?"Array":s(e).slice(8,-1)}return"function"===t?"Function":t}i.type=c,i.isType=function(e,t){return"object"===t?null!==e&&typeof e===t:"function"===t?typeof e===t:c(e)===t},i.isPrimitive=function(e){const t=typeof e;return"object"!==t&&"function"!==t||null===e}},{"./alias":3}],"dw-cache":[function(e,t,i){"use strict";var r=this&&this.__createBinding||(Object.create?function(e,t,i,r){void 0===r&&(r=i),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[i]}})}:function(e,t,i,r){void 0===r&&(r=i),e[r]=t[i]}),s=this&&this.__exportStar||function(e,t){for(var i in e)"default"===i||Object.prototype.hasOwnProperty.call(t,i)||r(t,e,i)};Object.defineProperty(i,"__esModule",{value:!0}),s(e("spica/cache"),i)},{"spica/cache":6}]},{},[1,2,"dw-cache"]),function(e,t){"function"==typeof define&&define.amd?define([],t):"object"==typeof module&&module.exports?module.exports=t():Object.assign(e,t())}("undefined"!=typeof self?self:this,function(){return require("dw-cache")}); | ||
/*! dw-cache v0.0.2 https://github.com/falsandtru/dw-cache | (c) 2021, falsandtru | (Apache-2.0 AND MPL-2.0) License */ | ||
require=function(){return function e(t,s,i){function r(o,c){if(!s[o]){if(!t[o]){var a="function"==typeof require&&require;if(!c&&a)return a(o,!0);if(n)return n(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var l=s[o]={exports:{}};t[o][0].call(l.exports,function(e){return r(t[o][1][e]||e)},l,l.exports,e,t,s,i)}return s[o].exports}for(var n="function"==typeof require&&require,o=0;o<i.length;o++)r(i[o]);return r}}()({1:[function(e,t,s){},{}],2:[function(e,t,s){arguments[4][1][0].apply(s,arguments)},{dup:1}],3:[function(e,t,s){"use strict";Object.defineProperty(s,"__esModule",{value:!0}),s.isArray=s.ObjectValues=s.ObjectSetPrototypeOf=s.ObjectSeal=s.ObjectPreventExtensions=s.ObjectKeys=s.isSealed=s.isFrozen=s.isExtensible=s.ObjectIs=s.ObjectGetPrototypeOf=s.ObjectGetOwnPropertySymbols=s.ObjectGetOwnPropertyNames=s.ObjectGetOwnPropertyDescriptors=s.ObjectGetOwnPropertyDescriptor=s.ObjectFromEntries=s.ObjectFreeze=s.ObjectEntries=s.ObjectDefineProperty=s.ObjectDefineProperties=s.ObjectCreate=s.ObjectAssign=s.toString=s.isEnumerable=s.isPrototypeOf=s.hasOwnProperty=s.SymbolKeyFor=s.SymbolFor=s.sign=s.round=s.random=s.min=s.max=s.floor=s.ceil=s.abs=s.parseInt=s.parseFloat=s.isSafeInteger=s.isNaN=s.isInteger=s.isFinite=s.NaN=void 0,s.NaN=Number.NaN,s.isFinite=Number.isFinite,s.isInteger=Number.isInteger,s.isNaN=Number.isNaN,s.isSafeInteger=Number.isSafeInteger,s.parseFloat=Number.parseFloat,s.parseInt=Number.parseInt,s.abs=Math.abs,s.ceil=Math.ceil,s.floor=Math.floor,s.max=Math.max,s.min=Math.min,s.random=Math.random,s.round=Math.round,s.sign=Math.sign,s.SymbolFor=Symbol.for,s.SymbolKeyFor=Symbol.keyFor,s.hasOwnProperty=Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty),s.isPrototypeOf=Object.prototype.isPrototypeOf.call.bind(Object.prototype.isPrototypeOf),s.isEnumerable=Object.prototype.propertyIsEnumerable.call.bind(Object.prototype.propertyIsEnumerable),s.toString=Object.prototype.toString.call.bind(Object.prototype.toString),s.ObjectAssign=Object.assign,s.ObjectCreate=Object.create,s.ObjectDefineProperties=Object.defineProperties,s.ObjectDefineProperty=Object.defineProperty,s.ObjectEntries=Object.entries,s.ObjectFreeze=Object.freeze,s.ObjectFromEntries=Object.fromEntries,s.ObjectGetOwnPropertyDescriptor=Object.getOwnPropertyDescriptor,s.ObjectGetOwnPropertyDescriptors=Object.getOwnPropertyDescriptors,s.ObjectGetOwnPropertyNames=Object.getOwnPropertyNames,s.ObjectGetOwnPropertySymbols=Object.getOwnPropertySymbols,s.ObjectGetPrototypeOf=Object.getPrototypeOf,s.ObjectIs=Object.is,s.isExtensible=Object.isExtensible,s.isFrozen=Object.isFrozen,s.isSealed=Object.isSealed,s.ObjectKeys=Object.keys,s.ObjectPreventExtensions=Object.preventExtensions,s.ObjectSeal=Object.seal,s.ObjectSetPrototypeOf=Object.setPrototypeOf,s.ObjectValues=Object.values,s.isArray=Array.isArray},{}],4:[function(e,t,s){"use strict";Object.defineProperty(s,"__esModule",{value:!0}),s.join=s.splice=s.pop=s.push=s.shift=s.unshift=s.indexOf=void 0;const i=e("./global");function r(e,t){if("length"in e)for(let s=e.length-1;s>=0;--s)t.unshift(e[s]);else t.unshift(...e);return t}function n(e,t){if("length"in t)for(let s=0,i=t.length;s<i;++s)e.push(t[s]);else for(const s of t)e.push(s);return e}function o(e,t,s,...c){if(0===s&&0===c.length)return[];switch(s=s>e.length?e.length:s,t){case 0:switch(s){case 0:return[[],r(c,e)][0];case 1:return 0===e.length?[[],r(c,e)][0]:[[e.shift()],r(c,e)][0];case void 0:if(e.length>1||arguments.length>2)break;return 0===e.length?[]:o(e,t,1)}break;case-1:case e.length-1:switch(s){case 1:return 0===e.length?[[],n(e,c)][0]:[[e.pop()],n(e,c)][0];case void 0:if(e.length>1||arguments.length>2)break;return 0===e.length?[]:o(e,t,1)}break;case e.length:case i.Infinity:return[[],n(e,c)][0]}return arguments.length>2?e.splice(t,s,...c):e.splice(t)}s.indexOf=function(e,t){return 0===e.length?-1:t==t?e.indexOf(t):e.findIndex(e=>e!=e)},s.unshift=r,s.shift=function(e,t){if(t<0)throw new Error("Unexpected negative number");return void 0===t?[e.shift(),e]:[o(e,0,t),e]},s.push=n,s.pop=function(e,t){if(t<0)throw new Error("Unexpected negative number");return void 0===t?[e,e.pop()]:[e,o(e,e.length-t,t)]},s.splice=o,s.join=function(e,t=""){let s="";for(let i=0;i<e.length;++i)s+=0===i?e[i]:t+e[i];return s}},{"./global":10}],5:[function(e,t,s){"use strict";Object.defineProperty(s,"__esModule",{value:!0}),s.template=s.overwrite=s.inherit=s.merge=s.extend=s.clone=s.assign=void 0;const i=e("./global"),r=e("./alias"),n=e("./type"),o=e("./array");function c(e){return function(t,...s){if((0,n.isPrimitive)(t))return t;for(let i=0;i<s.length;++i){const o=s[i];if(o===t)continue;if((0,n.isPrimitive)(o))continue;const c=(0,r.ObjectKeys)(o);for(let s=0;s<c.length;++s)e(c[s],t,o)}return t}}function a(e){switch((0,n.type)(e)){case"Array":return[];case"Object":return e instanceof i.Object?{}:(0,r.ObjectCreate)(null);default:return e}}s.assign=c((e,t,s)=>t[e]=s[e]),s.clone=c((e,t,i)=>{switch((0,n.type)(i[e])){case"Array":return t[e]=i[e].slice();case"Object":switch((0,n.type)(t[e])){case"Object":return t[e]=(0,s.clone)(a(i[e]),i[e]);default:return t[e]=i[e]}default:return t[e]=i[e]}}),s.extend=c((e,t,i)=>{switch((0,n.type)(i[e])){case"undefined":return;case"Array":return t[e]=i[e];case"Object":switch((0,n.type)(t[e])){case"Object":return t[e]=(0,s.extend)(t[e],i[e]);default:return t[e]=(0,s.extend)(a(i[e]),i[e])}default:return t[e]=i[e]}}),s.merge=c((e,t,i)=>{switch((0,n.type)(i[e])){case"undefined":return;case"Array":switch((0,n.type)(t[e])){case"Array":return t[e]=(0,o.push)(t[e],i[e]);default:return t[e]=i[e].slice()}case"Object":switch((0,n.type)(t[e])){case"Object":return t[e]=(0,s.merge)(t[e],i[e]);default:return t[e]=(0,s.merge)(a(i[e]),i[e])}default:return t[e]=i[e]}}),s.inherit=c((e,t,i)=>{switch((0,n.type)(i[e])){case"undefined":return;case"Array":return t[e]=i[e].slice();case"Object":switch((0,n.type)(t[e])){case"Object":return t[e]=(0,r.hasOwnProperty)(t,e)?(0,s.inherit)(t[e],i[e]):(0,s.inherit)((0,r.ObjectCreate)(t[e]),i[e]);default:return t[e]=(0,r.ObjectCreate)(i[e])}default:return t[e]=i[e]}}),s.overwrite=c((e,t,i)=>{switch((0,n.type)(i[e])){case"Array":return t[e]=i[e];case"Object":switch((0,n.type)(t[e])){case"Object":return t[e]=(0,s.overwrite)(t[e],i[e]);default:return t[e]=(0,s.overwrite)(a(i[e]),i[e])}default:return t[e]=i[e]}}),s.template=c},{"./alias":3,"./array":4,"./global":10,"./type":16}],6:[function(e,t,s){"use strict";var i;Object.defineProperty(s,"__esModule",{value:!0}),s.Cache=void 0;const r=e("./global"),n=e("./alias"),o=e("./clock"),c=e("./ixlist"),a=e("./assign"),u=e("./tuple"),l=e("./compare"),h=Symbol("size");function d(e,t,s,i,r){e=(0,n.min)(s+r,e);const o=100*t/s|0,c=(0,n.min)(100*s/e|0,100);return o*c+(100*i/r|0)*(100-c)|0}s.Cache=class{constructor(e,t={}){if(this.capacity=e,this.settings={space:0,age:r.Infinity,capture:{delete:!0,clear:!0}},this[i]=0,this.clock=0,this.clockR=0,this.memory=new r.Map,this.indexes={LRU:new c.IxList(this.capacity),LFU:new c.IxList(this.capacity)},this.stats={LRU:(0,u.tuple)(0,0),LFU:(0,u.tuple)(0,0)},this.ratio=50,e<1)throw new Error("Spica: Cache: Capacity must be 1 or more.");(0,a.extend)(this.settings,t),this.space=this.settings.space}get length(){return this.indexes.LRU.length+this.indexes.LFU.length}get size(){return this[h]}dispose(e,{target:t,index:s,value:i,size:r},n){this.indexes[t].delete(e,s),this.memory.delete(e),this.space&&(this[h]-=r),null==n||n(e,i)}secure(e,t){if(e<=0)return!0;const{LRU:s,LFU:i}=this.indexes;let r=!!t&&void 0;for(;this.length===this.capacity||this.space&&this.size+e>this.space;){const{key:n}=0===s.length||i.length>this.capacity*this.ratio/100||i.length>this.capacity/2&&i.last.value<this.clock-8*this.capacity?i.last:s.last;(null!=r?r:(0,l.equal)(n,t.key))?(r=!1,e+=t.record.size,this.dispose(n,t.record,this.settings.disposer)):this.dispose(n,this.memory.get(n),this.settings.disposer)}return null==r||r}put(e,t,s=1,i=this.settings.age){var n,c;if(s<1)throw new Error("Spica: Cache: Size must be 1 or more.");if(i<1)throw new Error("Spica: Cache: Age must be 1 or more.");if(this.space&&s>this.space/this.capacity*10||i<=0)return null===(c=(n=this.settings).disposer)||void 0===c||c.call(n,e,t),!1;const a=i===r.Infinity?r.Infinity:(0,o.now)()+i,u=this.memory.get(e);if(u&&this.secure(s-u.size,{key:e,record:u}))return this.space&&(this[h]+=s-u.size),u.value=t,u.size=s,u.expiry=a,!0;u||this.secure(s);const{LRU:l}=this.indexes;return this.space&&(this[h]+=s),this.memory.set(e,{target:"LRU",index:l.add(e,++this.clockR),value:t,size:s,expiry:a}),!1}set(e,t,s,i){return this.put(e,t,s,i),this}get(e){const t=this.memory.get(e);if(t){if(!(t.expiry!==r.Infinity&&t.expiry<=(0,o.now)()))return this.access(e,t),this.slide(),t.value;this.dispose(e,t,this.settings.disposer)}}has(e){const t=this.memory.get(e);return!(!t||t.expiry!==r.Infinity&&t.expiry<=(0,o.now)()&&(this.dispose(e,t,this.settings.disposer),1))}delete(e){const t=this.memory.get(e);return!!t&&(this.dispose(e,t,this.settings.capture.delete?this.settings.disposer:void 0),!0)}clear(){if(this[h]=0,this.ratio=50,this.indexes.LRU.clear(),this.indexes.LFU.clear(),this.stats={LRU:[0,0],LFU:[0,0]},!this.settings.disposer||!this.settings.capture.clear)return void this.memory.clear();const e=this.memory;this.memory=new r.Map;for(const[t,{value:s}]of e)this.settings.disposer(t,s)}*[(i=h,Symbol.iterator)](){for(const[e,{value:t}]of this.memory)yield[e,t]}slide(){const{LRU:e,LFU:t}=this.stats,{capacity:s,ratio:i,indexes:r}=this;if((e[0]+t[0])%(0,n.max)(s/100|0,1))return;const o=s,c=e[1]+t[1]>0,a=d(o,e[0],e[0]+t[0],e[1],e[1]+t[1]),u=d(o,t[0],e[0]+t[0],t[1],e[1]+t[1])*r.LRU.length/r.LFU.length|0,l=r.LRU.length>=s*(100-i)/100,h=r.LFU.length>=s*i/100;c&&i<100&&h&&u>a?this.ratio+=1:c&&i>10&&l&&a>u&&(this.ratio-=1),e[0]+t[0]>=o&&(this.stats={LRU:[0,e[0]],LFU:[0,t[0]]})}access(e,t){return this.accessLFU(e,t)||this.accessLRU(e,t)}accessLRU(e,t){if("LRU"!==t.target)return!1;const{LRU:s,LFU:i}=this.indexes,{index:r}=t;return++this.stats.LRU[0],++this.clock,++this.clockR,s.node(r).value+s.length/3>this.clockR?(s.put(e,this.clockR,r),s.moveToHead(r),!0):(s.delete(e,r),t.target="LFU",t.index=i.add(e,this.clock),!0)}accessLFU(e,t){if("LFU"!==t.target)return!1;const{LFU:s}=this.indexes,{index:i}=t;return++this.stats.LFU[0],++this.clock,s.put(e,this.clock,i),s.moveToHead(i),!0}}},{"./alias":3,"./assign":5,"./clock":7,"./compare":8,"./global":10,"./ixlist":11,"./tuple":15}],7:[function(e,t,s){"use strict";Object.defineProperty(s,"__esModule",{value:!0}),s.tick=s.wait=s.clock=s.now=void 0;const i=e("./global"),r=e("./alias"),n=e("./promise"),o=e("./exception");let c;s.now=function(){return void 0!==c?c:(d(()=>c=void 0),c=i.Date.now())},s.clock=Promise.resolve(void 0),s.wait=function(e){return 0===e?n.AtomicPromise.resolve(s.clock):new n.AtomicPromise(t=>void(0,i.setTimeout)(t,e))};let a=[],u=[],l=0;const h=Promise.resolve();function d(e){0===l&&h.then(f),l++===a.length?a.push(e):a[l-1]=e}function f(){const e=l;[l,a,u]=[0,u,a];for(let t=0;t<e;++t)try{u[t](),u[t]=void 0}catch(e){(0,o.causeAsyncException)(e)}u.length>1e3&&e<.5*u.length&&u.splice((0,r.floor)(.9*u.length),u.length)}s.tick=d},{"./alias":3,"./exception":9,"./global":10,"./promise":14}],8:[function(e,t,s){"use strict";Object.defineProperty(s,"__esModule",{value:!0}),s.equal=void 0,s.equal=function(e,t){return e==e?e===t:t!=t}},{}],9:[function(e,t,s){"use strict";Object.defineProperty(s,"__esModule",{value:!0}),s.causeAsyncException=void 0,s.causeAsyncException=function(e){Promise.reject(e)}},{}],10:[function(_dereq_,module,exports){"use strict";const global="undefined"!=typeof globalThis&&globalThis||"undefined"!=typeof self&&self||Function("return this")();eval("global.global = global"),module.exports=global},{}],11:[function(e,t,s){"use strict";var i=this&&this.__createBinding||(Object.create?function(e,t,s,i){void 0===i&&(i=s),Object.defineProperty(e,i,{enumerable:!0,get:function(){return t[s]}})}:function(e,t,s,i){void 0===i&&(i=s),e[i]=t[s]}),r=this&&this.__exportStar||function(e,t){for(var s in e)"default"===s||Object.prototype.hasOwnProperty.call(t,s)||i(t,e,s)};Object.defineProperty(s,"__esModule",{value:!0}),r(e("./list/ixlist"),s)},{"./list/ixlist":12}],12:[function(e,t,s){"use strict";var i,r,n;Object.defineProperty(s,"__esModule",{value:!0}),s.IxList=void 0;const o=e("../compare"),c=Symbol("head"),a=Symbol("cursor"),u=Symbol("length");s.IxList=class{constructor(e,t){this.capacity=e,this.index=t,this.nodes=[],this.buffers=[],this[i]=0,this[r]=0,this[n]=0}get length(){return this[u]}get head(){const e=this.nodes[this[c]];return e&&{index:e.index,key:e.key,value:e.value}}get last(){var e;const t=null===(e=this.nodes[this[c]])||void 0===e?void 0:e.prev;return t&&{index:t.index,key:t.key,value:t.value}}node(e){const t=this.nodes[e];if(!t)throw new Error("Spica: IxList: Invalid index.");return{index:t.index,key:t.key,value:t.value}}next(e){var t,s;return this.node(null!==(s=null===(t=this.nodes[e])||void 0===t?void 0:t.next.index)&&void 0!==s?s:this.capacity)}prev(e){var t,s;return this.node(null!==(s=null===(t=this.nodes[e])||void 0===t?void 0:t.prev.index)&&void 0!==s?s:this.capacity)}clear(){var e;this.nodes=[],this.buffers=[],null===(e=this.index)||void 0===e||e.clear(),this[c]=0,this[a]=0,this[u]=0}add(e,t){var s,i;const r=this.nodes,n=r[this[c]];if(!n){const i=this[c]=this[a]=this.buffers.length>0?this.buffers.shift():this.length;return++this[u],null===(s=this.index)||void 0===s||s.set(e,i),r[i]=new l(i,e,t,n,n),i}if(this.length<this.capacity){const s=this[c]=this[a]=this.buffers.length>0?this.buffers.shift():this.length;return++this[u],null===(i=this.index)||void 0===i||i.set(e,s),r[s]=n.prev=n.prev.next=new l(s,e,t,n,n.prev),s}{const s=n.prev,i=this[c]=this[a]=s.index;return this.index&&!(0,o.equal)(e,s.key)&&(this.index.delete(s.key,s.index),this.index.set(e,i)),s.key=e,s.value=t,i}}put(e,t,s){const i=this.search(e,s);return i?(i.value=t,i.index):this.add(e,t)}delete(e,t){var s;const i=this[a],r=this.search(e,t);if(!r)return;this[a]=i,--this[u],this.buffers.push(r.index),null===(s=this.index)||void 0===s||s.delete(r.key,r.index);const{prev:n,next:o,value:l}=r;return n.next=o,o.prev=n,this[c]===r.index&&(this[c]=o.index),this[a]===r.index&&(this[a]=o.index),this.nodes[r.index]=r.key=r.value=r.prev=r.next=void 0,{key:e,value:l}}unshift(e,t){return this.add(e,t)}shift(){const e=this.nodes[this[c]];return e&&this.delete(e.key,e.index)}push(e,t){const s=this[c],i=this.add(e,t);return this[c]=s,i}pop(){var e;const t=null===(e=this.nodes[this[c]])||void 0===e?void 0:e.prev;return t&&this.delete(t.key,t.index)}search(e,t=this[a]){var s;let i;if((i=this.nodes[t])&&(0,o.equal)(i.key,e))return this[a]=t,i;if(!this.index)throw new Error("Spica: IxList: Invalid index.");return(i=this.nodes[t=null!==(s=this.index.get(e))&&void 0!==s?s:this.capacity])&&(0,o.equal)(i.key,e)?(this[a]=t,i):void 0}find(e,t){var s;if(!this.index)throw new Error("Spica: IxList: No index.");return null===(s=this.search(e,t))||void 0===s?void 0:s.value}findIndex(e,t){var s;if(!this.index)throw new Error("Spica: IxList: No index.");return null===(s=this.search(e,t))||void 0===s?void 0:s.index}has(e,t){if(!this.index)throw new Error("Spica: IxList: No index.");return void 0!==this.search(e,t)}*[(i=c,r=a,n=u,Symbol.iterator)](){for(let e=this.nodes[this[c]],t=0;e&&t<this.length;(e=e.next)&&++t)yield[e.key,e.value]}insert(e,t){if(e===t)return!1;const s=this.nodes[e];if(!s)return!1;const i=this.nodes[t];if(!i)return!1;if(s.next===i)return!1;const r=i.prev,n=s.prev,o=s.next;return r.next=s,s.next=i,i.prev=s,s.prev=r,n.next=o,o.prev=n,!0}moveToHead(e){return!(this.length<=1)&&(e!==this[c]&&(!!this.nodes[e]&&(this.insert(e,this[c]),this[c]=e,!0)))}moveToPrev(e){if(this.length<=1)return!1;if(e===this[c])return!1;const t=this.nodes[e];return!!t&&(this.insert(t.index,t.prev.index),t.next.index===this[c]&&(this[c]=t.index),!0)}swap(e,t){if(this.length<=1)return!1;if(e===t)return!1;const s=this.nodes[e],i=this.nodes[t];if(!s||!i)return!1;if(s.next===i)return this.moveToPrev(t);if(i.next===s)return this.moveToPrev(e);const r=i.next;switch(this.insert(i.index,s.index),this.insert(s.index,r.index),this[c]){case s.index:this[c]=i.index;break;case i.index:this[c]=s.index}return!0}};class l{constructor(e,t,s,i,r){this.index=e,this.key=t,this.value=s,this.next=i,this.prev=r,i&&i.index!==e||(this.next=this),r&&r.index!==e||(this.prev=this)}}},{"../compare":8}],13:[function(e,t,s){"use strict";Object.defineProperty(s,"__esModule",{value:!0}),s.noop=void 0,s.noop=function(){}},{}],14:[function(e,t,s){"use strict";var i,r;Object.defineProperty(s,"__esModule",{value:!0}),s.never=s.isPromiseLike=s.Internal=s.AtomicPromise=void 0;const n=e("./global"),o=e("./alias"),c=e("./noop"),a=Symbol.for("spica/promise::internal");class u{constructor(e){this[i]="Promise",this[r]=new l;try{e(e=>void this[a].resolve(e),e=>void this[a].reject(e))}catch(e){this[a].reject(e)}}static get[Symbol.species](){return u}static all(e){return new u((t,s)=>{const i=(0,o.isArray)(e)?e:[...e],r=(0,n.Array)(i.length);let c=0;for(let e=0;e<i.length;++e){const n=i[e];if(h(n)){if(d(n)){const{status:t}=n[a];switch(t.state){case 2:r[e]=t.value,++c;continue;case 3:s(t.reason),e=i.length;continue}}n.then(s=>{r[e]=s,++c===i.length&&t(r)},t=>{s(t),e=i.length})}else r[e]=n,++c}c===i.length&&t(r)})}static race(e){return new u((t,s)=>{const i=(0,o.isArray)(e)?e:[...e];for(let e=0;e<i.length;++e){const r=i[e];if(!h(r))return t(r);if(d(r)){const{status:e}=r[a];switch(e.state){case 2:return t(e.value);case 3:return s(e.reason)}}}let r=!1;for(let e=0;e<i.length;++e){if(i[e].then(e=>{t(e),r=!0},e=>{s(e),r=!0}),r)return}})}static allSettled(e){return new u(t=>{const s=(0,o.isArray)(e)?e:[...e],i=(0,n.Array)(s.length);let r=0;for(let e=0;e<s.length;++e){const n=s[e];if(h(n)){if(d(n)){const{status:t}=n[a];switch(t.state){case 2:i[e]={status:"fulfilled",value:t.value},++r;continue;case 3:i[e]={status:"rejected",reason:t.reason},++r;continue}}n.then(n=>{i[e]={status:"fulfilled",value:n},++r===s.length&&t(i)},n=>{i[e]={status:"rejected",reason:n},++r===s.length&&t(i)})}else i[e]={status:"fulfilled",value:n},++r}r===s.length&&t(i)})}static resolve(e){return new u(t=>t(e))}static reject(e){return new u((t,s)=>s(e))}then(e,t){return new u((s,i)=>this[a].then(s,i,e,t))}catch(e){return this.then(void 0,e)}finally(e){return this.then(e,e).then(()=>this)}}s.AtomicPromise=u,i=Symbol.toStringTag,r=a;class l{constructor(){this.status={state:0},this.fulfillReactions=[],this.rejectReactions=[]}get isPending(){return 0===this.status.state}resolve(e){if(0===this.status.state){if(!h(e))return this.status={state:2,value:e},this.resume();if(d(e)){const t=e[a];switch(t.status.state){case 2:case 3:return this.status=t.status,this.resume();default:return t.then(()=>(this.status=t.status,this.resume()),()=>(this.status=t.status,this.resume()))}}this.status={state:1,promise:e},e.then(e=>{this.status={state:2,value:e},this.resume()},e=>{this.status={state:3,reason:e},this.resume()})}}reject(e){if(0===this.status.state)return this.status={state:3,reason:e},this.resume()}then(e,t,s,i){const{status:r,fulfillReactions:n,rejectReactions:o}=this;switch(r.state){case 2:if(0!==n.length)break;return this.call(e,t,e,s,r.value);case 3:if(0!==o.length)break;return this.call(e,t,t,i,r.reason)}n.push([e,t,e,s]),o.push([e,t,t,i])}resume(){const{status:e,fulfillReactions:t,rejectReactions:s}=this;switch(e.state){case 0:case 1:return;case 2:if(s.length>0&&(this.rejectReactions=[]),0===t.length)return;return this.react(t,e.value),void(this.fulfillReactions=[]);case 3:if(t.length>0&&(this.fulfillReactions=[]),0===s.length)return;return this.react(s,e.reason),void(this.rejectReactions=[])}}react(e,t){for(let s=0;s<e.length;++s){const i=e[s];this.call(i[0],i[1],i[2],i[3],t)}}call(e,t,s,i,r){if(!i)return s(r);try{e(i(r))}catch(e){t(e)}}}function h(e){return null!==e&&"object"==typeof e&&"function"==typeof e.then}function d(e){return a in e}s.Internal=l,s.isPromiseLike=h,s.never=new class e extends Promise{static get[Symbol.species](){return e}constructor(){super(c.noop)}then(){return this}catch(){return this}finally(){return this}}},{"./alias":3,"./global":10,"./noop":13}],15:[function(e,t,s){"use strict";Object.defineProperty(s,"__esModule",{value:!0}),s.tuple=void 0,s.tuple=function(...e){return e}},{}],16:[function(e,t,s){"use strict";Object.defineProperty(s,"__esModule",{value:!0}),s.isPrimitive=s.isType=s.type=void 0;const i=e("./alias"),r=Object.prototype.toString.call.bind(Object.prototype.toString),n=Object.prototype,o=Array.prototype;function c(e){if(void 0===e)return"undefined";if(null===e)return"null";const t=typeof e;if("object"===t){const t=(0,i.ObjectGetPrototypeOf)(e);return t===n||null===t?"Object":t===o?"Array":r(e).slice(8,-1)}return"function"===t?"Function":t}s.type=c,s.isType=function(e,t){return"object"===t?null!==e&&typeof e===t:"function"===t?typeof e===t:c(e)===t},s.isPrimitive=function(e){const t=typeof e;return"object"!==t&&"function"!==t||null===e}},{"./alias":3}],"dw-cache":[function(e,t,s){"use strict";var i=this&&this.__createBinding||(Object.create?function(e,t,s,i){void 0===i&&(i=s),Object.defineProperty(e,i,{enumerable:!0,get:function(){return t[s]}})}:function(e,t,s,i){void 0===i&&(i=s),e[i]=t[s]}),r=this&&this.__exportStar||function(e,t){for(var s in e)"default"===s||Object.prototype.hasOwnProperty.call(t,s)||i(t,e,s)};Object.defineProperty(s,"__esModule",{value:!0}),r(e("spica/cache"),s)},{"spica/cache":6}]},{},[1,2,"dw-cache"]),function(e,t){"function"==typeof define&&define.amd?define([],t):"object"==typeof module&&module.exports?module.exports=t():Object.assign(e,t())}("undefined"!=typeof self?self:this,function(){return require("dw-cache")}); |
{ | ||
"name": "dw-cache", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"description": "Dual window cache adaptively coordinates the ratio of LRU to LFU using the two sliding windows.", | ||
@@ -52,9 +52,8 @@ "private": false, | ||
"karma-mocha": "^2.0.1", | ||
"lru-cache": "^6.0.0", | ||
"mocha": "^8.3.0", | ||
"mocha": "^8.3.1", | ||
"npm-check-updates": "^11.1.10", | ||
"power-assert": "^1.6.1", | ||
"spica": "0.0.461", | ||
"spica": "0.0.462", | ||
"tsify": "^5.0.2", | ||
"typescript": "4.3.0-dev.20210304", | ||
"typescript": "4.3.0-dev.20210306", | ||
"vinyl-buffer": "^1.0.1", | ||
@@ -61,0 +60,0 @@ "vinyl-source-stream": "^2.0.0" |
@@ -14,59 +14,59 @@ # Dual Window Cache | ||
``` | ||
DEBUG: 'LRU hit rate even 100', 10.026 | ||
DEBUG: 'DWC hit rate even 100', 10.007 | ||
DEBUG: 'LFU ratio even 100', 83, 82 | ||
DEBUG: 'DWC / LRU hit rate ratio even 100', '99%' | ||
. | ||
DEBUG: 'LRU hit rate uneven 100', 18.526 | ||
DEBUG: 'DWC hit rate uneven 100', 37.309 | ||
DEBUG: 'LFU ratio uneven 100', 98, 97 | ||
DEBUG: 'DWC / LRU hit rate ratio uneven 100', '201%' | ||
. | ||
DEBUG: 'LRU hit rate uneven 100 transitive distribution', 18.466 | ||
DEBUG: 'DWC hit rate uneven 100 transitive distribution', 37.79 | ||
DEBUG: 'LFU ratio uneven 100 transitive distribution', 100, 97 | ||
DEBUG: 'DWC / LRU hit rate ratio uneven 100 transitive distribution', '204%' | ||
. | ||
DEBUG: 'LRU hit rate uneven 100 transitive bias', 17.526 | ||
DEBUG: 'DWC hit rate uneven 100 transitive bias', 16.659 | ||
DEBUG: 'LFU ratio uneven 100 transitive bias', 54, 54 | ||
DEBUG: 'DWC / LRU hit rate ratio uneven 100 transitive bias', '95%' | ||
. | ||
DEBUG: 'LRU hit rate uneven 100 sequential', 13.963 | ||
DEBUG: 'DWC hit rate uneven 100 sequential', 39.154 | ||
DEBUG: 'LFU ratio uneven 100 sequential', 100, 97 | ||
DEBUG: 'DWC / LRU hit rate ratio uneven 100 sequential', '280%' | ||
. | ||
DEBUG: 'LRU hit rate uneven 100 adversarial', 41.95 | ||
DEBUG: 'DWC hit rate uneven 100 adversarial', 42.615 | ||
DEBUG: 'LFU ratio uneven 100 adversarial', 10, 10 | ||
DEBUG: 'DWC / LRU hit rate ratio uneven 100 adversarial', '101%' | ||
'LRU hit rate even 100', 10.0265 | ||
'DWC hit rate even 100', 10.004 | ||
'LFU ratio even 100', 18, 17 | ||
'DWC / LRU hit rate ratio even 100', '99%' | ||
'LRU hit rate uneven 100', 18.64 | ||
'DWC hit rate uneven 100', 37.5535 | ||
'LFU ratio uneven 100', 100, 98 | ||
'DWC / LRU hit rate ratio uneven 100', '201%' | ||
'LRU hit rate uneven 100 transitive distribution', 18.4455 | ||
'DWC hit rate uneven 100 transitive distribution', 37.708 | ||
'LFU ratio uneven 100 transitive distribution', 99, 98 | ||
'DWC / LRU hit rate ratio uneven 100 transitive distribution', '204%' | ||
'LRU hit rate uneven 100 transitive bias', 17.566 | ||
'DWC hit rate uneven 100 transitive bias', 16.5355 | ||
'LFU ratio uneven 100 transitive bias', 55, 54 | ||
'DWC / LRU hit rate ratio uneven 100 transitive bias', '94%' | ||
'LRU hit rate uneven 100 sequential', 13.9335 | ||
'DWC hit rate uneven 100 sequential', 39.2995 | ||
'LFU ratio uneven 100 sequential', 100, 99 | ||
'DWC / LRU hit rate ratio uneven 100 sequential', '282%' | ||
'LRU hit rate uneven 100 adversarial', 42.0535 | ||
'DWC hit rate uneven 100 adversarial', 42.6685 | ||
'LFU ratio uneven 100 adversarial', 10, 10 | ||
'DWC / LRU hit rate ratio uneven 100 adversarial', '101%' | ||
``` | ||
https://github.com/falsandtru/spica/runs/2031763150 | ||
https://github.com/falsandtru/spica/runs/2046523894 | ||
### Benchmark (ops/sec) | ||
Slower x0.2-0.5 of [lru-cache](https://www.npmjs.com/package/lru-cache). | ||
Slower x0.1-0.5 of [lru-cache](https://www.npmjs.com/package/lru-cache). | ||
|Operation |dw-cache |lru-cache|Faster| | ||
|:-----------------|--------:|--------:|-----:| | ||
|set 100 (hit) | 14,363K | 8,945K | 60% | | ||
|set 1,000 (hit) | 14,536K | 8,095K | 79% | | ||
|set 10,000 (hit) | 13,677K | 8,323K | 64% | | ||
|set 100,000 (hit) | 9,465K | 6,783K | 39% | | ||
|set 100 (miss)| 4,450K | 5,358K | -17% | | ||
|set 1,000 (miss)| 4,015K | 5,776K | -8% | | ||
|set 10,000 (miss)| 2,551K | 2,748K | -8% | | ||
|set 100,000 (miss)| 1,373K | 1,882K | -28% | | ||
|get 100 (hit) | 8,424K | 16,010K | -48% | | ||
|get 1,000 (hit) | 10,060K | 14,447K | -31% | | ||
|get 10,000 (hit) | 10,537K | 13,663K | -23% | | ||
|get 100,000 (hit) | 7,943K | 10,285K | -23% | | ||
|get 100 (miss)| 25,818K | 25,416K | 1% | | ||
|get 1,000 (miss)| 24,149K | 22,475K | 7% | | ||
|get 10,000 (miss)| 24,027K | 22,894K | 4% | | ||
|get 100,000 (miss)| 13,773K | 13,194K | 4% | | ||
|set 100 (hit) | 10,604K | 7,172K | 47% | | ||
|set 1,000 (hit) | 9,833K | 6,756K | 45% | | ||
|set 10,000 (hit) | 11,168K | 6,618K | 68% | | ||
|set 100,000 (hit) | 6,263K | 5,364K | 16% | | ||
|set 100 (miss)| 3,592K | 5,101K | -30% | | ||
|set 1,000 (miss)| 3,263K | 4,571K | -29% | | ||
|set 10,000 (miss)| 2,026K | 2,462K | -18% | | ||
|set 100,000 (miss)| 1,163K | 1,387K | -17% | | ||
|get 100 (hit) | 7,130K | 12,999K | -46% | | ||
|get 1,000 (hit) | 9,022K | 11,545K | -12% | | ||
|get 10,000 (hit) | 9,215K | 10,954K | -16% | | ||
|get 100,000 (hit) | 6,505K | 7,082K | -9% | | ||
|get 100 (miss)| 20,872K | 19,983K | 4% | | ||
|get 1,000 (miss)| 18,974K | 18,196K | 4% | | ||
|get 10,000 (miss)| 20,027K | 17,870K | 12% | | ||
|get 100,000 (miss)| 10,543K | 9,738K | 8% | | ||
https://github.com/falsandtru/spica/runs/2031798638 | ||
https://github.com/falsandtru/spica/runs/2046532617 | ||
@@ -73,0 +73,0 @@ ## API |
Sorry, the diff of this file is too big to display
526245
29
12384