# 機能設計書 110-first_key

## 概要

本ドキュメントは、Hack Standard Library（HSL）の `C\first_key` 関数の機能設計書である。この関数は、KeyedTraversableの最初のキーを取得する。

### 本機能の処理概要

`C\first_key` 関数は、与えられた `KeyedTraversable` の最初の要素の**キー**を返す関数である。KeyedTraversable が空の場合は `null` を返す。`C\first` が値を返すのに対し、本関数はキーを返す点が異なる。

**業務上の目的・背景**：コレクションの先頭要素のキー（インデックスや辞書キー）へのアクセスは、様々な場面で必要となる。例えば、dict の最初のキーを取得してそのエントリを削除する、vec の先頭インデックスを確認する、反復処理の開始位置を特定するなどの用途がある。O(1) の計算量で高速にキーを取得できるため、効率的なプログラミングが可能である。

**機能の利用シーン**：
- dict の最初のキーを取得して特定の操作を行う場合
- 順序付きマップの先頭キーを取得する場合
- 検索結果の最初のレコードのIDを取得する場合
- イテレーションの開始位置を確認する場合
- キーに基づいた後続の処理（更新、削除など）を行う前にキーを取得する場合

**主要な処理内容**：
1. 入力パラメータとして KeyedTraversable を受け取る
2. KeyedContainer の場合は _Private\Native\first_key を呼び出す
3. それ以外の場合は foreach で最初のキーを取得
4. 空の場合は null を返す

**関連システム・外部連携**：なし（純粋な関数であり、外部システムへの依存はない）

**権限による制御**：なし（ライブラリ関数のため権限制御は不要）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 該当なし | - | 本プロジェクトはUIを持たないライブラリのため画面は存在しない |

## 機能種別

選択処理 / アクセス処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $traversable | KeyedTraversable<Tk, Tv> | Yes | 最初のキーを取得する対象のKeyedTraversable | なし |

### 入力データソース

関数呼び出し元から引数として渡される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | ?Tk | 最初の要素のキー。空の場合は `null` |

### 出力先

関数の戻り値として呼び出し元に返される。

## 処理フロー

### 処理シーケンス

```
1. KeyedTraversable を引数として受け取る
   └─ 型パラメータ Tk はキーの型、Tv は値の型
2. KeyedTraversable が KeyedContainer かどうかを判定
   └─ KeyedContainer の場合は最適化されたパスを使用
3a. KeyedContainer の場合: _Private\Native\first_key を呼び出す
   └─ HHVM 内蔵の最適化された関数を使用
3b. それ以外の場合: foreach で最初のキーを取得
   └─ foreach ($traversable as $key => $_) で最初のキーを取得
4. 空の KeyedTraversable の場合は null を返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[traversable を受け取る]
    B --> C{KeyedContainer?}
    C -->|Yes| D[_Private\Native\first_key を呼び出す]
    C -->|No| E[foreach ループ開始]
    E --> F{要素あり?}
    F -->|Yes| G[最初のキーを返す]
    F -->|No| H[null を返す]
    D --> I[結果を返す]
    G --> I
    H --> I
    I --> J[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-110-01 | 空コレクション対応 | 空の KeyedTraversable に対しては null を返す | KeyedTraversableが空の場合 |
| BR-110-02 | KeyedContainer最適化 | KeyedContainer の場合は O(1) のネイティブ関数を使用 | KeyedContainer型の場合 |
| BR-110-03 | 順序保持 | KeyedTraversable の反復順序に従った最初のキーを返す | 常に適用 |
| BR-110-04 | キー型保持 | 戻り値はキーの型（Tk）を保持する | 常に適用 |

### 計算ロジック

特になし（キー取得のみで複雑な計算処理は含まれない）

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

該当なし（本機能はインメモリのコレクション操作のみを行う）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| TypeError | 型エラー | KeyedTraversable 型以外を渡した場合 | 型チェッカーがコンパイル時に検出 |

### リトライ仕様

該当なし（同期処理であり、リトライの必要性はない）

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

該当なし（データベース操作を行わない純粋関数）

## パフォーマンス要件

- 時間計算量: O(1)
- 空間計算量: O(1)

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

- 純粋関数であり、外部への副作用がないためセキュリティリスクは低い
- 読み取り専用の操作であり、入力データは変更されない

## 備考

- 空でないことが保証される場合は `C\first_keyx` を使用する
- `C\first` は値を返すが、本関数はキーを返す
- vec の場合、キーは 0 始まりのインデックス（int）で、空でなければ必ず 0 を返す
- dict の場合、キーは最初に挿入されたキーを返す
- Generator を使用する場合、yield されたキーを返す
- 関連関数: `C\first_keyx`（必須版）、`C\first`（値取得版）、`C\last_key`（末尾キー取得版）

---

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

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

### 推奨読解順序

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

本関数で扱うデータ構造は、Hack言語の組み込み型である `KeyedTraversable` と `KeyedContainer` である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | (Hack組み込み型) | - | KeyedTraversable<Tk, Tv> は キーと値のペアで反復可能な型の基底インターフェース |
| 1-2 | (Hack組み込み型) | - | KeyedContainer<Tk, Tv> は KeyedTraversable のサブタイプで、count 可能な型 |

**読解のコツ**: `KeyedContainer` は `KeyedTraversable` より具体的な型であり、dict、vec、keyset、Map、Vector、Set などが該当する。KeyedContainer に対しては最適化されたネイティブ関数が使用される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | select.php | `src/c/select.php` | C\first_key 関数の定義を確認 |

**主要処理フロー**:
1. **134-142行目**: 関数のドキュメントコメント
2. **138行目**: first_keyx への参照
3. **143-153行目**: `first_key` 関数の定義
4. **146-148行目**: KeyedContainer の場合は _Private\Native\first_key を使用
5. **149-151行目**: それ以外は foreach で最初のキーを取得
6. **152行目**: 空の場合は null を返す

#### Step 3: 関連関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | select.php | `src/c/select.php` | first_keyx、last_key との違いを理解 |

**主要処理フロー**:
- **164-180行目**: `C\first_keyx` 関数 - 必須版（空の場合は例外）
- **253-267行目**: `C\last_key` 関数 - 末尾キー取得版

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

```
C\first_key($traversable)
    │
    ├─ $traversable is KeyedContainer<_, _>
    │      │
    │      └─ _Private\Native\first_key($traversable)  [HHVM内蔵関数]
    │
    └─ foreach ($traversable as $key => $_)
           │
           └─ return $key  [最初のイテレーション]
```

### データフロー図

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

KeyedTraversable<Tk, Tv> ──▶ KeyedContainer判定 ──┬──▶ Native\first_key() ──▶ ?Tk
                                                   │
                                                   └──▶ foreach           ──▶ ?Tk or null
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| select.php | `src/c/select.php` | ソース | C\first_key 関数の実装（143-153行目） |
| CSelectTest.php | `tests/c/CSelectTest.php` | テスト | first_key のユニットテスト（189-255行目） |
