# 画面設計書 166-Cat PITセグメント

## 概要

本ドキュメントは、OpenSearchのCat PIT Segments API（`GET /_cat/pit_segments`）の画面設計書である。Point in Time（PIT）のセグメント情報をテーブル形式で返すREST APIエンドポイントについて、入出力仕様・処理フロー・データベース影響等を定義する。

### 本画面の処理概要

Cat PIT Segments APIは、アクティブなPoint in Time検索コンテキストに関連するLuceneセグメントの低レベル情報を、人間が読みやすいテーブル形式で返すAPIエンドポイントである。

**業務上の目的・背景**：PIT（Point in Time）を使用した検索において、PITが参照しているセグメントの詳細情報を確認する必要がある場合がある。本APIにより、PITに関連するインデックスのシャードごとのセグメント情報（セグメント名、ドキュメント数、サイズ、コミット状態、検索可能性、バージョン等）を確認でき、PITがリソースに与える影響の診断やセグメントマージの効果確認を支援する。

**画面へのアクセス方法**：HTTPクライアントから `GET /_cat/pit_segments` または `GET /_cat/pit_segments/_all` にリクエストを送信する。特定PITのセグメント情報を取得する場合はリクエストボディにPIT IDを指定する。

**主要な操作・処理内容**：
1. リクエストパスに`_all`が含まれる場合は全PIT、それ以外はリクエストボディからPIT IDを取得する
2. `PitSegmentsAction`を実行してインデックスセグメント情報を取得する
3. インデックス > シャード > セグメントの階層構造を走査してテーブル行を構築する
4. 各セグメントの名前、世代、ドキュメント数、サイズ、コミット状態等をテーブル形式で返す

**画面遷移**：本APIは単独で使用される。PIT作成（`POST /{index}/_search/point_in_time`）でPITを作成した後に、本APIでセグメント情報を確認する流れが一般的である。

**権限による表示制御**：システムインデックスへのアクセスがデフォルトで許可されている（`allowSystemIndexAccessByDefault`がtrue）。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 23 | Point in Time（PIT） | 主機能 | PITのセグメント情報をテーブル形式で返す処理 |
| 121 | セグメント情報 | 補助機能 | セグメント情報の取得処理 |

## 画面種別

一覧（テーブル形式表示）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| GET | `/_cat/pit_segments` | 特定PIT（リクエストボディ指定）のセグメント情報を返す |
| GET | `/_cat/pit_segments/_all` | 全PITのセグメント情報を返す |

## 入出力項目

### リクエストパラメータ

| パラメータ名 | 型 | 必須 | デフォルト | 説明 |
|-------------|------|------|-----------|------|
| format | string | No | text | レスポンス形式 |
| h | list | No | - | 表示するカラム名のカンマ区切りリスト |
| help | boolean | No | false | ヘルプ情報を返す |
| s | list | No | - | ソートするカラム名のカンマ区切りリスト |
| v | boolean | No | false | カラムヘッダを表示するか |

### リクエストボディ（`/_cat/pit_segments`の場合）

| フィールド | 型 | 必須 | 説明 |
|-----------|------|------|------|
| pit_id | list | No | 対象PIT IDのリスト |

## 表示項目

| カラム名 | エイリアス | デフォルト表示 | 説明 |
|---------|----------|-------------|------|
| index | i, idx | Yes | インデックス名 |
| shard | s, sh | Yes | シャード番号 |
| prirep | p, pr, primaryOrReplica | Yes | プライマリ(p)/レプリカ(r) |
| ip | - | Yes | ノードのIPアドレス |
| id | - | No | ノードの一意ID |
| segment | seg | Yes | セグメント名 |
| generation | g, gen | Yes | セグメント世代 |
| docs.count | dc, docsCount | Yes | セグメント内ドキュメント数 |
| docs.deleted | dd, docsDeleted | Yes | セグメント内削除済みドキュメント数 |
| size | si | Yes | セグメントサイズ（バイト） |
| size.memory | sm, sizeMemory | Yes | セグメントメモリサイズ（バイト、常時0） |
| committed | ic, isCommitted | Yes | セグメントがコミット済みか |
| searchable | is, isSearchable | Yes | セグメントが検索可能か |
| version | v, ver | Yes | Luceneバージョン |
| compound | ico, isCompound | Yes | コンパウンドセグメントか |

## イベント仕様

### 1-GETリクエスト受信

1. `RestPitSegmentsAction.doCatRequest()`がリクエストを受信する
2. パスに`_all`が含まれる場合は全PIT対象の`PitSegmentsRequest`を構築する
3. それ以外の場合はリクエストボディからPIT IDをパースして`PitSegmentsRequest`を構築する
4. `client.execute(PitSegmentsAction.INSTANCE, ...)`を実行する
5. `buildTable()`でインデックス > シャード > セグメントの3階層を走査してテーブル行を構築する

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| GETリクエスト | - | SELECT | PITセグメント情報を参照のみ。データ更新なし |

## メッセージ仕様

| 種別 | 条件 | メッセージ/レスポンス |
|------|------|---------------------|
| 成功 | 正常取得時 | テーブル形式のセグメント情報（HTTPステータス200） |
| 成功 | PITなし/セグメントなし | 空テーブル（HTTPステータス200） |
| エラー | リクエストボディパース失敗 | IllegalArgumentException "Failed to parse request body" |
| エラー | 無効なPIT ID | PIT関連エラー |

## 例外処理

- リクエストボディのパースに失敗した場合は`IllegalArgumentException`（"Failed to parse request body"）をスローする（行76-77）
- 存在しないPIT IDを指定した場合はPIT関連のエラーレスポンスを返す
- ノード情報の取得時にノードが見つからない場合は`NullPointerException`の可能性がある

## 備考

- `size.memory`カラムは常に0Lを返す（行142）。これはLuceneの変更によりセグメントメモリの正確な値が取得できなくなったためと考えられる
- `_all`パスと通常パスの2つのルートがある。`_all`の場合はPIT ID指定不要
- `nodesInCluster` SupplierでDiscoveryNodesをリアルタイムに取得する
- prirep列はprimary()がtrueなら"p"、それ以外は"r"（検索専用の区別はない）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Segment.java | `server/src/main/java/org/opensearch/index/engine/Segment.java` | セグメント情報の構造（name, generation, numDocs, deletedDocs, size, committed, search, version, compound） |
| 1-2 | IndexSegments.java | `server/src/main/java/org/opensearch/action/admin/indices/segments/IndexSegments.java` | インデックス単位のセグメント集約 |
| 1-3 | PitSegmentsRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/segments/PitSegmentsRequest.java` | リクエストオブジェクト（PIT ID指定） |

**読解のコツ**: IndexSegments > IndexShardSegments > ShardSegments > Segment の4階層構造を理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestPitSegmentsAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestPitSegmentsAction.java` | AbstractCatActionを継承したRESTハンドラ |

**主要処理フロー**:
1. **行48-49**: ルート定義 `/_cat/pit_segments/_all` と `/_cat/pit_segments`
2. **行63-88**: `doCatRequest()`でPitSegmentsRequestを構築し実行
3. **行97-117**: `getTableWithHeader()`で15カラムを定義
4. **行119-154**: `buildTable()`で3階層ループでテーブル行を構築

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

```
RestPitSegmentsAction.doCatRequest() [行63]
    |
    +-- パス判定 (_all or specific) [行64-79]
    |       +-- _all: PitSegmentsRequest("_all")
    |       +-- other: PitSegmentsRequest + fromXContent()
    |
    +-- client.execute(PitSegmentsAction.INSTANCE, ...) [行80]
    |       |
    |       +-- PitSegmentsAction
    |               +-- PIT関連セグメント情報取得
    |               +-- IndicesSegmentResponse構築
    |
    +-- buildTable() [行119]
    |       +-- IndexSegmentsループ [行124]
    |           +-- IndexShardSegmentsループ [行126]
    |               +-- ShardSegmentsループ [行128]
    |                   +-- Segmentループ [行130]
    |                       +-- テーブル行構築 [行131-147]
    |
    +-- RestTable.buildResponse() [行85]
```

### データフロー図

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

GET /_cat/pit_segments  ---> RestPitSegmentsAction          テーブル形式
  /_all                       |                              レスポンス
  (or body: pit_id)           +-> PitSegmentsAction
                              |     +-> PIT -> Segments
                              |     +-> IndicesSegmentResponse
                              +-> buildTable()
                              |     +-> 4階層ループ
                              +-> RestTable.buildResponse()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestPitSegmentsAction.java | `server/src/main/java/org/opensearch/rest/action/cat/RestPitSegmentsAction.java` | ソース | RESTエンドポイントハンドラ |
| PitSegmentsAction.java | `server/src/main/java/org/opensearch/action/admin/indices/segments/PitSegmentsAction.java` | ソース | トランスポートアクション定義 |
| PitSegmentsRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/segments/PitSegmentsRequest.java` | ソース | リクエストオブジェクト |
| IndicesSegmentResponse.java | `server/src/main/java/org/opensearch/action/admin/indices/segments/IndicesSegmentResponse.java` | ソース | レスポンスオブジェクト |
| Segment.java | `server/src/main/java/org/opensearch/index/engine/Segment.java` | ソース | セグメント情報データ構造 |
| IndexSegments.java | `server/src/main/java/org/opensearch/action/admin/indices/segments/IndexSegments.java` | ソース | インデックス単位セグメント集約 |
