# 機能設計書 104-llvm-cas

## 概要

本ドキュメントは、llvm-cas機能の設計仕様を記述する。llvm-casは、LLVM Content Addressable Storage（CAS）を操作するためのコマンドラインツールである。

### 本機能の処理概要

llvm-casは、LLVM CAS（Content Addressable Storage）に対する各種操作を行うユーティリティツールである。CASはコンテンツのハッシュをキーとしてデータを保存・取得するストレージシステムで、ビルドキャッシュやアクションキャッシュの基盤として使用される。

**業務上の目的・背景**：大規模プロジェクトのビルドにおいて、中間成果物のキャッシュは重要である。CASを使用することで、同一コンテンツの重複保存を避け、ビルドの高速化とストレージ効率の向上を実現できる。また、アクションキャッシュと組み合わせることで、同一入力に対するビルド結果を再利用できる。

**機能の利用シーン**：ビルドシステムとの統合、キャッシュデータの検査・管理、CASデータの検証・修復作業に使用される。開発者がキャッシュの状態を確認したり、問題のあるキャッシュを修復する際に利用される。

**主要な処理内容**：
1. CASへのデータ保存（make-blob、make-node）
2. CASからのデータ取得（cat-node-data、ls-node-refs）
3. CASデータのダンプ（dump）
4. CAS間のデータインポート（import）
5. アクションキャッシュ操作（put-cache-key、get-cache-result）
6. CAS検証・修復（validate、validate-object、validate-if-needed）
7. CASプルーニング（prune）

**関連システム・外部連携**：ビルドシステム（CMake、Ninja等）、他のCASインスタンス（import時）と連携する。

**権限による制御**：特になし。CASディレクトリへのファイルシステムアクセス権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLIインターフェース | 主画面 | サブコマンドによる各種操作 |

## 機能種別

データ操作処理 / ストレージ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --cas | 文字列 | Yes | CASディレクトリパス | 存在するパス |
| --upstream-cas | 文字列 | No | インポート元CASパス | import時必須 |
| --data | 文字列 | No | データファイルパス | make-blob/make-node時 |
| --check-hash | フラグ | No | ハッシュ検証を実行 | validate時 |
| --allow-recovery | フラグ | No | 修復を許可 | validate-if-needed時 |
| --force | フラグ | No | 強制実行 | validate-if-needed時 |
| --in-process | フラグ | No | 同一プロセスで実行 | validate-if-needed時 |
| objects | CAS ID | 条件付き | 操作対象オブジェクトID | 各種コマンド時 |

### サブコマンド一覧

| サブコマンド | 説明 | 入力要否 |
|-------------|------|---------|
| --dump | CAS全体をダンプ | 不要 |
| --cat-node-data | オブジェクトのデータを出力 | 必要 |
| --make-blob | BLOBを作成 | --data必須 |
| --make-node | ノードを作成 | 参照オブジェクト、--data必須 |
| --ls-node-refs | オブジェクトの参照一覧 | 必要 |
| --import | 上流CASからインポート | --upstream-cas、オブジェクト必須 |
| --put-cache-key | キャッシュキーを設定 | キー/値ペア必須 |
| --get-cache-result | キャッシュ結果を取得 | キー必須 |
| --validate | CAS全体を検証 | 不要 |
| --validate-object | 特定オブジェクトを検証 | 必要 |
| --validate-if-needed | 必要時のみ検証 | 不要 |
| --prune | 不要データを削除 | 不要 |

### 入力データソース

- コマンドライン引数
- データファイル（--data）
- 標準入力（--data -）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| CAS ID | 文字列 | 作成/取得されたオブジェクトのID |
| オブジェクトデータ | バイナリ | cat-node-data時のデータ内容 |
| 参照一覧 | 文字列リスト | ls-node-refs時の参照ID |
| 検証結果 | 文字列 | validate系コマンドの結果メッセージ |

### 出力先

標準出力

## 処理フロー

### 処理シーケンス

```
1. 引数解析
   └─ コマンドと引数の解析
2. CASオープン
   └─ createOnDiskUnifiedCASDatabasesでCAS/ACを開く
3. コマンド実行
   └─ コマンド種別に応じた処理
4. 結果出力
   └─ CAS IDまたは結果メッセージを出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[引数解析]
    B --> C{コマンド種別}
    C -->|validate-if-needed| D[validateIfNeeded]
    C -->|その他| E[CAS/ACオープン]
    E --> F{コマンド分岐}
    F -->|dump| G[dump]
    F -->|validate| H[validate]
    F -->|make-blob| I[makeBlob]
    F -->|make-node| J[makeNode]
    F -->|prune| K[prune]
    F -->|import| L[import]
    F -->|put-cache-key| M[putCacheKey]
    F -->|get-cache-result| N[getCacheResult]
    F -->|ls-node-refs| O[listObjectReferences]
    F -->|cat-node-data| P[catNodeData]
    F -->|validate-object| Q[validateObject]
    D --> R[終了]
    G --> R
    H --> R
    I --> R
    J --> R
    K --> R
    L --> R
    M --> R
    N --> R
    O --> R
    P --> R
    Q --> R
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-104-1 | CASパス必須 | --casオプションは全コマンドで必須 | 常時 |
| BR-104-2 | キャッシュキーペア | put-cache-keyは偶数個の引数が必要 | put-cache-key時 |
| BR-104-3 | 単一オブジェクト | 一部コマンドは1つのオブジェクトのみ指定可 | cat-node-data等 |

### 計算ロジック

CAS IDはオブジェクトのコンテンツハッシュ（SHA-256等）として計算される。

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

### 操作別データベース影響一覧

| 操作 | 対象 | 操作種別 | 概要 |
|-----|------|---------|------|
| make-blob | CAS | INSERT | 新規BLOBオブジェクト作成 |
| make-node | CAS | INSERT | 新規ノードオブジェクト作成 |
| import | CAS | INSERT | 外部CASからオブジェクトコピー |
| put-cache-key | ActionCache | INSERT | キャッシュエントリ追加 |
| prune | CAS | DELETE | 不要データ削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | CASパス未指定 | --casが未指定 | エラーメッセージ、終了 |
| - | 入力不足 | 必要なオブジェクトIDが未指定 | エラーメッセージ、終了 |
| - | オブジェクト未発見 | 指定IDがCASに存在しない | エラーメッセージ、終了 |
| - | 検証失敗 | CASデータが破損 | 検証結果を報告 |

### リトライ仕様

特になし

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

CASは内部的にアトミック操作を保証。

## パフォーマンス要件

特に定義なし。大規模CASの操作は時間がかかる場合がある。

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

CASディレクトリへのアクセス権限により保護される。

## 備考

CASはビルドシステムとの統合が前提。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ObjectStore.h | `llvm/include/llvm/CAS/ObjectStore.h` | ObjectStore、CASID、ObjectProxyクラス |
| 1-2 | ActionCache.h | `llvm/include/llvm/CAS/ActionCache.h` | ActionCacheクラス |

**読解のコツ**: CASIDがコンテンツハッシュであり、ObjectStoreがキー・バリューストアとして機能することを理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | llvm-cas.cpp | `llvm/tools/llvm-cas/llvm-cas.cpp` | main関数、コマンド種別enum |
| 2-2 | Options.td | `llvm/tools/llvm-cas/Options.td` | コマンドラインオプション定義 |

**主要処理フロー**:
1. **192-254行目**: main関数
2. **142-190行目**: parseOptions関数で引数解析
3. **198-200行目**: validate-if-needed時は別処理
4. **202行目**: createOnDiskUnifiedCASDatabasesでCAS/ACオープン
5. **205-253行目**: コマンド種別に応じた処理分岐

#### Step 3: 各コマンドの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | llvm-cas.cpp | `llvm/tools/llvm-cas/llvm-cas.cpp` | 各コマンド関数（264-405行目） |

**主要処理フロー**:
- **264-268行目**: dump関数 - CAS.print()でダンプ
- **270-277行目**: makeBlob関数 - CAS.createProxy()でBLOB作成
- **279-283行目**: catNodeData関数 - CAS.getProxy().getData()でデータ取得
- **285-295行目**: listObjectReferences関数 - Object.forEachReference()で参照列挙
- **297-316行目**: makeNode関数 - 参照とデータからノード作成
- **318-332行目**: import関数 - ToCAS.importObject()でインポート
- **334-347行目**: putCacheKey関数 - AC.put()でキャッシュ設定
- **349-359行目**: getCacheResult関数 - AC.get()でキャッシュ取得
- **361-366行目**: validateObject関数 - CAS.validateObject()で検証
- **368-374行目**: validate関数 - CAS.validate()、AC.validate()で全体検証
- **376-399行目**: validateIfNeeded関数 - 条件付き検証
- **401-405行目**: prune関数 - CAS.pruneStorageData()でプルーニング

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

```
main (192行目)
    │
    ├─ parseOptions (196行目)
    │      └─ コマンド種別とオプション解析
    │
    ├─ validateIfNeeded (199行目)
    │      └─ validateOnDiskUnifiedCASDatabasesIfNeeded
    │
    └─ createOnDiskUnifiedCASDatabases (202行目)
           │
           ├─ dump (206行目)
           │      └─ CAS.print()
           │
           ├─ validate (208-209行目)
           │      ├─ CAS.validate()
           │      └─ AC.validate()
           │
           ├─ makeBlob (211-212行目)
           │      └─ CAS.createProxy({}, data)
           │
           ├─ makeNode (214-215行目)
           │      └─ CAS.createProxy(refs, data)
           │
           ├─ prune (217-218行目)
           │      └─ CAS.pruneStorageData()
           │
           ├─ import (220-227行目)
           │      └─ ToCAS.importObject(FromCAS, ref)
           │
           ├─ putCacheKey (235-236行目)
           │      └─ AC.put(key, result)
           │
           ├─ getCacheResult (243-244行目)
           │      └─ AC.get(id)
           │
           ├─ listObjectReferences (246-247行目)
           │      └─ Object.forEachReference()
           │
           ├─ catNodeData (249-250行目)
           │      └─ CAS.getProxy(id).getData()
           │
           └─ validateObject (252-253行目)
                  └─ CAS.validateObject(id)
```

### データフロー図

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

データ/参照 ───▶ make-blob/make-node ───▶ CAS ID
                      │
                      └─ ObjectStore

CAS ID ───▶ cat-node-data ───▶ データ内容
               │
               └─ ObjectStore.getProxy()

キー/結果 ───▶ put-cache-key ───▶ 成功メッセージ
                  │
                  └─ ActionCache.put()

キー ───▶ get-cache-result ───▶ キャッシュ結果
             │
             └─ ActionCache.get()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| llvm-cas.cpp | `llvm/tools/llvm-cas/llvm-cas.cpp` | ソース | メインエントリーポイント |
| Options.td | `llvm/tools/llvm-cas/Options.td` | TableGen | コマンドラインオプション定義 |
| CMakeLists.txt | `llvm/tools/llvm-cas/CMakeLists.txt` | ビルド設定 | ビルド構成 |
| ObjectStore.h | `llvm/include/llvm/CAS/ObjectStore.h` | ヘッダ | CASストアAPI |
| ActionCache.h | `llvm/include/llvm/CAS/ActionCache.h` | ヘッダ | アクションキャッシュAPI |
| BuiltinUnifiedCASDatabases.h | `llvm/include/llvm/CAS/BuiltinUnifiedCASDatabases.h` | ヘッダ | 統合CAS/ACファクトリ |
