@asamuzakjp/generational-cache

中文文档
3.0.1发布于 2026/06/20MITTypeScriptES Module零依赖近 30 天下载 8570.1万

A generational cache with strict entry-count limits and payload validation.

原始使用文档
文档目录19 节
  1. How it Works
  2. When NOT to Use
  3. Installation
  4. Usage
  5. API
  6. new GenerationalCache(max, opt)
  7. Properties
  8. Methods
  9. Performance
  10. Benchmark Environment
  11. 1. Small Cache (Max Size = 512)
  12. 2. Medium Cache (Max Size = 2,048)
  13. 3. Large Cache (Max Size = 8,192)
  14. 4. Non-Primitive Payload (Max Size = 4,096 / strictValidate…
  15. 5. Non-Primitive Payload (Max Size = 4,096 / strictValidate…
  16. 6. Cyclic Access (Max Size = 8,192 / Working Set = 5,000)
  17. 7. Cyclic Access (Max Size = 4,096 / Working Set = 5,000)
  18. Key Characteristics
  19. License

generational-cache

CI CodeQL npm (scoped)

A lightweight, generational cache with strict entry-count limits and payload validation.

How it Works

GenerationalCache maintains two internal Map objects: current and old. It uses an internal boundary of ($max / 2$), allowing both generations to remain bounded while keeping generation swaps inexpensive.

  1. Insertion & Validation: New items are validated against byte size limits before being added to the current generation.
  2. Promotion: If you get an item that exists in the old generation, it is promoted to the current generation to ensure it stays in the cache longer.
  3. Generation Swapping: Once the current generation's size meets or exceeds the boundary threshold ($max / 2$), a generation swap is triggered: the existing old generation is discarded, the current generation becomes the new old generation, and a new empty current generation is created.

This two-generation approach avoids the overhead of updating timestamps or linked list pointers on every access. While not a drop-in replacement for standard LRU caches, it prioritizes raw throughput over strict eviction ordering.

When NOT to Use

GenerationalCache may not be a good fit when:

  • You require strict LRU eviction ordering.
  • Cache hit rate is more important than insertion/eviction throughput.
  • You already know your working set size and can provision a sufficiently large LRU cache.

Installation

npm i @asamuzakjp/generational-cache

Usage

import { GenerationalCache } from '@asamuzakjp/generational-cache';

// Initialize with a max capacity of 1024 items and custom size limits
const cache = new GenerationalCache(1024, {
  maxKeySize: 4096,          // 4 KB limit for keys
  maxValueSize: 1024 * 1024, // 1 MB limit for values
  strictValidate: true       // Enable strict deep validation for objects (default)
});

API

new GenerationalCache(max, opt)

Creates a new cache instance with a maximum capacity of max entries.

  • max (number): The maximum number of items the cache can hold. If the specified value is less than 4, or if an invalid value is specified, the default value of 4 will be used.
  • opt (object, optional):
    • cacheFunction (boolean): Caches functions if true. Defaults to false.
    • cacheSymbol (boolean): Caches symbols if true. Defaults to false.
    • maxKeySize (number): Maximum allowed size for a key in bytes. Defaults to 8192 (8 KB).
    • maxValueSize (number): Maximum allowed size for a value in bytes. Defaults to 1048576 (1 MB).
    • strictValidate (boolean): Strictly validate object payload structures and sizes if true. Defaults to true.

Properties

  • cache.entryCount (number, read-only): Returns the total number of underlying entries currently stored across both generations. Note: To maximize write throughput, this library allows temporary key duplication between the current and old generations (e.g., when an item exists in both generations simultaneously). The reported count may exceed the number of unique keys, but remains bounded by the cache's internal capacity.
  • cache.max (number): Gets or sets the maximum item capacity. Note: Updating this property dynamically will clear all existing cached items (it implicitly invokes cache.clear() to safely recalculate boundaries).

Methods

  • cache.get(key) Retrieves an item. If the item is found in the old generation, it is automatically promoted to the current generation to prevent it from being evicted during the next swap.
    • Returns (any | undefined): The value associated with the key, or undefined if the key is not found.
  • cache.set(key, value) Adds or updates an item. It validates the byte size of both the key and value (if they are strings) before inserting. If this operation causes the current generation's size to meet or exceed the boundary threshold, a generation swap is triggered.
    • Note: Storing undefined as a value is not supported, as cache.get(key) treats undefined as a cache miss.
    • Returns: The cache instance itself (allows chaining).
  • cache.has(key) Checks if a key exists in the cache (in either generation).
    • Returns: true if the key exists, otherwise false.
  • cache.delete(key) Removes an item from the cache.
    • Returns: true if the item existed and was removed, otherwise false.
  • cache.clear() Empties all items from the cache.

Performance

Benchmarks are divided into two states to simulate real-world conditions:

  • Cold State: Measured with aggressive internal Garbage Collection to observe performance before full V8 TurboFan optimizations.
  • Warm State: Measured after sufficient warmup, representing sustained throughput under optimal JIT compilation.

The results below reflect the sustained operations per second (ops/sec), calculated from the average latency (ns/iter). Higher values indicate better performance.

Benchmark Environment

1. Small Cache (Max Size = 512)

ScenarioStateGenerationalCacheLRUCacheQuickLRUMnemonist
SetCold15,137,754 ops/sec4,265,484 ops/sec13,800,718 ops/sec17,844,397 ops/sec
Warm18,993,352 ops/sec15,299,878 ops/sec18,132,366 ops/sec19,007,793 ops/sec
GetCold16,028,210 ops/sec7,566,013 ops/sec13,881,177 ops/sec30,030,030 ops/sec
Warm17,917,936 ops/sec23,523,877 ops/sec16,458,196 ops/sec39,416,634 ops/sec
EvictionCold16,236,402 ops/sec7,372,457 ops/sec14,547,571 ops/sec5,407,451 ops/sec
Warm20,479,214 ops/sec8,993,615 ops/sec17,123,288 ops/sec7,668,712 ops/sec

2. Medium Cache (Max Size = 2,048)

ScenarioStateGenerationalCacheLRUCacheQuickLRUMnemonist
SetCold15,024,038 ops/sec4,537,617 ops/sec11,818,934 ops/sec15,110,305 ops/sec
Warm17,126,220 ops/sec13,299,641 ops/sec15,309,247 ops/sec17,070,673 ops/sec
GetCold13,976,240 ops/sec8,134,711 ops/sec11,784,115 ops/sec26,315,789 ops/sec
Warm16,015,375 ops/sec19,425,019 ops/sec13,599,891 ops/sec35,663,338 ops/sec
EvictionCold14,858,841 ops/sec6,439,979 ops/sec12,425,447 ops/sec5,252,929 ops/sec
Warm19,805,902 ops/sec7,981,483 ops/sec16,108,247 ops/sec7,295,010 ops/sec

3. Large Cache (Max Size = 8,192)

ScenarioStateGenerationalCacheLRUCacheQuickLRUMnemonist
SetCold13,292,569 ops/sec3,637,686 ops/sec7,970,033 ops/sec11,318,619 ops/sec
Warm17,652,251 ops/sec11,709,602 ops/sec12,781,186 ops/sec15,225,335 ops/sec
GetCold13,840,830 ops/sec5,746,136 ops/sec11,021,713 ops/sec17,155,601 ops/sec
Warm19,116,804 ops/sec17,885,888 ops/sec15,664,160 ops/sec28,344,671 ops/sec
EvictionCold14,025,245 ops/sec5,358,770 ops/sec9,882,399 ops/sec4,185,501 ops/sec
Warm19,249,278 ops/sec7,029,383 ops/sec13,646,288 ops/sec6,086,798 ops/sec

4. Non-Primitive Payload (Max Size = 4,096 / strictValidate = true)

ScenarioStateGenerationalCacheLRUCacheQuickLRUMnemonist
SetCold602,410 ops/sec3,003,725 ops/sec9,948,269 ops/sec10,231,226 ops/sec
Warm757,576 ops/sec10,964,912 ops/sec14,697,237 ops/sec16,572,754 ops/sec
GetCold13,180,440 ops/sec7,043,742 ops/sec11,037,528 ops/sec17,580,872 ops/sec
Warm16,170,763 ops/sec19,007,793 ops/sec14,363,689 ops/sec28,719,127 ops/sec
EvictionCold617,284 ops/sec5,356,186 ops/sec12,072,920 ops/sec2,607,222 ops/sec
Warm775,194 ops/sec7,504,127 ops/sec14,981,273 ops/sec6,208,481 ops/sec

5. Non-Primitive Payload (Max Size = 4,096 / strictValidate = false)

ScenarioStateGenerationalCacheLRUCacheQuickLRUMnemonist
SetCold12,315,271 ops/sec2,650,060 ops/sec10,233,320 ops/sec10,884,946 ops/sec
Warm16,100,467 ops/sec10,561,893 ops/sec14,624,159 ops/sec16,672,224 ops/sec
GetCold13,835,086 ops/sec7,248,478 ops/sec10,714,668 ops/sec19,015,022 ops/sec
Warm16,012,810 ops/sec18,744,142 ops/sec14,106,362 ops/sec32,927,231 ops/sec
EvictionCold10,424,268 ops/sec5,473,753 ops/sec11,983,223 ops/sec2,544,853 ops/sec
Warm16,291,952 ops/sec6,972,996 ops/sec13,417,416 ops/sec5,798,782 ops/sec

6. Cyclic Access (Max Size = 8,192 / Working Set = 5,000)

MetricGenerationalCacheLRUCacheQuickLRUMnemonist
Hit Rate78.30%100.00%100.00%100.00%
Throughput8,783,487 ops/sec37,778,617 ops/sec38,550,501 ops/sec44,742,729 ops/sec

7. Cyclic Access (Max Size = 4,096 / Working Set = 5,000)

MetricGenerationalCacheLRUCacheQuickLRUMnemonist
Hit Rate0.00%0.00%78.30%0.00%
Throughput9,931,472 ops/sec6,396,724 ops/sec8,509,189 ops/sec6,078,288 ops/sec

Key Characteristics

  • High Eviction Efficiency: GenerationalCache demonstrates strong throughput during high-turnover workloads, maintaining a performance margin compared to standard LRU designs in large-scale eviction scenarios.
  • Predictable Scalability: While other libraries may experience performance degradation as cache size increases, GenerationalCache maintains consistent throughput due to its generational swap mechanism.
  • Balanced Read/Write: It provides stable and competitive performance across all basic operations (get, set), making it suitable for both read-heavy and write-heavy environments.
  • Strict Validation Toggle: By default, non-primitive payloads undergo deep validation to prevent memory exhaustion from oversized objects, which impacts write throughput. Disabling strictValidate restores write performance, provided that payload sizes are managed externally (See 4 & 5).
  • Trade-offs: In cyclic access patterns where the working set is greater than max / 2 but smaller than max, GenerationalCache will experience frequent generation swaps and cache misses. To maximize the performance benefits of GenerationalCache, it is often better to keep the max size small enough to allow some evictions, rather than trying to fit the entire working set (See 6 & 7).

License

MIT

版本与发布记录

@asamuzakjp/generational-cache 共发布 10 个版本,首次发布于 2026/04/12;过去 12 个月发布了 10 个版本。

版本发布日期距今
3.0.1latest2026/06/204 个月前
3.0.02026/06/164 个月前
2.0.42026/06/114 个月前
2.0.32026/06/114 个月前
2.0.22026/05/155 个月前
2.0.12026/05/026 个月前

其他发布通道:next → 0.1.0。

关于 @asamuzakjp/generational-cache 的常见问题

@asamuzakjp/generational-cache 是什么?

A generational cache with strict entry-count limits and payload validation.

如何安装 @asamuzakjp/generational-cache?

在项目目录运行 npm install @asamuzakjp/generational-cache,或使用 pnpm add / yarn add / bun add。

@asamuzakjp/generational-cache 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@asamuzakjp/generational-cache 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@asamuzakjp/generational-cache 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js ^22.13.0 || >=24.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@asamuzakjp/generational-cache 可以商用吗?

@asamuzakjp/generational-cache 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@asamuzakjp/generational-cache 的下载量有多少?

根据 npm 官方下载统计,@asamuzakjp/generational-cache 在 2026/10/07 – 2026/11/05 这 30 天内被下载 85,701,131 次,日均约 2,856,704 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@asamuzakjp/generational-cache 还在维护吗?

最新版本 3.0.1 发布于 2026/06/20(4 个月前);至今共发布 10 个版本,其中过去 12 个月发布了 10 个;首次发布于 2026/04/12。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。