# 機能設計書 107-キャッシュ共通基盤

## 概要

本ドキュメントは、OpenSearchのキャッシュ共通基盤（Cache Common Module）の設計を記述する。階層型スピルオーバーキャッシュ（Tiered Spillover Cache）を提供し、オンヒープキャッシュとディスクキャッシュを組み合わせた多層キャッシュ基盤を実現するモジュールである。

### 本機能の処理概要

**業務上の目的・背景**：検索結果やリクエストキャッシュのヒット率を向上させるため、限られたヒープメモリだけでなくディスクストレージも活用した多層キャッシュ戦略が必要となる。本モジュールはオンヒープ層から溢れたエントリをディスク層に自動的にスピルオーバーする仕組みを提供する。

**機能の利用シーン**：検索クエリ結果のキャッシュ、リクエストキャッシュの多層化、大量のキャッシュエントリを低コストで保持したい場合に利用される。

**主要な処理内容**：
1. TieredSpilloverCacheによるオンヒープ/ディスク多層キャッシュ管理
2. オンヒープ層からのEviction時にディスク層へのスピルオーバー
3. TookTimePolicyによるキャッシュ対象のフィルタリング（実行時間ベース）
4. セグメント化されたキャッシュ構造（TieredSpilloverCacheSegment）による並行性向上
5. TieredSpilloverCacheStatsHolderによる層別統計情報管理
6. ディスクキャッシュの有効/無効制御

**関連システム・外部連携**：ICache（キャッシュインターフェース）、ディスクキャッシュ実装（例：Ehcache）。

**権限による制御**：特定の権限制御はない。設定により動作を制御。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能は直接的な画面を持たない内部基盤モジュール |

## 機能種別

基盤機能 / キャッシュ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| tiered_spillover.onheap.store.size | long | No | オンヒープキャッシュサイズ | 正の値 |
| tiered_spillover.disk.store.size | long | No | ディスクキャッシュサイズ | 正の値 |
| tiered_spillover.segments | int | No | セグメント数 | VALID_SEGMENT_COUNT_VALUES |
| disk_cache.enabled | boolean | No | ディスクキャッシュ有効/無効 | - |
| took_time_policy | TimeValue | No | キャッシュ対象最小実行時間 | 正のTimeValue |

### 入力データソース

- クラスタ/インデックス設定
- キャッシュ対象データ（key-valueペア）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| キャッシュ値 | V | キャッシュから取得した値 |
| stats | ImmutableCacheStatsHolder | 層別キャッシュ統計 |

### 出力先

呼び出し元のキャッシュ利用コンポーネント

## 処理フロー

### 処理シーケンス

```
1. computeIfAbsent(key, loader)呼出
   └─ オンヒープ層から検索
2. オンヒープ層にヒットした場合
   └─ 値を返却（キャッシュヒット）
3. オンヒープ層にミスの場合
   └─ ディスク層から検索（ディスクキャッシュ有効時）
4. ディスク層にヒットした場合
   └─ 値をオンヒープ層にプロモートして返却
5. 全層ミスの場合
   └─ loader経由でデータ取得→TookTimePolicy判定→オンヒープ層に格納
6. オンヒープ層からEviction発生時
   └─ EvictionをRemovalListenerで検知→ディスク層にスピルオーバー
```

### フローチャート

```mermaid
flowchart TD
    A[computeIfAbsent] --> B{オンヒープ層にHit?}
    B -->|Yes| C[値返却]
    B -->|No| D{ディスク層有効?}
    D -->|Yes| E{ディスク層にHit?}
    D -->|No| G[loader実行]
    E -->|Yes| F[オンヒープにプロモート→返却]
    E -->|No| G
    G --> H{TookTimePolicy通過?}
    H -->|Yes| I[オンヒープ層に格納→返却]
    H -->|No| J[値のみ返却（キャッシュなし）]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-701 | スピルオーバー条件 | EVICTEDまたはCAPACITYのRemovalReasonのみディスクにスピルオーバー | オンヒープからEviction時 |
| BR-702 | TookTimePolicy | 実行時間が閾値未満のクエリ結果はディスクキャッシュに格納しない | ディスク層への書き込み時 |
| BR-703 | セグメント数制約 | セグメント数は1以上でVALID_SEGMENT_COUNT_VALUESに含まれる値 | キャッシュ初期化時 |

### 計算ロジック

セグメントの選択はキーのハッシュ値に基づく。各セグメントは独立したオンヒープ/ディスクキャッシュペアを保持。

## データベース操作仕様

データベース操作なし。キャッシュはメモリ/ディスク上のインメモリデータ構造。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ExecutionException | computeIfAbsent中のloader失敗 | 例外を伝搬 |
| - | IllegalArgumentException | 無効なセグメント数 | 有効な値を設定 |

### リトライ仕様

キャッシュミスは自動的にloaderを実行。loader失敗時のリトライはキャッシュ層では行わない。

## トランザクション仕様

キャッシュ操作はスレッドセーフだが、トランザクション管理の対象外。ConcurrentHashMapとReadWriteLockで並行性を制御。

## パフォーマンス要件

- セグメント化によるロック競合の低減
- CompletableFutureによる同一キーの重複ロード防止
- ディスクキャッシュの有効/無効を動的に切替可能

## セキュリティ考慮事項

- キャッシュデータはノードローカルに保持
- ディスクキャッシュのデータはローカルファイルシステムに保存

## 備考

- 本機能は `@ExperimentalApi` として提供されている
- SPILLOVER_REMOVAL_REASONS = [EVICTED, CAPACITY] のみがスピルオーバー対象
- TIER_DIMENSION_VALUE_ON_HEAP = "on_heap", TIER_DIMENSION_VALUE_DISK = "disk"

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TieredSpilloverCacheSettings.java | `modules/cache-common/src/main/java/org/opensearch/cache/common/tier/TieredSpilloverCacheSettings.java` | キャッシュ設定定義 |
| 1-2 | TieredSpilloverCacheStatsHolder.java | `modules/cache-common/src/main/java/org/opensearch/cache/common/tier/TieredSpilloverCacheStatsHolder.java` | 層別統計管理 |

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TieredSpilloverCachePlugin.java | `modules/cache-common/src/main/java/org/opensearch/cache/common/tier/TieredSpilloverCachePlugin.java` | プラグインエントリーポイント |
| 2-2 | TieredSpilloverCache.java | `modules/cache-common/src/main/java/org/opensearch/cache/common/tier/TieredSpilloverCache.java` | メインキャッシュ実装 |

**主要処理フロー**:
1. **74行目**: ICache<K,V>インターフェースの実装
2. **77行目**: SPILLOVER_REMOVAL_REASONS定義（EVICTED, CAPACITY）
3. **89行目**: セグメント化されたキャッシュ構造
4. **95行目**: CompletableFutureMapによる重複ロード防止
5. **98-100行目**: Builderパターンによるキャッシュ構築

#### Step 3: ポリシー層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TookTimePolicy.java | `modules/cache-common/src/main/java/org/opensearch/cache/common/policy/TookTimePolicy.java` | 実行時間ベースのキャッシュポリシー |

### プログラム呼び出し階層図

```
TieredSpilloverCache.computeIfAbsent(key, loader)
    |
    +-- getSegment(key) -> TieredSpilloverCacheSegment
    |
    +-- TieredSpilloverCacheSegment.computeIfAbsent()
            |
            +-- onHeapCache.computeIfAbsent()
            |       +-- [HIT] -> 返却
            |       +-- [MISS] -> diskCache.get()
            |               +-- [HIT] -> onHeapにプロモート → 返却
            |               +-- [MISS] -> loader.load()
            |                       +-- TookTimePolicy.test()
            |                       +-- onHeapCache.put()
            |
            +-- [Eviction Listener]
                    +-- TookTimePolicy.test()
                    +-- diskCache.put()  [スピルオーバー]
```

### データフロー図

```
[入力]                    [処理]                           [出力]

Key + Loader       ----> TieredSpilloverCache
                          |
                          +-> OnHeap Layer  [HIT] -----> 値返却
                          |     |
                          |     +-> [MISS]
                          |            |
                          +-> Disk Layer   [HIT] -----> プロモート+返却
                          |     |
                          |     +-> [MISS]
                          |            |
                          +-> Loader実行            -----> 値返却+キャッシュ
                          |
                          [Eviction]
                          +-> OnHeap → Disk (スピルオーバー)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TieredSpilloverCache.java | `modules/cache-common/src/main/java/org/opensearch/cache/common/tier/TieredSpilloverCache.java` | ソース | メインキャッシュ実装 |
| TieredSpilloverCachePlugin.java | `modules/cache-common/src/main/java/org/opensearch/cache/common/tier/TieredSpilloverCachePlugin.java` | ソース | プラグインクラス |
| TieredSpilloverCacheSettings.java | `modules/cache-common/src/main/java/org/opensearch/cache/common/tier/TieredSpilloverCacheSettings.java` | ソース | 設定定義 |
| TieredSpilloverCacheStatsHolder.java | `modules/cache-common/src/main/java/org/opensearch/cache/common/tier/TieredSpilloverCacheStatsHolder.java` | ソース | 統計管理 |
| TookTimePolicy.java | `modules/cache-common/src/main/java/org/opensearch/cache/common/policy/TookTimePolicy.java` | ソース | 実行時間ポリシー |
