# 通知設計書 25-OutdatedDependee

## 概要

本ドキュメントは、Zigコンパイラにおけるインクリメンタルコンパイルの依存先更新通知「OutdatedDependee」の設計を記述する。

### 本通知の処理概要

本通知は、インクリメンタルコンパイルにおいて依存先（Dependee）が更新され、依存元（Depender）が古くなったことを示す内部状態変更の通知である。これは外部ログではなく、コンパイラ内部の依存関係追跡メカニズムの一部である。

**業務上の目的・背景**：Zigのインクリメンタルコンパイルでは、ソースコードの変更による影響範囲を最小限に抑えるため、精密な依存関係追跡が必要である。依存先が変更された場合、その依存元を「古い」（outdated）としてマークし、再解析の対象とする。これにより、変更されていないコードの再コンパイルを避け、コンパイル時間を短縮できる。

**通知の送信タイミング**：`markDependeeOutdated`関数が呼び出された時点で、依存元のAnalUnitが`outdated`マップに追加される。これは以下の場合に発生する: (1) ZIRコードの変更検出時、(2) 埋め込みファイルの変更時、(3) ZONファイルの変更時、(4) 解析結果の変更確定時。

**通知の受信者**：これは内部状態変更であり、外部への通知ではない。コンパイラ内部の`outdated`マップと`potentially_outdated`マップを通じて、再解析が必要なAnalUnitを追跡する。

**通知内容の概要**：更新された依存先（Dependee）の種類と、影響を受ける依存元（AnalUnit）のリストが内部的に管理される。

**期待されるアクション**：コンパイラは`outdated`マップにあるAnalUnitを順次再解析し、コードを最新状態に保つ。開発者側でのアクションは不要（透過的）。

## 通知種別

内部状態変更（マップ更新）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（内部状態更新） |
| 優先度 | - |
| リトライ | なし |

### 送信先決定ロジック

`InternPool.dependencyIterator`を使用して、指定されたDependeeに依存するすべてのAnalUnitを列挙し、それぞれを`outdated`マップに追加する。

## 通知テンプレート

該当なし（内部状態変更）

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| dependee | 更新された依存先 | InternPool.Dependee | Yes |
| depender | 影響を受ける依存元 | AnalUnit | Yes |
| po_dep_count | PO依存のカウント | u32 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ソース変更 | src_hash変更 | ZIRが変更された場合 | ソースファイルの内容が変更 |
| 埋め込み変更 | embed_file変更 | @embedFileの対象ファイルが変更 | 埋め込みファイルの更新 |
| ZON変更 | zon_file変更 | ZONファイルが変更 | 設定ファイルの更新 |
| 解析完了 | 解析結果確定 | 値が変更された場合 | Nav/Type/Funcの解析完了時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 依存元が既にoutdated | 重複追加を防止 |
| インクリメンタル無効 | 非インクリメンタルビルドでは追跡なし |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[Dependee変更検出] --> B[markDependeeOutdated呼び出し]
    B --> C[dependencyIterator取得]
    C --> D[依存元ループ開始]
    D --> E{既にoutdated?}
    E -->|Yes| F[スキップ]
    E -->|No| G{potentially_outdated?}
    G -->|Yes| H[POから削除、outdatedに追加]
    G -->|No| I[outdatedに追加]
    I --> J[markTransitiveDependersPotentiallyOutdated]
    H --> J
    J --> D
    F --> D
    D --> K[ループ終了]
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| InternPool.deps | 依存関係の参照 | Dependee→Dependerのマッピング |
| outdated | 既存のoutdated状態確認 | 重複防止 |
| potentially_outdated | PO状態の確認 | PO→outdated遷移 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| outdated | PUT | AnalUnitをoutdatedとしてマーク |
| potentially_outdated | REMOVE | POからoutdatedに遷移 |
| outdated_ready | PUT | PO依存カウントが0の場合 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| OutOfMemory | マップ拡張時にメモリ不足 | エラーを伝播 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

該当なし（内部処理）

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

- 内部状態のみを変更し、外部への情報漏洩はない
- メモリ内のマップ操作のみ

## 備考

- `markDependeeOutdated`の`reason`パラメータは、PO依存のカウント調整に使用される
  - `.not_marked_po`: PO依存カウントを新たに設定
  - `.marked_po`: 既存のPO依存カウントを使用
- 推移的な依存元は`potentially_outdated`としてマークされる

---

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

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

### 推奨読解順序

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

依存関係追跡に使用されるマップを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Zcu.zig | `src/Zcu.zig` | 253-260行目: outdated/potentially_outdated/outdated_readyの定義 |
| 1-2 | InternPool.zig | `src/InternPool.zig` | Dependee型とdependencyIteratorの定義 |

**読解のコツ**: `outdated`はPO依存カウントを値として持つ。カウントが0になると`outdated_ready`に追加され、即座に再解析可能になる。

#### Step 2: markDependeeOutdated関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Zcu.zig | `src/Zcu.zig` | markDependeeOutdated関数（約3900行目付近） |

**主要処理フロー**:
1. `dependencyIterator`で依存元を列挙
2. 各依存元について、既存の状態を確認
3. `outdated`マップに追加
4. `markTransitiveDependersPotentiallyOutdated`で推移的依存元をPOマーク

#### Step 3: 呼び出し元を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Compilation.zig | `src/Compilation.zig` | 5693行目: embed_file変更時 |
| 3-2 | Zcu/PerThread.zig | `src/Zcu/PerThread.zig` | 443行目: zon_file変更時 |
| 3-3 | Zcu/PerThread.zig | `src/Zcu/PerThread.zig` | 694-697行目: 解析結果変更時 |

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

```
[変更検出]
    │
    ├─ Compilation.runJob (embed_file) → markDependeeOutdated(.not_marked_po, .embed_file)
    │
    ├─ PerThread.ensureFileAnalyzed (zon) → markDependeeOutdated(.not_marked_po, .zon_file)
    │
    └─ PerThread.ensureMemoizedStateUpToDate → markDependeeOutdated(.marked_po, .memoized_state)
           │
           └─ markDependeeOutdated()
                  │
                  ├─ ip.dependencyIterator(dependee)
                  │      └─ [依存元を列挙]
                  │
                  ├─ outdated.put(depender, po_count)
                  │
                  └─ markTransitiveDependersPotentiallyOutdated(depender)
                         └─ [推移的依存元をPOマーク]
```

### データフロー図

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

Dependee変更      ───▶ markDependeeOutdated()     ───▶ outdatedマップ更新
        │                       │                           │
        ▼                       ▼                           ▼
  dependencyIterator     各dependerを処理         outdated_ready更新
        │                       │                     (PO count=0の場合)
        ▼                       ▼
  依存元リスト取得     推移的依存元をPOマーク ───▶ potentially_outdatedマップ更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Zcu.zig | `src/Zcu.zig` | ソース | 依存関係追跡マップとmarkDependeeOutdated関数 |
| Zcu/PerThread.zig | `src/Zcu/PerThread.zig` | ソース | 解析完了時の呼び出し元 |
| Compilation.zig | `src/Compilation.zig` | ソース | embed_file変更時の呼び出し元 |
| InternPool.zig | `src/InternPool.zig` | ソース | Dependee型と依存関係ストレージ |
