Agent Skillslichtblick-suite/lichtblick › caching-internals

caching-internals

GitHub

解析 Lichtblick 预加载子系统的缓存内部机制,涵盖 CachingIterableSource、BufferedIterableSource 及 BlockLoader 的实现细节,包括内存预算、LRU 驱逐、预读缓冲及背压协调。

.github/skills/caching-internals/SKILL.md lichtblick-suite/lichtblick

Trigger Scenarios

询问缓存策略或内存管理 排查播放卡顿或预加载问题 理解 LRU 驱逐逻辑

Install

npx skills add lichtblick-suite/lichtblick --skill caching-internals -g -y
More Options

Non-standard path

npx skills add https://github.com/lichtblick-suite/lichtblick/tree/develop/.github/skills/caching-internals -g -y

Use without installing

npx skills use lichtblick-suite/lichtblick@caching-internals

指定 Agent (Claude Code)

npx skills add lichtblick-suite/lichtblick --skill caching-internals -a claude-code -g -y

安装 repo 全部 skill

npx skills add lichtblick-suite/lichtblick --all -g -y

预览 repo 内 skill

npx skills add lichtblick-suite/lichtblick --list

SKILL.md

Frontmatter
{
    "name": "caching-internals",
    "description": "Deep implementation details of caching strategies, memory budgets, block eviction, and buffered reading in the Lichtblick preloading subsystem."
}

Caching Internals Skill

CachingIterableSource Implementation

Cache Structure

class CachingIterableSource {
  #blocks = new Map<string, CacheBlock>();  // key: serialized range+topics
  #totalSize = 0;                           // current memory usage
  #cacheSizeBytes = 600 * 1024 * 1024;      // 600MB budget
  #maxBlockSize = 50 * 1024 * 1024;         // 50MB per block
  #accessOrder: string[] = [];              // LRU tracking
}

Cache Key Design

  • Key combines: startTime + endTime + sorted topic names
  • This means the same time range with different topic sets creates separate cache entries
  • Allows partial cache hits when subscription set changes

Eviction Algorithm

  1. When #totalSize + newBlockSize > #cacheSizeBytes:
  2. Find blocks behind current read position (already consumed)
  3. Evict LRU blocks until sufficient space is freed
  4. If no blocks behind read position exist, evict oldest block regardless

Block Lifecycle

EMPTY → LOADING → CACHED → EVICTED
                     │
                     └──► ACCESSED (moves to front of LRU)

BufferedIterableSource Implementation

Read-Ahead Configuration

// packages/suite-base/src/players/IterablePlayer/BufferedIterableSource.ts
const DEFAULT_READ_AHEAD_DURATION = { sec: 10, nsec: 0 };
// Overridable per-instance via opt.readAheadDuration; defaults to 10 s.

⚠️ There is no MCAP_READ_AHEAD_DURATION_SEC = 120 (or any 120-second MCAP-specific read-ahead). The only default is { sec: 10, nsec: 0 }, applied uniformly regardless of source format.

Producer-Consumer Coordination

Producer Thread (may be Worker):
  while (not at end && buffer not full) {
    message = await source.next();
    buffer.push(message);
    signal consumer;
  }
  wait for consumer to drain;

Consumer (IterablePlayer tick loop):
  messages = buffer.drain(upToTime);
  signal producer to refill;

Backpressure Mechanism

  • Producer fills buffer up to readAheadDuration worth of messages
  • When buffer is full, producer yields (awaits a drain signal)
  • Consumer pulls messages up to its tick budget time
  • After consuming, signals producer to resume filling

VecQueue Details

  • Backed by a plain array with start/end pointers
  • push(): appends to end, O(1)
  • drain(predicate): returns all items matching predicate from front, O(n) but bulk operation
  • Periodic compaction: when start pointer exceeds threshold, shifts array

BlockLoader Implementation

Block Division Strategy

  • Total time range divided into N blocks of equal duration
  • Block count determined by: Math.ceil(totalDuration / targetBlockDuration)
  • Target block duration balances granularity vs overhead

Loading Priority

  1. Block containing current playback time (immediate need)
  2. Blocks ahead of current time (upcoming data)
  3. Blocks behind current time (for seek-back scenarios)
  4. Never-accessed blocks (lowest priority)

Progress Reporting

interface Progress {
  fullyLoadedFractionRanges: Array<{ start: number; end: number }>;
  // Fraction 0..1 representing which portions of the time range are cached
}

Memory Optimization Patterns

  1. Shared ArrayBuffers: Message data stored as Uint8Array views into shared buffers where possible
  2. Lazy deserialization: Raw bytes cached, deserialized only when consumed
  3. Topic-scoped loading: Each block only contains data for requested topics
  4. Size estimation: Block size estimated before full load to prevent over-allocation

Version History

  • 6435710 Current 2026-08-16 02:34

    新增 BlockLoader 实现细节,包括分块策略、加载优先级及进度报告机制。

  • cab9317 2026-07-24 12:16

Same Skill Collection

.github/skills/3d-rendering/SKILL.md
.github/skills/deserialization/SKILL.md
.github/skills/e2e-playwright-mcp/SKILL.md
.github/skills/electron-internals/SKILL.md
.github/skills/extensions-internals/SKILL.md
.github/skills/layouts-internals/SKILL.md
.github/skills/mcap-format/SKILL.md
.github/skills/message-path/SKILL.md
.github/skills/message-pipeline/SKILL.md
.github/skills/panel-extension-api/SKILL.md
.github/skills/panel-image/SKILL.md
.github/skills/panel-log/SKILL.md
.github/skills/panel-map/SKILL.md
.github/skills/panel-raw-messages/SKILL.md
.github/skills/panel-state-transitions/SKILL.md
.github/skills/panel-user-scripts/SKILL.md
.github/skills/performance/SKILL.md
.github/skills/player-internals/SKILL.md
.github/skills/plot-internals/SKILL.md
.github/skills/release-process/SKILL.md
.github/skills/remote-caching/SKILL.md
.github/skills/test-conventions/SKILL.md
.github/skills/theme/SKILL.md
.github/skills/unit-testing/SKILL.md
.github/skills/web-workers/SKILL.md
.github/skills/websocket-connection/SKILL.md

Metadata

Files
0
Version
6435710
Hash
7456aa9d
Indexed
2026-07-24 12:16

inicio - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-16 23:25
浙ICP备14020137号-1 $mapa de visitantes$