# 機能設計書 37-strtabs

## 概要

本ドキュメントは、Nimプログラミング言語の文字列テーブルモジュールである`strtabs`モジュールの機能設計を記載する。strtabsモジュールは文字列から文字列へのマッピングを行う効率的なハッシュテーブルを提供し、大文字小文字の区別やスタイルの区別についてのモードをサポートする。

### 本機能の処理概要

strtabsモジュールはStringTableRef型を提供し、文字列キーと文字列値のペアを効率的に格納・検索できる。比較モードとして、大文字小文字を区別するモード、区別しないモード、スタイルを無視するモードの3種類をサポート。

**業務上の目的・背景**：設定ファイル、HTTPヘッダー、環境変数など、文字列から文字列へのマッピングが必要な場面は多い。特にHTTPヘッダーのように大文字小文字を区別しない場合や、Nim識別子のようにスタイルを無視する場合に、strtabsモジュールが有用。%演算子による文字列置換機能も提供し、テンプレート処理に便利。

**機能の利用シーン**：
- 設定ファイルの読み込み・保存
- HTTPヘッダーの処理
- 環境変数の管理
- テンプレート文字列の置換
- キーバリューストアの実装

**主要な処理内容**：
1. StringTableRef型の作成（newStringTable）
2. キーと値の追加・更新（[]=）
3. 値の取得（[], getOrDefault）
4. キーの存在確認（hasKey, contains, in）
5. キーの削除（del, clear）
6. イテレーション（pairs, keys, values）
7. 文字列置換（%演算子）
8. 3つの比較モード（modeCaseSensitive, modeCaseInsensitive, modeStyleInsensitive）

**関連システム・外部連携**：hashesモジュールのハッシュ関数を使用。strutilsモジュールの比較関数を使用。

**権限による制御**：権限による制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面には関連しない（ライブラリモジュール） |

## 機能種別

データ構造 / ハッシュテーブル / 文字列処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| mode | StringTableMode | No | 比較モード（デフォルト: modeCaseSensitive） | enum値 |
| key | string | Yes | キー文字列 | なし |
| val | string | Yes | 値文字列 | なし |
| keyValuePairs | varargs | No | 初期化用のキーバリューペア | なし |

### 入力データソース

プログラム内の文字列データ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| StringTableRef | ref StringTableObj | 文字列テーブルへの参照 |
| value | string | キーに対応する値 |
| exists | bool | キーの存在確認結果 |
| count | int | キーの数 |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. テーブルの作成
   └─ newStringTableで初期化
2. ハッシュ計算
   └─ モードに応じたハッシュ関数を使用
3. キーの検索
   └─ 線形探査法でスロットを検索
4. 値の操作
   └─ 挿入、更新、取得、削除
5. リハッシュ
   └─ 負荷率が高くなったら拡張
```

### フローチャート

```mermaid
flowchart TD
    A[操作要求] --> B{操作種別}
    B -->|挿入| C[ハッシュ計算]
    B -->|検索| D[rawGet呼び出し]
    B -->|削除| E[キー検索]
    C --> F{既存キー?}
    F -->|Yes| G[値を更新]
    F -->|No| H{リハッシュ必要?}
    H -->|Yes| I[テーブル拡張]
    H -->|No| J[新規挿入]
    I --> J
    D --> K{見つかった?}
    K -->|Yes| L[値を返す]
    K -->|No| M[KeyError/デフォルト値]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | modeCaseSensitive | 大文字小文字を区別して比較 | デフォルトモード |
| BR-02 | modeCaseInsensitive | 大文字小文字を無視して比較 | HTTPヘッダー等 |
| BR-03 | modeStyleInsensitive | 大文字小文字無視+アンダースコア無視 | Nim識別子風 |
| BR-04 | リハッシュ条件 | 負荷率が2/3を超えるか、空きが4未満 | 挿入時 |

### 計算ロジック

ハッシュ関数の選択:
- modeCaseSensitive: `hashes.hash(key)`
- modeCaseInsensitive: `hashes.hashIgnoreCase(key)`
- modeStyleInsensitive: `hashes.hashIgnoreStyle(key)`

比較関数の選択:
- modeCaseSensitive: `cmp(a, b) == 0`
- modeCaseInsensitive: `cmpIgnoreCase(a, b) == 0`
- modeStyleInsensitive: `cmpIgnoreStyle(a, b) == 0`

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

### テーブル別操作詳細

データベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| KeyError | Exception | 存在しないキーへのアクセス | hasKeyでチェック、getOrDefault使用 |
| ValueError | Exception | %演算子でキーが見つからない | FormatFlagの設定 |

### リトライ仕様

リトライは不要。事前チェックで対処。

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

トランザクション管理は不要。

## パフォーマンス要件

- 検索、挿入、削除: 平均O(1)
- リハッシュ: O(n)（負荷率に応じて発生）
- 初期サイズ: 64スロット
- 拡張率: 2倍

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

- ハッシュ衝突攻撃に対する耐性は標準的なレベル
- %演算子でuseEnvironmentフラグを使用する場合、環境変数へのアクセスが発生

## 備考

汎用的なハッシュテーブルが必要な場合はtablesモジュールを使用すること。strtabsは文字列から文字列へのマッピングに特化している。

---

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

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

### 推奨読解順序

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

StringTableObj型とStringTableMode列挙型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | strtabs.nim | `lib/pure/strtabs.nim` | StringTableMode列挙型（69-72行目） |
| 1-2 | strtabs.nim | `lib/pure/strtabs.nim` | StringTableObj型（75-80行目） |
| 1-3 | strtabs.nim | `lib/pure/strtabs.nim` | FormatFlag列挙型（82-90行目） |

**読解のコツ**: StringTableObjはcounter（要素数）、data（KeyValuePairのシーケンス）、mode（比較モード）を持つ。

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

モジュール冒頭のドキュメントを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | strtabs.nim | `lib/pure/strtabs.nim` | モジュールドキュメント（10-49行目） |

**主要処理フロー**:
1. **10-12行目**: 文字列から文字列へのハッシュテーブル
2. **26-35行目**: modeStyleInsensitiveの使用例
3. **37-42行目**: %演算子の使用例

#### Step 3: ハッシュ・比較関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | strtabs.nim | `lib/pure/strtabs.nim` | myhash関数（117-121行目） |
| 3-2 | strtabs.nim | `lib/pure/strtabs.nim` | myCmp関数（123-127行目） |

**主要処理フロー**:
- **117-121行目**: モードに応じたハッシュ関数の選択
- **123-127行目**: モードに応じた比較関数の選択

#### Step 4: 基本操作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | strtabs.nim | `lib/pure/strtabs.nim` | rawGet関数（136-142行目） |
| 4-2 | strtabs.nim | `lib/pure/strtabs.nim` | []演算子（155-174行目） |
| 4-3 | strtabs.nim | `lib/pure/strtabs.nim` | []=演算子（237-255行目） |

**主要処理フロー**:
- **136-142行目**: 線形探査法によるキー検索
- **155-174行目**: 値の取得（KeyError発生の可能性）
- **237-255行目**: 値の挿入・更新（リハッシュ処理を含む）

#### Step 5: テーブル作成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | strtabs.nim | `lib/pure/strtabs.nim` | newStringTable（257-297行目） |

**主要処理フロー**:
- **257-264行目**: 空のテーブル作成
- **266-281行目**: 文字列ペアからのテーブル作成
- **283-297行目**: タプルペアからのテーブル作成

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

```
strtabs.nim (メインモジュール)
    │
    ├─ newStringTable
    │      └─ 初期サイズ64のデータ配列を作成
    │
    ├─ []=演算子
    │      ├─ rawGet (キー検索)
    │      ├─ mustRehash (リハッシュ判定)
    │      ├─ enlarge (テーブル拡張)
    │      └─ rawInsert (挿入処理)
    │
    ├─ []演算子
    │      └─ rawGet (キー検索)
    │
    ├─ ハッシュ・比較
    │      ├─ myhash (モード別ハッシュ)
    │      └─ myCmp (モード別比較)
    │
    └─ %演算子
           └─ 文字列置換処理
```

### データフロー図

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

{"name":"John"}  ───▶  newStringTable        ───▶  StringTableRef
                        (テーブル構築)

t["name"]        ───▶  rawGet → []           ───▶  "John"
                        (ハッシュ検索)

t["age"]="30"    ───▶  rawGet → []=          ───▶  テーブル更新
                        (挿入/更新)

"${name}"        ───▶  %演算子              ───▶  "John"
                        (文字列置換)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| strtabs.nim | `lib/pure/strtabs.nim` | ソース | メインモジュール、StringTableRef |
| hashes.nim | `lib/pure/hashes.nim` | ソース | ハッシュ関数（hash, hashIgnoreCase, hashIgnoreStyle） |
| strutils.nim | `lib/pure/strutils.nim` | ソース | 文字列比較（cmpIgnoreCase, cmpIgnoreStyle） |
| envvars.nim | `lib/std/envvars.nim` | ソース | 環境変数アクセス（useEnvironment用） |
