* Find the content with the oldest item and run GC on that. * Only runs for one content to avoid large invalidation.
()
| 574 | * Only runs for one content to avoid large invalidation. |
| 575 | */ |
| 576 | _gcOldestContent() { |
| 577 | /** @type {PackItemInfo | undefined} */ |
| 578 | let oldest; |
| 579 | for (const info of this.itemInfo.values()) { |
| 580 | if (oldest === undefined || info.lastAccess < oldest.lastAccess) { |
| 581 | oldest = info; |
| 582 | } |
| 583 | } |
| 584 | if ( |
| 585 | Date.now() - /** @type {PackItemInfo} */ (oldest).lastAccess > |
| 586 | this.maxAge |
| 587 | ) { |
| 588 | const loc = /** @type {PackItemInfo} */ (oldest).location; |
| 589 | if (loc < 0) return; |
| 590 | const content = /** @type {PackContent} */ (this.content[loc]); |
| 591 | const items = new Set(content.items); |
| 592 | const usedItems = new Set(content.used); |
| 593 | this._gcAndUpdateLocation(items, usedItems, loc); |
| 594 | |
| 595 | this.content[loc] = |
| 596 | items.size > 0 |
| 597 | ? new PackContent(items, usedItems, async () => { |
| 598 | await content.unpack( |
| 599 | "it contains old items that should be garbage collected" |
| 600 | ); |
| 601 | /** @type {Content} */ |
| 602 | const map = new Map(); |
| 603 | for (const identifier of items) { |
| 604 | map.set( |
| 605 | identifier, |
| 606 | /** @type {Content} */ |
| 607 | (content.content).get(identifier) |
| 608 | ); |
| 609 | } |
| 610 | return new PackContentItems(map); |
| 611 | }) |
| 612 | : undefined; |
| 613 | } |
| 614 | } |
| 615 | |
| 616 | /** |
| 617 | * Serializes this instance into the provided serializer context. |