@creejs/commons-collection 2.0.3 → 2.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index-dev.cjs +656 -12
- package/dist/cjs/index-dev.cjs.map +1 -1
- package/dist/cjs/index-min.cjs +1 -1
- package/dist/cjs/index-min.cjs.map +1 -1
- package/dist/esm/index-dev.js +655 -13
- package/dist/esm/index-dev.js.map +1 -1
- package/dist/esm/index-min.js +1 -1
- package/dist/esm/index-min.js.map +1 -1
- package/dist/umd/index.dev.js +656 -12
- package/dist/umd/index.dev.js.map +1 -1
- package/dist/umd/index.min.js +1 -1
- package/dist/umd/index.min.js.map +1 -1
- package/package.json +1 -1
- package/types/fixed-linked-list.d.ts +59 -0
- package/types/hour24-time-wheel-cache.d.ts +6 -0
- package/types/index.d.ts +5 -1
- package/types/linked-list.d.ts +178 -0
- package/types/time-wheel-cache.d.ts +10 -3
package/dist/cjs/index-dev.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
function a$1(t){return "boolean"==typeof t}function c$1(t){return "function"==typeof t}function l$1(t){return null!=t&&"object"==typeof t&&!A(t)}function y(t){return null==t}function p$1(t){return !!m$1(t)&&t>0}function h$1(t){return !!m$1(t)&&t>=0}function g$1(t){return !!m$1(t)&&t<0}function w$1(t){return null===t}function d$1(t){return void 0===t}function m$1(t){return null!=t&&"number"==typeof t}function b$1(t){return null!=t&&"object"==typeof t}function A(t){return null!==t&&"object"==typeof t&&(t.constructor===Object||void 0===t.constructor)}function E(t){return null!=t&&"function"==typeof t.then}function N(t){return null!=t&&"string"==typeof t}function $(t){return null!=t&&"symbol"==typeof t}function O$1(t){return ArrayBuffer.isView(t)&&t.constructor!==DataView}function v$1(t){return t instanceof Int8Array}function
|
|
5
|
+
function a$1(t){return "boolean"==typeof t}function c$1(t){return "function"==typeof t}function l$1(t){return null!=t&&"object"==typeof t&&!A(t)}function y(t){return null==t}function p$1(t){return !!m$1(t)&&t>0}function h$1(t){return !!m$1(t)&&t>=0}function g$1(t){return !!m$1(t)&&t<0}function w$1(t){return null===t}function d$1(t){return void 0===t}function m$1(t){return null!=t&&"number"==typeof t}function b$1(t){return null!=t&&"object"==typeof t}function A(t){return null!==t&&"object"==typeof t&&(t.constructor===Object||void 0===t.constructor)}function E(t){return null!=t&&"function"==typeof t.then}function N(t){return null!=t&&"string"==typeof t}function $(t){return null!=t&&"symbol"==typeof t}function O$1(t){return ArrayBuffer.isView(t)&&t.constructor!==DataView}function v$1(t){return t instanceof Int8Array}function P(t){return t instanceof Uint8Array}function j(t){return t instanceof Uint8ClampedArray}function S(t){return t instanceof Int16Array}function x(t){return t instanceof Uint16Array}function U(t){return t instanceof Int32Array}function T(t){return t instanceof Uint32Array}function I(t){return t instanceof Float32Array}function B(t){return t instanceof Float64Array}function k$1(t){return t instanceof BigInt64Array}function L$1(t){return t instanceof BigUint64Array}function F(t){return t instanceof ArrayBuffer}var C={assertNumber:q,assertPositive:_$1,assertNegative:function(t,r){if(!g$1(t))throw new Error(`${r?'"'+r+'" ':""}Not Negative: ${t}`)},assertNotNegative:R,assertBoolean:function(t,r){if(!a$1(t))throw new Error(`${r?'"'+r+'" ':""}Not Boolean: type=${typeof t} value=${Z(t)}`)},assertObject:J,assertPlainObject:function(t,r){if(!A(t))throw new Error(`${r?'"'+r+'" ':""}Not PlainObject: type=${typeof t} value=${Z(t)}`)},assertSymbol:function(t,r){if(!$(t))throw new Error(`${r?'"'+r+'" ':""}Not Symbol: type=${typeof t} value=${Z(t)}`)},assertFunction:W,assertInstance:function(t,r){if(!l$1(t))throw new Error(`${r?'"'+r+'" ':""}Not Class Instance: type=${typeof t} value=${Z(t)}`)},assertPromise:H,assertNil:function(t,r){if(!y(t))throw new Error(`${r?'"'+r+'" ':""}Neither Null nor Undefined: type=${typeof t} value=${Z(t)}`)},assertNotNil:V,assertNull:function(t,r){if(!w$1(t))throw new Error(`${r?'"'+r+'" ':""}Not Null: type=${typeof t} value=${Z(t)}`)},assertNotNull:function(t,r){if(w$1(t))throw new Error((r?'"'+r+'" ':"")+"Should Not Null")},assertUndefined:function(t,r){if(!d$1(t))throw new Error(`${r?'"'+r+'" ':""}Not Undefined: type=${typeof t} value=${Z(t)}`)},assertString:D,assertArray:M,assertStringOrSymbol:function(t,r){if(!N(t)&&!$(t))throw new Error(`${r?'"'+r+'" ':""}Not String or Symbol: type=${typeof t} value=${Z(t)}`)},assertInt8Array:function(t,r){if(v$1(t))throw new Error((r?'"'+r+'" ':"")+"Not Int8Array")},assertUint8Array:function(t,r){if(P(t))throw new Error((r?'"'+r+'" ':"")+"Not Uint8Array")},assertUint8ClampedArray:function(t,r){if(j(t))throw new Error((r?'"'+r+'" ':"")+"Not Uint8ClampedArray")},assertInt16Array:function(t,r){if(S(t))throw new Error((r?'"'+r+'" ':"")+"Not Int16Array")},assertUint16Array:function(t,r){if(x(t))throw new Error((r?'"'+r+'" ':"")+"Not Uint16Array")},assertInt32Array:function(t,r){if(U(t))throw new Error((r?'"'+r+'" ':"")+"Not Int32Array")},assertUint32Array:function(t,r){if(T(t))throw new Error((r?'"'+r+'" ':"")+"Not Uint32Array")},assertFloat32Array:function(t,r){if(I(t))throw new Error((r?'"'+r+'" ':"")+"Not Float32Array")},assertFloat64Array:function(t,r){if(B(t))throw new Error((r?'"'+r+'" ':"")+"Not Float64Array")},assertBigInt64Array:function(t,r){if(k$1(t))throw new Error((r?'"'+r+'" ':"")+"Not BigInt64Array")},assertBigUint64Array:function(t,r){if(L$1(t))throw new Error((r?'"'+r+'" ':"")+"Not BigUint64Array")},assertTypedArray:function(t,r){if(O$1(t))throw new Error((r?'"'+r+'" ':"")+"Not TypedArray")},assertArrayBuffer:z};function M(t,r){if(!Array.isArray(t))throw new Error(`${r?'"'+r+'" ':""}Not Array: type=${typeof t} value=${Z(t)}`)}function D(t,r){if(!N(t))throw new Error(`${r?'"'+r+'" ':""}Not String: type=${typeof t} value=${Z(t)}`)}function q(t,r){if(!m$1(t))throw new Error(`${r?'"'+r+'" ':""}Not Number: type=${typeof t} value=${Z(t)}`)}function _$1(t,r){if(!p$1(t))throw new Error(`${r?'"'+r+'" ':""}Not Positive: ${t}`)}function R(t,r){if(!h$1(t))throw new Error(`${r?'"'+r+'" ':""}Not "0 or Positive": ${t}`)}function J(t,r){if(!b$1(t))throw new Error(`${r?'"'+r+'" ':""}Not Object: type=${typeof t} value=${Z(t)}`)}function W(t,r){if(!c$1(t))throw new Error(`${r?'"'+r+'" ':""}Not Function: type=${typeof t} value=${Z(t)}`)}function H(t,r){if(!E(t))throw new Error(`${r?'"'+r+'" ':""}Not Promise: type=${typeof t} value=${Z(t)}`)}function V(t,r){if(y(t))throw new Error((r?'"'+r+'" ':"")+"Should Not Nil")}function z(t,r){if(!F(t))throw new Error((r?'"'+r+'" ':"")+"Not ArrayBuffer")}var G={isEmpty:K,assertNotEmpty:Y,isBlank:Q,assertNotBlank:function(t,r){if(Q(t))throw new Error(`${r?'"'+r+'" ':""}Is Blank: ${t}`)},capitalize:function(t){if(D(t),0===t.length)return t;const r=t.charAt(0),e=r.toUpperCase();return r===e?t:e+t.slice(1)},decapitalize:function(t){if(D(t),0===t.length)return t;const r=t.charAt(0),e=r.toLowerCase();return r===e?t:e+t.slice(1)},splitWithFixedLength:function(t,r,e=" "){if(D(t),q(r),D(e),0===t.length)return [];if(r<=0)throw new Error("length muse >=0");if(t.length<r)return [t.padEnd(r,e)];const n=[];for(let o=0;o<t.length;o+=r){const i=t.substring(o,o+r);n.push(i.padEnd(r,e));}return n},split:function(t,...r){D(t);if(0===t.length)return [];const e=[...r];0===r.length&&r.push(",");const n=X(t,...e);if(0===n.length)return [];const o=[];let i="",s=0;for(const{marker:r,index:e}of n)i=t.substring(s,e),o.push(i),s=e+r.length;return i=t.substring(s),o.push(i),o},findMarkerPositions:function(t,...r){if(D(t),0===r.length)throw new Error("At least one marker must be provided");const e=[];for(const n of new Set(r)){if(K(n))continue;D(n);let r=t.indexOf(n);for(;-1!==r;)e.push({marker:n,index:r}),r=t.indexOf(n,r+n.length);}return e.sort((t,r)=>t.index-r.index),e},findMarkerPositionsRegex:X,substringBefore:function(t,r){if(D(t),D(r),0===t.length||0===r.length)return;const e=t.indexOf(r);if(-1===e)return;return t.substring(0,e)},substringBeforeLast:function(t,r){if(D(t),D(r),0===t.length||0===r.length)return;const e=t.lastIndexOf(r);if(-1===e)return;return t.substring(0,e)},substringAfter:function(t,r){if(D(t),D(r),0===t.length||0===r.length)return;const e=t.indexOf(r);if(-1===e)return;return t.substring(e+r.length)},substringAfterLast:function(t,r){if(D(t),D(r),0===t.length||0===r.length)return;const e=t.lastIndexOf(r);if(-1===e)return;return t.substring(e+r.length)},substringBetween:function(t,r,e){Y(t),Y(r),Y(e);const n=t.indexOf(r);if(-1===n)return;const o=t.indexOf(e,n+r.length);if(-1===o)return;return t.substring(n+r.length,o)},substringBetweenGreedy:function(t,r,e){Y(t),Y(r),Y(e);const n=t.indexOf(r);if(-1===n)return;const o=t.lastIndexOf(e);if(-1===o||o<=n)return;return t.substring(n+r.length,o)},substringsBetween:function(t,r,e){Y(t),Y(r),Y(e);const n=[];let o=0;for(;;){const i=t.indexOf(r,o);if(-1===i)break;const s=t.indexOf(e,i+r.length);if(-1===s)break;n.push(t.substring(i+r.length,s)),o=s+e.length;}return n},safeToString:Z};function K(t){return null==t||(D(t),0===t.length)}function Y(t,r){if(K(t))throw new Error(`${r?'"'+r+'" ':""}IsEmpty String: ${t}`)}function Q(t){return null==t||(D(t),0===t.trim().length)}function X(t,...r){if(D(t),0===r.length)throw new Error("At least one marker must be provided");const e=[...new Set(r.filter(t=>null!=t))].map(t=>(D(t),t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"))),n=new RegExp(e.map(t=>`(${t})`).join("|"),"g"),o=[];let i=null;for(;null!==(i=n.exec(t));){for(let t=1;t<i.length;t++)if(i[t]){o.push({marker:r[t-1],index:i.index});break}0===i[0].length&&n.lastIndex++;}return o}function Z(t){if(null===t)return "null";if(void 0===t)return "undefined";const r=typeof t;if("string"===r)return t;if("symbol"===r)return `Symbol(${t.description})`;if("function"===r)return `Function ${t.name}(){}`;if(t instanceof String)return t.toString();if(Number.isNaN(t))return "NaN";if(t===1/0)return "Infinity";if(t===-1/0)return "-Infinity";if(t instanceof Error)return `${t.constructor.name}: ${t.message}`;if(t instanceof Promise)return "Promise";if(t instanceof Set)return `Set: ${Z(Array.from(t))}`;if(t instanceof Map)return `Map: ${Z(Array.from(t.entries()))}`;if(t instanceof RegExp)return t.toString();if(Array.isArray(t))return `[${t.map(Z).join(", ")}]`;let e;try{e=JSON.stringify(t);}catch(r){e=t.toString();}return e}new TextDecoder;new TextEncoder;const dt=1e6;var mt={s2ns:1e9,ms2ns:dt,timestamp:function(){if("undefined"!=typeof performance&&"number"==typeof performance.timeOrigin){const t=performance.timeOrigin,r=performance.now();return Math.ceil((t+r)/dt)}return Date.now()},timestamp64:bt,lapseNano:At,lapseMillis:Et,timeoutNano:function(t,r){return At(t)>r},timeoutMillis:function(t,r){return Et(t)>r}};function bt(){if("undefined"!=typeof performance&&"number"==typeof performance.timeOrigin){const t=performance.timeOrigin,r=performance.now();return BigInt((t+r)*dt)}return BigInt(Date.now()*dt)}function At(t,r){return (r??bt())-t}function Et(t,r){r=r??bt();return BigInt(r-t)/BigInt(dt)}
|
|
6
6
|
|
|
7
7
|
// internal
|
|
8
8
|
// owned
|
|
@@ -16,7 +16,7 @@ function a$1(t){return "boolean"==typeof t}function c$1(t){return "function"==ty
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
// module vars
|
|
19
|
-
const { assertPositive } = C;
|
|
19
|
+
const { assertPositive: assertPositive$1 } = C;
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* A set that has a fixed capacity and automatically removes the oldest element when the capacity is reached.
|
|
@@ -31,7 +31,7 @@ class CappedSet {
|
|
|
31
31
|
* @throws {Error} If capacity is less than or equal to 0
|
|
32
32
|
*/
|
|
33
33
|
constructor (capacity) {
|
|
34
|
-
assertPositive(capacity, 'capacity');
|
|
34
|
+
assertPositive$1(capacity, 'capacity');
|
|
35
35
|
this.capacity = capacity;
|
|
36
36
|
/**
|
|
37
37
|
* 1. key is the Value stored in CappedSet
|
|
@@ -184,8 +184,9 @@ var e={isFunction:t,isNil:s};function t(e){return "function"==typeof e}function
|
|
|
184
184
|
/**
|
|
185
185
|
* @typedef {number} Timestamp
|
|
186
186
|
* @typedef {{
|
|
187
|
-
*
|
|
188
|
-
*
|
|
187
|
+
* autoStart?:boolean, // default true
|
|
188
|
+
* tickInterval?: number, // ms
|
|
189
|
+
* tickCount?: number // ms
|
|
189
190
|
* }} TimeWheelCacheOptions
|
|
190
191
|
*/
|
|
191
192
|
|
|
@@ -222,6 +223,11 @@ class TimeWheelCache extends k {
|
|
|
222
223
|
* How many Ticks does the Wheel have
|
|
223
224
|
*/
|
|
224
225
|
this._tickCount = this.options.tickCount ?? 60;
|
|
226
|
+
/**
|
|
227
|
+
* Whether auto start "AutoEvict"
|
|
228
|
+
* @type {boolean}
|
|
229
|
+
*/
|
|
230
|
+
this._autoStart = this.options.autoStart ?? true;
|
|
225
231
|
/**
|
|
226
232
|
* Slots, one Tick owns one Slot to store key and expire timestamp
|
|
227
233
|
* @type {Map<any, {value: any, slotIndex: number, expireTimestamp: number}>[]}
|
|
@@ -237,7 +243,7 @@ class TimeWheelCache extends k {
|
|
|
237
243
|
this._timer = undefined;
|
|
238
244
|
|
|
239
245
|
// must start it immediately
|
|
240
|
-
this._startAutoEvict();
|
|
246
|
+
this._autoStart && this._startAutoEvict();
|
|
241
247
|
}
|
|
242
248
|
|
|
243
249
|
get tickInterval () {
|
|
@@ -269,6 +275,10 @@ class TimeWheelCache extends k {
|
|
|
269
275
|
return this._timer != null
|
|
270
276
|
}
|
|
271
277
|
|
|
278
|
+
get autoStart () {
|
|
279
|
+
return this._autoStart
|
|
280
|
+
}
|
|
281
|
+
|
|
272
282
|
_startAutoEvict () {
|
|
273
283
|
this._timer = setInterval(() => this._advance(), this._tickInterval);
|
|
274
284
|
}
|
|
@@ -388,7 +398,7 @@ class TimeWheelCache extends k {
|
|
|
388
398
|
}
|
|
389
399
|
if (wrapped.expireTimestamp <= mt.timestamp()) {
|
|
390
400
|
this.delete(key);
|
|
391
|
-
this.emit(
|
|
401
|
+
this.emit(Event$1.Expired, key, wrapped.value, wrapped.expireTimestamp);
|
|
392
402
|
return false
|
|
393
403
|
}
|
|
394
404
|
return true
|
|
@@ -478,8 +488,9 @@ class Hour24TimeWheelCache extends k {
|
|
|
478
488
|
/**
|
|
479
489
|
*
|
|
480
490
|
*/
|
|
481
|
-
constructor () {
|
|
491
|
+
constructor (autoStart = true) {
|
|
482
492
|
super();
|
|
493
|
+
this._autoStart = autoStart ?? true;
|
|
483
494
|
/**
|
|
484
495
|
* Second Wheel:
|
|
485
496
|
* 1. 1 Tick Mark is 1 Second, is 1000 Milliseconds
|
|
@@ -490,7 +501,7 @@ class Hour24TimeWheelCache extends k {
|
|
|
490
501
|
* * 60 00:00:59.XXX -> 00:00:59.XXX in Slot60 Index59
|
|
491
502
|
* @type {TimeWheelCache}
|
|
492
503
|
*/
|
|
493
|
-
this._secondWheel = new TimeWheelCache({ tickInterval: SecondInMillisecond, tickCount: 60 });
|
|
504
|
+
this._secondWheel = new TimeWheelCache({ tickInterval: SecondInMillisecond, tickCount: 60, autoStart });
|
|
494
505
|
/**
|
|
495
506
|
* Minute Wheel:
|
|
496
507
|
* 1. 1 Tick Mark is 1 Minute, is 60 * 1000 Milliseconds
|
|
@@ -500,7 +511,7 @@ class Hour24TimeWheelCache extends k {
|
|
|
500
511
|
* * 60 00:59:00 -> 00:59:59 in Slot60 Index59
|
|
501
512
|
* @type {TimeWheelCache}
|
|
502
513
|
*/
|
|
503
|
-
this._minuteWheel = new TimeWheelCache({ tickInterval: MinuteInMillisecond, tickCount: 60 });
|
|
514
|
+
this._minuteWheel = new TimeWheelCache({ tickInterval: MinuteInMillisecond, tickCount: 60, autoStart });
|
|
504
515
|
/**
|
|
505
516
|
* Hour Wheel:
|
|
506
517
|
* 1. 1 Tick Mark is 1 Hour, is 60 * 60 * 1000 Milliseconds
|
|
@@ -510,7 +521,7 @@ class Hour24TimeWheelCache extends k {
|
|
|
510
521
|
* * 24 23:00:00 -> 23:59:59 in Slot23 Index23
|
|
511
522
|
* @type {TimeWheelCache}
|
|
512
523
|
*/
|
|
513
|
-
this._hourWheel = new TimeWheelCache({ tickInterval: HourInMillisecond, tickCount: 24 });
|
|
524
|
+
this._hourWheel = new TimeWheelCache({ tickInterval: HourInMillisecond, tickCount: 24, autoStart });
|
|
514
525
|
/**
|
|
515
526
|
* @type {Map<any, TimeWheelCache>}
|
|
516
527
|
*/
|
|
@@ -530,6 +541,10 @@ class Hour24TimeWheelCache extends k {
|
|
|
530
541
|
return this._secondWheel.autoEvictRunning || this._minuteWheel.autoEvictRunning || this._hourWheel.autoEvictRunning
|
|
531
542
|
}
|
|
532
543
|
|
|
544
|
+
get autoStart () {
|
|
545
|
+
return this._autoStart
|
|
546
|
+
}
|
|
547
|
+
|
|
533
548
|
_init () {
|
|
534
549
|
/**
|
|
535
550
|
* 1. We don't store "Timetick: < 00:00:01 -> 00:59:59" into HourWheel, instead, we store them into MinuteWheel
|
|
@@ -707,10 +722,639 @@ class Hour24TimeWheelCache extends k {
|
|
|
707
722
|
}
|
|
708
723
|
}
|
|
709
724
|
|
|
710
|
-
|
|
725
|
+
// internal
|
|
726
|
+
// owned
|
|
727
|
+
|
|
728
|
+
/**
|
|
729
|
+
* @typedef {{
|
|
730
|
+
* value: any,
|
|
731
|
+
* prev: Node|undefined,
|
|
732
|
+
* next: Node|undefined
|
|
733
|
+
* }} Node
|
|
734
|
+
*/
|
|
735
|
+
|
|
736
|
+
// module vars
|
|
737
|
+
const { assertNotNegative } = C;
|
|
738
|
+
|
|
739
|
+
/**
|
|
740
|
+
* A doubly linked list implementation.
|
|
741
|
+
*
|
|
742
|
+
* @class LinkedList
|
|
743
|
+
*/
|
|
744
|
+
class LinkedList {
|
|
745
|
+
/**
|
|
746
|
+
* Creates a new LinkedList instance.
|
|
747
|
+
* @constructor
|
|
748
|
+
*/
|
|
749
|
+
constructor () {
|
|
750
|
+
/**
|
|
751
|
+
* @type {Node|undefined}
|
|
752
|
+
*/
|
|
753
|
+
this._head = undefined;
|
|
754
|
+
/**
|
|
755
|
+
* @type {Node|undefined}
|
|
756
|
+
*/
|
|
757
|
+
this._tail = undefined;
|
|
758
|
+
/**
|
|
759
|
+
* @type {number}
|
|
760
|
+
*/
|
|
761
|
+
this._size = 0;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
get size () {
|
|
765
|
+
return this._size
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* get the first element
|
|
770
|
+
*/
|
|
771
|
+
get first () {
|
|
772
|
+
return this._head?.value
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/**
|
|
776
|
+
* get the last element
|
|
777
|
+
*/
|
|
778
|
+
get last () {
|
|
779
|
+
return this._tail?.value
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
[Symbol.iterator] () {
|
|
783
|
+
let current = this._head;
|
|
784
|
+
const iterator = {
|
|
785
|
+
next () {
|
|
786
|
+
if (current) {
|
|
787
|
+
const value = current.value;
|
|
788
|
+
current = current.next;
|
|
789
|
+
return { value, done: false }
|
|
790
|
+
}
|
|
791
|
+
return { value: undefined, done: true }
|
|
792
|
+
},
|
|
793
|
+
[Symbol.iterator] () {
|
|
794
|
+
return this
|
|
795
|
+
}
|
|
796
|
+
};
|
|
797
|
+
return iterator
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
/**
|
|
801
|
+
* Adds a value to the beginning of the linked list.
|
|
802
|
+
* @param {*} value - The value to add
|
|
803
|
+
* @returns {LinkedList} This linked list instance for chaining
|
|
804
|
+
*/
|
|
805
|
+
addFirst (value) {
|
|
806
|
+
/**
|
|
807
|
+
* @type {Node}
|
|
808
|
+
*/
|
|
809
|
+
const node = { value, prev: undefined, next: this._head };
|
|
810
|
+
|
|
811
|
+
if (this._head) {
|
|
812
|
+
this._head.prev = node;
|
|
813
|
+
} else {
|
|
814
|
+
this._tail = node;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
this._head = node;
|
|
818
|
+
this._size++;
|
|
819
|
+
return this
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* Adds a value to the end of the linked list.
|
|
824
|
+
* @param {*} value - The value to add
|
|
825
|
+
* @returns {LinkedList} This linked list instance for chaining
|
|
826
|
+
*/
|
|
827
|
+
addLast (value) {
|
|
828
|
+
/**
|
|
829
|
+
* @type {Node}
|
|
830
|
+
*/
|
|
831
|
+
const node = { value, prev: this._tail, next: undefined };
|
|
832
|
+
|
|
833
|
+
if (this._tail) {
|
|
834
|
+
this._tail.next = node;
|
|
835
|
+
} else {
|
|
836
|
+
this._head = node;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
this._tail = node;
|
|
840
|
+
this._size++;
|
|
841
|
+
return this
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* Adds a value to the end of the linked list.
|
|
846
|
+
* @param {*} value - The value to add
|
|
847
|
+
* @returns {LinkedList} This linked list instance for chaining
|
|
848
|
+
*/
|
|
849
|
+
add (value) {
|
|
850
|
+
return this.addLast(value)
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
/**
|
|
854
|
+
* Removes and returns the first element from the linked list.
|
|
855
|
+
* @returns {*} The removed value, or undefined if the list is empty
|
|
856
|
+
*/
|
|
857
|
+
removeFirst () {
|
|
858
|
+
if (!this._head) {
|
|
859
|
+
return undefined
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
const value = this._head.value;
|
|
863
|
+
this._head = this._head.next;
|
|
864
|
+
|
|
865
|
+
if (this._head) {
|
|
866
|
+
this._head.prev = undefined;
|
|
867
|
+
} else {
|
|
868
|
+
this._tail = undefined;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
this._size--;
|
|
872
|
+
return value
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* Removes and returns the last element from the linked list.
|
|
877
|
+
* @returns {*} The removed value, or undefined if the list is empty
|
|
878
|
+
*/
|
|
879
|
+
removeLast () {
|
|
880
|
+
if (!this._tail) {
|
|
881
|
+
return undefined
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
const value = this._tail.value;
|
|
885
|
+
this._tail = this._tail.prev;
|
|
886
|
+
|
|
887
|
+
if (this._tail) {
|
|
888
|
+
this._tail.next = undefined;
|
|
889
|
+
} else {
|
|
890
|
+
this._head = undefined;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
this._size--;
|
|
894
|
+
return value
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
* Removes the first occurrence of the specified value from the linked list.
|
|
899
|
+
* @param {*} value - The value to remove
|
|
900
|
+
* @param {function(*, *): boolean} [comparator] - Optional comparison function (a, b) => boolean
|
|
901
|
+
* @returns {boolean} True if the value was found and removed, false otherwise
|
|
902
|
+
*/
|
|
903
|
+
remove (value, comparator) {
|
|
904
|
+
const compare = comparator || this._defaultComparator;
|
|
905
|
+
let current = this._head;
|
|
906
|
+
|
|
907
|
+
while (current) {
|
|
908
|
+
if (compare(current.value, value)) {
|
|
909
|
+
this._removeNode(current);
|
|
910
|
+
return true
|
|
911
|
+
}
|
|
912
|
+
current = current.next;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
return false
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
/**
|
|
919
|
+
* Removes all occurrences of the specified value from the linked list.
|
|
920
|
+
* @param {*} value - The value to remove
|
|
921
|
+
* @param {function(*, *): boolean} [comparator] - Optional comparison function (a, b) => boolean
|
|
922
|
+
* @returns {number} The number of elements removed
|
|
923
|
+
*/
|
|
924
|
+
removeAll (value, comparator) {
|
|
925
|
+
const compare = comparator || this._defaultComparator;
|
|
926
|
+
let removedCount = 0;
|
|
927
|
+
let current = this._head;
|
|
928
|
+
|
|
929
|
+
while (current) {
|
|
930
|
+
const next = current.next; // Store next before potential removal
|
|
931
|
+
if (compare(current.value, value)) {
|
|
932
|
+
this._removeNode(current);
|
|
933
|
+
removedCount++;
|
|
934
|
+
}
|
|
935
|
+
current = next;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
return removedCount
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
/**
|
|
942
|
+
* Removes the element at the specified index.
|
|
943
|
+
* @param {number} index - The index of the element to remove
|
|
944
|
+
* @returns {*} The removed value, or undefined if index is out of bounds
|
|
945
|
+
*/
|
|
946
|
+
removeAt (index) {
|
|
947
|
+
assertNotNegative(index, 'index');
|
|
948
|
+
|
|
949
|
+
if (index >= this._size) {
|
|
950
|
+
return undefined
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
if (index === 0) {
|
|
954
|
+
return this.removeFirst()
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
if (index === this._size - 1) {
|
|
958
|
+
return this.removeLast()
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
let current = this._head;
|
|
962
|
+
for (let i = 0; i < index; i++) {
|
|
963
|
+
current = current?.next;
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
if (current) {
|
|
967
|
+
const value = current.value;
|
|
968
|
+
this._removeNode(current);
|
|
969
|
+
return value
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
return undefined
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
/**
|
|
976
|
+
* Checks if the linked list contains the specified value.
|
|
977
|
+
* @param {*} value - The value to check for
|
|
978
|
+
* @param {function(*, *): boolean} [comparator] - Optional comparison function (a, b) => boolean
|
|
979
|
+
* @returns {boolean} True if the value exists, false otherwise
|
|
980
|
+
*/
|
|
981
|
+
contains (value, comparator) {
|
|
982
|
+
const compare = comparator || this._defaultComparator;
|
|
983
|
+
let current = this._head;
|
|
984
|
+
while (current) {
|
|
985
|
+
if (compare(current.value, value)) {
|
|
986
|
+
return true
|
|
987
|
+
}
|
|
988
|
+
current = current.next;
|
|
989
|
+
}
|
|
990
|
+
return false
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
/**
|
|
994
|
+
* Returns the index of the first occurrence of the specified value.
|
|
995
|
+
* @param {*} value - The value to find
|
|
996
|
+
* @param {function(*, *): boolean} [comparator] - Optional comparison function (a, b) => boolean
|
|
997
|
+
* @returns {number} The index of the value, or -1 if not found
|
|
998
|
+
*/
|
|
999
|
+
indexOf (value, comparator) {
|
|
1000
|
+
const compare = comparator || this._defaultComparator;
|
|
1001
|
+
let current = this._head;
|
|
1002
|
+
let index = 0;
|
|
1003
|
+
while (current) {
|
|
1004
|
+
if (compare(current.value, value)) {
|
|
1005
|
+
return index
|
|
1006
|
+
}
|
|
1007
|
+
current = current.next;
|
|
1008
|
+
index++;
|
|
1009
|
+
}
|
|
1010
|
+
return -1
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
/**
|
|
1014
|
+
* Returns the index of the last occurrence of the specified value.
|
|
1015
|
+
* @param {*} value - The value to find
|
|
1016
|
+
* @param {function(*, *): boolean} [comparator] - Optional comparison function (a, b) => boolean
|
|
1017
|
+
* @returns {number} The index of the last occurrence, or -1 if not found
|
|
1018
|
+
*/
|
|
1019
|
+
indexLastOf (value, comparator) {
|
|
1020
|
+
const compare = comparator || this._defaultComparator;
|
|
1021
|
+
let current = this._tail;
|
|
1022
|
+
let index = this._size - 1;
|
|
1023
|
+
while (current) {
|
|
1024
|
+
if (compare(current.value, value)) {
|
|
1025
|
+
return index
|
|
1026
|
+
}
|
|
1027
|
+
current = current.prev;
|
|
1028
|
+
index--;
|
|
1029
|
+
}
|
|
1030
|
+
return -1
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
/**
|
|
1034
|
+
* Gets the value at the specified index.
|
|
1035
|
+
* @param {number} index - The index of the value to get
|
|
1036
|
+
* @returns {*} The value at the index, or undefined if index is out of bounds
|
|
1037
|
+
*/
|
|
1038
|
+
get (index) {
|
|
1039
|
+
assertNotNegative(index, 'index');
|
|
1040
|
+
|
|
1041
|
+
if (index >= this._size) {
|
|
1042
|
+
return undefined
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
let current = this._head;
|
|
1046
|
+
for (let i = 0; i < index; i++) {
|
|
1047
|
+
current = current?.next;
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
return current?.value
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
/**
|
|
1054
|
+
* Inserts a value at the specified index.
|
|
1055
|
+
* @param {number} index - The index at which to insert the value
|
|
1056
|
+
* @param {*} value - The value to insert
|
|
1057
|
+
* @returns {LinkedList} This linked list instance for chaining
|
|
1058
|
+
*/
|
|
1059
|
+
insertAt (index, value) {
|
|
1060
|
+
assertNotNegative(index, 'index');
|
|
1061
|
+
|
|
1062
|
+
if (index === 0) {
|
|
1063
|
+
return this.addFirst(value)
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
if (index >= this._size) {
|
|
1067
|
+
return this.addLast(value)
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
let current = this._head;
|
|
1071
|
+
for (let i = 0; i < index - 1; i++) {
|
|
1072
|
+
current = current?.next;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
if (current) {
|
|
1076
|
+
/**
|
|
1077
|
+
* @type {Node}
|
|
1078
|
+
*/
|
|
1079
|
+
const node = { value, prev: current, next: current.next };
|
|
1080
|
+
if (current.next) {
|
|
1081
|
+
current.next.prev = node;
|
|
1082
|
+
}
|
|
1083
|
+
current.next = node;
|
|
1084
|
+
this._size++;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
return this
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
/**
|
|
1091
|
+
* Removes all elements from the linked list.
|
|
1092
|
+
*/
|
|
1093
|
+
clear () {
|
|
1094
|
+
this._head = undefined;
|
|
1095
|
+
this._tail = undefined;
|
|
1096
|
+
this._size = 0;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
/**
|
|
1100
|
+
* Returns an array containing all the values in the linked list.
|
|
1101
|
+
* @returns {any[]} An array of all values
|
|
1102
|
+
*/
|
|
1103
|
+
toArray () {
|
|
1104
|
+
const result = [];
|
|
1105
|
+
let current = this._head;
|
|
1106
|
+
while (current) {
|
|
1107
|
+
result.push(current.value);
|
|
1108
|
+
current = current.next;
|
|
1109
|
+
}
|
|
1110
|
+
return result
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
/**
|
|
1114
|
+
* Returns an iterator of the values in the linked list.
|
|
1115
|
+
* @returns {Iterator<any>} An iterator object that yields the values of the linked list
|
|
1116
|
+
*/
|
|
1117
|
+
values () {
|
|
1118
|
+
return this[Symbol.iterator]()
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
/**
|
|
1122
|
+
* Returns a slice of the linked list as an array.
|
|
1123
|
+
* @param {number} [start=0] - The start index (inclusive). If negative, counts from the end.
|
|
1124
|
+
* @param {number} [end=this.size] - The end index (exclusive). If negative, counts from the end.
|
|
1125
|
+
* @returns {any[]} An array containing the sliced elements
|
|
1126
|
+
*/
|
|
1127
|
+
slice (start = 0, end = this.size) {
|
|
1128
|
+
// Handle negative indices
|
|
1129
|
+
const normalizedStart = start < 0 ? Math.max(this.size + start, 0) : Math.min(start, this.size);
|
|
1130
|
+
const normalizedEnd = end < 0 ? Math.max(this.size + end, 0) : Math.min(end, this.size);
|
|
1131
|
+
|
|
1132
|
+
if (normalizedStart >= normalizedEnd) {
|
|
1133
|
+
return []
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
if (start < 0) {
|
|
1137
|
+
return this._sliceNegative(normalizedStart, normalizedEnd)
|
|
1138
|
+
} else {
|
|
1139
|
+
return this._slicePositive(normalizedStart, normalizedEnd)
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
/**
|
|
1144
|
+
* Returns a string representation of the FixedLinkedList.
|
|
1145
|
+
* @returns {string} String representation
|
|
1146
|
+
*/
|
|
1147
|
+
toString () {
|
|
1148
|
+
const partialElements = this.slice(0, 3);
|
|
1149
|
+
const partialString = this.size > 3 ? G.safeToString(partialElements) + '...' : G.safeToString(partialElements);
|
|
1150
|
+
return `LinkedList[${this.size}](${partialString})`
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
/**
|
|
1154
|
+
* Slice implementation for positive indices (iterates from head to tail)
|
|
1155
|
+
* @param {number} start - Normalized start index (inclusive)
|
|
1156
|
+
* @param {number} end - Normalized end index (exclusive)
|
|
1157
|
+
* @returns {any[]} An array containing the sliced elements
|
|
1158
|
+
* @private
|
|
1159
|
+
*/
|
|
1160
|
+
_slicePositive (start, end) {
|
|
1161
|
+
const result = [];
|
|
1162
|
+
let current = this._head;
|
|
1163
|
+
let index = 0;
|
|
1164
|
+
|
|
1165
|
+
// Move to the starting position
|
|
1166
|
+
while (current && index < start) {
|
|
1167
|
+
current = current.next;
|
|
1168
|
+
index++;
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
// Collect elements from start to end
|
|
1172
|
+
while (current && index < end) {
|
|
1173
|
+
result.push(current.value);
|
|
1174
|
+
current = current.next;
|
|
1175
|
+
index++;
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
return result
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
/**
|
|
1182
|
+
* Slice implementation for negative indices (iterates from tail to head)
|
|
1183
|
+
* @param {number} start - Normalized start index (inclusive)
|
|
1184
|
+
* @param {number} end - Normalized end index (exclusive)
|
|
1185
|
+
* @returns {any[]} An array containing the sliced elements
|
|
1186
|
+
* @private
|
|
1187
|
+
*/
|
|
1188
|
+
_sliceNegative (start, end) {
|
|
1189
|
+
const result = [];
|
|
1190
|
+
let current = this._tail;
|
|
1191
|
+
let index = this.size - 1;
|
|
1192
|
+
|
|
1193
|
+
// Move to the starting position
|
|
1194
|
+
while (current && index > start) {
|
|
1195
|
+
current = current.prev;
|
|
1196
|
+
index--;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
// Collect elements from start to end
|
|
1200
|
+
while (current && index < end) {
|
|
1201
|
+
result.push(current.value);
|
|
1202
|
+
current = current.next;
|
|
1203
|
+
index++;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
return result
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
/**
|
|
1210
|
+
* Removes a node from the linked list.
|
|
1211
|
+
* @param {Node} node - The node to be removed
|
|
1212
|
+
* @private
|
|
1213
|
+
*/
|
|
1214
|
+
_removeNode (node) {
|
|
1215
|
+
if (node.prev) {
|
|
1216
|
+
node.prev.next = node.next;
|
|
1217
|
+
} else {
|
|
1218
|
+
this._head = node.next;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
if (node.next) {
|
|
1222
|
+
node.next.prev = node.prev;
|
|
1223
|
+
} else {
|
|
1224
|
+
this._tail = node.prev;
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
this._size--;
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
/**
|
|
1231
|
+
* Default comparator for strict equality comparison.
|
|
1232
|
+
* @param {*} a - First value to compare
|
|
1233
|
+
* @param {*} b - Second value to compare
|
|
1234
|
+
* @returns {boolean} True if values are strictly equal
|
|
1235
|
+
* @private
|
|
1236
|
+
*/
|
|
1237
|
+
_defaultComparator (a, b) {
|
|
1238
|
+
return a === b
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
// internal
|
|
1243
|
+
// owned
|
|
1244
|
+
|
|
1245
|
+
// module vars
|
|
1246
|
+
const { assertPositive } = C;
|
|
1247
|
+
|
|
1248
|
+
/**
|
|
1249
|
+
* A fixed-capacity linked list that automatically removes elements when capacity is exceeded.
|
|
1250
|
+
* When adding to the end (addLast), it removes the first element if capacity is full.
|
|
1251
|
+
* When adding to the beginning (addFirst), it removes the last element if capacity is full.
|
|
1252
|
+
*
|
|
1253
|
+
* @class FixedLinkedList
|
|
1254
|
+
* @extends LinkedList
|
|
1255
|
+
*/
|
|
1256
|
+
class FixedLinkedList extends LinkedList {
|
|
1257
|
+
/**
|
|
1258
|
+
* Creates a new FixedLinkedList instance with a fixed capacity.
|
|
1259
|
+
* @constructor
|
|
1260
|
+
* @param {number} capacity - The maximum number of elements the list can hold (must be > 0)
|
|
1261
|
+
* @throws {Error} If capacity is less than or equal to 0
|
|
1262
|
+
*/
|
|
1263
|
+
constructor (capacity) {
|
|
1264
|
+
assertPositive(capacity, 'capacity');
|
|
1265
|
+
super();
|
|
1266
|
+
this.capacity = Math.ceil(capacity);
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
/**
|
|
1270
|
+
* Adds a value to the beginning of the linked list.
|
|
1271
|
+
* If the list is at capacity, removes the last element before adding.
|
|
1272
|
+
* @param {*} value - The value to add
|
|
1273
|
+
* @returns {FixedLinkedList} This linked list instance for chaining
|
|
1274
|
+
*/
|
|
1275
|
+
addFirst (value) {
|
|
1276
|
+
if (this.size >= this.capacity) {
|
|
1277
|
+
this.removeLast();
|
|
1278
|
+
}
|
|
1279
|
+
super.addFirst(value);
|
|
1280
|
+
return this
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
/**
|
|
1284
|
+
* Adds a value to the end of the linked list.
|
|
1285
|
+
* If the list is at capacity, removes the first element before adding.
|
|
1286
|
+
* @param {*} value - The value to add
|
|
1287
|
+
* @returns {FixedLinkedList} This linked list instance for chaining
|
|
1288
|
+
*/
|
|
1289
|
+
addLast (value) {
|
|
1290
|
+
if (this.size >= this.capacity) {
|
|
1291
|
+
this.removeFirst();
|
|
1292
|
+
}
|
|
1293
|
+
super.addLast(value);
|
|
1294
|
+
return this
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
/**
|
|
1298
|
+
* Adds a value to the end of the linked list.
|
|
1299
|
+
* If the list is at capacity, removes the first element before adding.
|
|
1300
|
+
* @param {*} value - The value to add
|
|
1301
|
+
* @returns {FixedLinkedList} This linked list instance for chaining
|
|
1302
|
+
*/
|
|
1303
|
+
add (value) {
|
|
1304
|
+
return this.addLast(value)
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
/**
|
|
1308
|
+
* Inserts a value at the specified index.
|
|
1309
|
+
* If the list is at capacity and index is not at the end, removes the first element before adding.
|
|
1310
|
+
* If the list is at capacity and index is at the end, removes the first element before adding.
|
|
1311
|
+
* @param {number} index - The index at which to insert the value
|
|
1312
|
+
* @param {*} value - The value to insert
|
|
1313
|
+
* @returns {FixedLinkedList} This linked list instance for chaining
|
|
1314
|
+
*/
|
|
1315
|
+
insertAt (index, value) {
|
|
1316
|
+
// Remove an element if we're at capacity and not adding beyond current size
|
|
1317
|
+
if (this.size >= this.capacity) {
|
|
1318
|
+
// Always remove first element to maintain capacity
|
|
1319
|
+
this.removeFirst();
|
|
1320
|
+
}
|
|
1321
|
+
super.insertAt(index, value);
|
|
1322
|
+
return this
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
/**
|
|
1326
|
+
* Returns the remaining capacity of the list.
|
|
1327
|
+
* @returns {number} The number of additional elements that can be added
|
|
1328
|
+
*/
|
|
1329
|
+
get remainingCapacity () {
|
|
1330
|
+
return this.capacity - this.size
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
/**
|
|
1334
|
+
* Checks if the list is at full capacity.
|
|
1335
|
+
* @returns {boolean} True if the list is full, false otherwise
|
|
1336
|
+
*/
|
|
1337
|
+
get isFull () {
|
|
1338
|
+
return this.size >= this.capacity
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
/**
|
|
1342
|
+
* Returns a string representation of the FixedLinkedList.
|
|
1343
|
+
* @returns {string} String representation
|
|
1344
|
+
*/
|
|
1345
|
+
toString () {
|
|
1346
|
+
const partialElements = this.slice(0, 3);
|
|
1347
|
+
const partialString = this.size > 3 ? G.safeToString(partialElements) + '...' : G.safeToString(partialElements);
|
|
1348
|
+
return `FixedLinkedList[${this.size}/${this.capacity}](${partialString})`
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
var index = { CappedSet, TimeWheelCache, Hour24TimeWheelCache, LinkedList, FixedLinkedList };
|
|
711
1353
|
|
|
712
1354
|
exports.CappedSet = CappedSet;
|
|
1355
|
+
exports.FixedLinkedList = FixedLinkedList;
|
|
713
1356
|
exports.Hour24TimeWheelCache = Hour24TimeWheelCache;
|
|
1357
|
+
exports.LinkedList = LinkedList;
|
|
714
1358
|
exports.TimeWheelCache = TimeWheelCache;
|
|
715
1359
|
exports.default = index;
|
|
716
1360
|
//# sourceMappingURL=index-dev.cjs.map
|