# 通知設計書 26-UpToDateDependee

## 概要

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

### 本通知の処理概要

本通知は、インクリメンタルコンパイルにおいて「潜在的に古い」（Potentially Outdated: PO）状態だった依存先が、実際には最新状態であることが確認された際に発生する内部状態変更である。これにより、不必要な再解析を回避し、コンパイル効率を向上させる。

**業務上の目的・背景**：インクリメンタルコンパイルでは、依存関係の連鎖により多くのAnalUnitが「潜在的に古い」としてマークされる可能性がある。しかし、実際に解析を行うと、依存先の値が変わっていないことが判明する場合がある。この場合、POとしてマークされた依存元を最新状態に戻すことで、不必要な再コンパイルを防ぐ。

**通知の送信タイミング**：`markPoDependeeUpToDate`関数が呼び出された時点で発生する。これは、解析結果が以前と変わらないことが確認された場合（`any_changed == false`）に発生する。

**通知の受信者**：これは内部状態変更であり、外部への通知ではない。`potentially_outdated`マップのPO依存カウントを減少させ、カウントが0になったAnalUnitは最新状態と見なされる。

**通知内容の概要**：最新と確認された依存先（Dependee）の情報が内部的に処理される。

**期待されるアクション**：PO依存カウントが0になったAnalUnitは再解析が不要となり、コンパイル時間が短縮される。開発者側でのアクションは不要。

## 通知種別

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

## 送信仕様

### 基本情報

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

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

`InternPool.dependencyIterator`を使用して、指定されたDependeeに依存するすべてのAnalUnitを列挙し、それぞれの`potentially_outdated`カウントを減少させる。

## 通知テンプレート

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

## テンプレート変数

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

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 解析完了 | 解析結果確定 | 値が変更されなかった場合 | any_changed == false |
| 状態確認 | memoized_state解析 | 状態が変わらなかった場合 | 組み込み型の解析等 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 解析結果が変更された場合 | markDependeeOutdatedが呼ばれる |
| インクリメンタル無効 | 非インクリメンタルビルドでは追跡なし |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[解析完了] --> B{any_changed?}
    B -->|Yes| C[markDependeeOutdated]
    B -->|No| D[markPoDependeeUpToDate]
    D --> E[dependencyIterator取得]
    E --> F[依存元ループ開始]
    F --> G{potentially_outdated?}
    G -->|No| H[スキップ]
    G -->|Yes| I[PO countを減少]
    I --> J{PO count == 0?}
    J -->|Yes| K[potentially_outdatedから削除]
    J -->|No| L[カウント更新]
    K --> M[最新状態として扱う]
    H --> F
    L --> F
    M --> F
    F --> N[ループ終了]
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| InternPool.deps | 依存関係の参照 | Dependee→Dependerのマッピング |
| potentially_outdated | PO状態とカウントの確認 | カウント減少対象 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| potentially_outdated | UPDATE/REMOVE | PO countを減少、0になったら削除 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| OutOfMemory | マップ操作時 | エラーを伝播 |

### リトライ仕様

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

## 配信設定

該当なし（内部処理）

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

- 内部状態のみを変更し、外部への情報漏洩はない

## 備考

- PO依存カウントは、そのAnalUnitがPO状態の依存先をいくつ持っているかを示す
- カウントが0になると、すべてのPO依存が解決されたことを意味し、再解析は不要
- これはコンパイル効率化の重要なメカニズム

---

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

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

### 推奨読解順序

#### Step 1: PO状態管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Zcu.zig | `src/Zcu.zig` | 253行目: potentially_outdatedマップの定義 |
| 1-2 | Zcu.zig | `src/Zcu.zig` | markPoDependeeUpToDate関数 |

**読解のコツ**: `potentially_outdated`の値はPO依存のカウントである。このカウントが0になると、そのAnalUnitはPO状態から解除される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Zcu/PerThread.zig | `src/Zcu/PerThread.zig` | 694-698行目: any_changedに基づく分岐 |

**主要処理フロー**:
- **694行目**: `if (any_changed)`で分岐
- **695行目**: 変更あり → `markDependeeOutdated`
- **697行目**: 変更なし → `markPoDependeeUpToDate`

#### Step 3: カウント管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Zcu.zig | `src/Zcu.zig` | markPoDependeeUpToDate関数の実装 |

**主要処理フロー**:
1. 依存元を列挙
2. `potentially_outdated`にあればカウントを減少
3. カウントが0になれば削除

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

```
PerThread.ensureMemoizedStateUpToDate() [630行目]
    │
    └─ analyzeMemoizedState()
           │
           └─ [結果確認]
                  │
                  ├─ any_changed == true → markDependeeOutdated()
                  │
                  └─ any_changed == false → markPoDependeeUpToDate() ← 本通知
                         │
                         ├─ ip.dependencyIterator(dependee)
                         │      └─ [依存元を列挙]
                         │
                         └─ potentially_outdated[depender] -= 1
                                │
                                └─ [count == 0なら削除]
```

### データフロー図

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

解析完了(変更なし)  ───▶ markPoDependeeUpToDate()   ───▶ POカウント減少
        │                       │                           │
        ▼                       ▼                           ▼
  dependee指定        各dependerのカウント処理      [count > 0] 更新
        │                       │                     [count == 0] 削除
        ▼                       ▼
  依存元リスト取得           カウント判定    ───▶ 最新状態確定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Zcu.zig | `src/Zcu.zig` | ソース | markPoDependeeUpToDate関数と状態マップ |
| Zcu/PerThread.zig | `src/Zcu/PerThread.zig` | ソース | 呼び出し元の解析処理 |
| InternPool.zig | `src/InternPool.zig` | ソース | 依存関係ストレージ |
