# 機能設計書 20-Queue

## 概要

本ドキュメントは、VBCorLibライブラリにおける先入れ先出しコレクション機能「Queue」クラスの機能設計について記述する。

### 本機能の処理概要

Queueクラスは、先入れ先出し（FIFO: First-In-First-Out）のコレクションを提供するクラスである。.NET FrameworkのSystem.Collections.Queueクラスと互換性のあるAPIを持ち、内部に循環バッファ（Circular Buffer）として実装されたVariant配列を持つ。Enqueue操作でキューの末尾に要素を追加し、Dequeue操作で先頭の要素を取り出す。

**業務上の目的・背景**：キューはメッセージ処理、タスクスケジューリング、幅優先探索、バッファリングなど、様々な場面で使用される基本データ構造である。VBAには標準でキュー構造がないため、Queueクラスがこのギャップを埋める。

**機能の利用シーン**：
- メッセージキューの実装
- タスクの順次処理
- 幅優先探索（BFS）アルゴリズム
- プリンタージョブキュー
- イベントキューイング

**主要な処理内容**：
1. 要素追加（Enqueue）- キュー末尾への追加
2. 要素取り出し（Dequeue）- キュー先頭からの取り出し
3. 要素参照（Peek）- キュー先頭の参照（取り出さない）
4. 検索（Contains）- 要素の存在確認
5. 変換（ToArray、CopyTo）
6. 容量管理（TrimToSize、Clear）

**関連システム・外部連携**：ICollection、IEnumerable、ICloneableインターフェースを実装し、他のVBCorLibコンポーネントとの相互運用が可能。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Simply VB Unit Runner | 主画面 | テストスイート内のQueueテスト（QueueTests）の実行 |

## 機能種別

コレクション処理 / データ構造

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Value | Variant | Yes | Enqueueで追加する値 | 任意の値（オブジェクト含む） |
| Value | Variant | Yes | Containsで検索する値 | 任意の値 |
| Arr | Variant | Yes | CopyToのコピー先配列 | 1次元配列 |
| Index | Long | Yes | CopyToの開始インデックス | 配列下限以上 |

### 入力データソース

プログラムからの直接呼び出し（パラメータ指定）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Dequeue戻り値 | Variant | キュー先頭から取り出した要素 |
| Peek戻り値 | Variant | キュー先頭の要素（取り出さない） |
| Contains戻り値 | Boolean | 要素の存在有無 |
| ToArray戻り値 | Variant() | 配列に変換された要素（FIFO順） |
| Count | Long | 要素数 |
| Clone戻り値 | Queue | 浅いコピー |

### 出力先

呼び出し元への戻り値として返却

## 処理フロー

### 処理シーケンス

```
1. インスタンス生成
   └─ 初期容量（デフォルト16）でVariant配列確保
   └─ mHead=0, mTail=0, mCount=0に初期化

2. Enqueue呼び出し
   └─ EnsureCapacityで容量確認
   └─ mItems(mTail)に要素追加
   └─ mTail = (mTail + 1) Mod mCapacity
   └─ Count++
   └─ Version++

3. Dequeue呼び出し
   └─ Countが0なら例外
   └─ mItems(mHead)の値を取得
   └─ mItems(mHead)をクリア
   └─ mHead = (mHead + 1) Mod mCapacity
   └─ Count--
   └─ Version++
   └─ 取得した値を返却

4. Peek呼び出し
   └─ Countが0なら例外
   └─ mItems(mHead)の値を返却（削除しない）
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{メソッド種別}
    B -->|Enqueue| C[EnsureCapacity]
    C --> D[mItems(mTail) = Value]
    D --> E[mTail = (mTail + 1) Mod mCapacity]
    E --> F[mCount++]
    F --> G[mVersion++]
    G --> H[終了]
    B -->|Dequeue| I{mCount > 0?}
    I -->|No| J[InvalidOperationException]
    I -->|Yes| K[Result = mItems(mHead)]
    K --> L[mItems(mHead) = Empty]
    L --> M[mHead = (mHead + 1) Mod mCapacity]
    M --> N[mCount--]
    N --> G
    B -->|Peek| O{mCount > 0?}
    O -->|No| P[InvalidOperationException]
    O -->|Yes| Q[Return mItems(mHead)]
    Q --> H
    B -->|Contains| R[ループで全要素検索]
    R --> S{見つかった?}
    S -->|Yes| T[Return True]
    S -->|No| U[Return False]
    T --> H
    U --> H
    J --> H
    P --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | FIFO順序 | 先に追加した要素が先に取り出される | Enqueue/Dequeue操作 |
| BR-002 | デフォルト容量 | 初期容量は16要素 | 新規インスタンス生成時 |
| BR-003 | 容量拡張戦略 | 容量不足時は現在の2倍に拡張 | EnsureCapacity時 |
| BR-004 | 循環バッファ | 内部配列は循環バッファとして使用 | 全操作 |
| BR-005 | 空キュー操作 | 空キューへのDequeue/PeekはInvalidOperationException | Dequeue/Peek呼び出し時 |
| BR-006 | シャローコピー | Cloneは浅いコピーを作成 | Clone呼び出し時 |
| BR-007 | バージョン管理 | 変更時にVersionをインクリメント | Enqueue/Dequeue/Clear |
| BR-008 | TrimToSize | TrimToSizeは配列を正規化してCountに容量を縮小 | TrimToSize呼び出し時 |

### 計算ロジック

**循環バッファのインデックス計算**:
```
' Enqueue: 末尾への追加
mTail = (mTail + 1) Mod mCapacity

' Dequeue: 先頭からの取り出し
mHead = (mHead + 1) Mod mCapacity

' 要素アクセス（i番目の要素）
Index = (mHead + i) Mod mCapacity
```

**NormalizeArray（配列正規化）**:
```
' mHead=0となるように配列を再配置
If mHead < mTail Then
    ' 連続領域: そのままコピー
    CopyMemory NewItems(0), mItems(mHead), (mTail - mHead) * vbSizeOfVariant
Else
    ' ラップアラウンド: 2回に分けてコピー
    CopyMemory NewItems(0), mItems(mHead), (mCapacity - mHead) * vbSizeOfVariant
    CopyMemory NewItems(mCapacity - mHead), mItems(0), mHead * vbSizeOfVariant
End If
```

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | InvalidOperationException | 空キューへのDequeue | Countを確認してから操作 |
| - | InvalidOperationException | 空キューへのPeek | Countを確認してから操作 |
| - | ArgumentNullException | CopyToでArrがNull | 有効な配列を指定 |
| - | ArgumentException | CopyToで多次元配列 | 1次元配列を使用 |
| - | ArgumentOutOfRangeException | CopyToでIndex < LBound | 有効なインデックスを指定 |

### リトライ仕様

コレクション操作処理であるため、リトライは不要。

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

本機能はトランザクション処理を行わない。

## パフォーマンス要件

- Enqueue: O(1)の償却定数時間（容量拡張時を除く）
- Dequeue: O(1)の定数時間
- Peek: O(1)の定数時間
- Contains: O(n)の線形時間
- TrimToSize: O(n)（配列の再配置が必要）

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

- 参照型要素は浅いコピーとなるため、Clone後も同一オブジェクトを参照
- Dequeue後は内部配列からの参照をクリアしてメモリリークを防止

## 備考

- 循環バッファにより、Dequeue時に要素の移動が不要で高効率
- Persistable属性を持ち、PropertyBagによるシリアライズが可能
- IVersionableインターフェースでバージョン追跡を実装

---

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

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

### 推奨読解順序

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

Queueクラスは循環バッファとして実装されている。mHeadが先頭、mTailが末尾を指し、配列をリング状に使用する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Queue.cls | `Source/CorLib/System.Collections/Queue.cls` | クラス構造、メンバ変数、循環バッファの概念 |

**主要なメンバ変数**:
- **56行目**: `mItems() As Variant` - 内部配列
- **57行目**: `mHead As Long` - 先頭インデックス
- **58行目**: `mTail As Long` - 末尾インデックス（次の追加位置）
- **59行目**: `mCapacity As Long` - 配列容量
- **60行目**: `mCount As Long` - 要素数
- **61行目**: `mVersion As Long` - バージョン

**実装インターフェース**（43-47行目）:
- IObject, ICloneable, ICollection, IEnumerable, IVersionable

#### Step 2: Enqueue/Dequeue/Peekを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Queue.cls | `Source/CorLib/System.Collections/Queue.cls` | Enqueue、Dequeue、Peek |

**主要処理フロー**:
1. **167-173行目**: Enqueueメソッド - EnsureCapacity後に末尾に追加、mTailを循環更新
2. **150-158行目**: Dequeueメソッド - 先頭から取り出し、mHeadを循環更新
3. **224-229行目**: Peekメソッド - 先頭を参照（削除しない）

#### Step 3: 循環バッファ管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Queue.cls | `Source/CorLib/System.Collections/Queue.cls` | NormalizeArray、EnsureCapacity |

**主要処理フロー**:
- **302-323行目**: NormalizeArrayメソッド - 配列を正規化（mHead=0に）
- **325-339行目**: EnsureCapacityメソッド - 容量拡張時にNormalizeArrayを呼び出し

#### Step 4: 検索・変換・クローンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Queue.cls | `Source/CorLib/System.Collections/Queue.cls` | Contains、ToArray、CopyTo、Clone |

**主要処理フロー**:
- **98-110行目**: Containsメソッド - 循環バッファを考慮したループ検索
- **237-246行目**: ToArrayメソッド - CopyToを利用
- **119-128行目**: CopyToメソッド - mHead位置に応じた2パターンのコピー
- **86-89行目**: Cloneメソッド - InitCloneで浅いコピー

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

```
Queue (インスタンス)
    │
    ├─ Enqueue(Value)
    │      ├─ EnsureCapacity(mCount + 1)
    │      │      └─ NormalizeArray (拡張時)
    │      ├─ VariantCopyInd(mItems(mTail), Value)
    │      └─ mTail = (mTail + 1) Mod mCapacity
    │
    ├─ Dequeue()
    │      ├─ 空チェック
    │      ├─ Helper.MoveVariant(Dequeue, mItems(mHead))
    │      └─ mHead = (mHead + 1) Mod mCapacity
    │
    ├─ Peek()
    │      ├─ 空チェック
    │      └─ VariantCopy(Peek, mItems(mHead))
    │
    ├─ Contains(Value)
    │      └─ 循環ループ: Object.Equals比較
    │
    ├─ ToArray()
    │      └─ CopyTo(Result, 0)
    │
    ├─ CopyTo(Arr, Index)
    │      ├─ mHead < mTail の場合: 連続コピー
    │      └─ それ以外: 2回に分けてコピー
    │
    ├─ Clone()
    │      └─ New Queue.InitClone(mItems, mCount, mHead, mTail)
    │
    ├─ TrimToSize()
    │      └─ NormalizeArray(mCount)
    │
    └─ Clear()
           └─ ReDim mItems, mHead=0, mTail=0, mCount=0
```

### データフロー図

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

Value ──────────────▶ Enqueue ──────────────────▶ （なし）
                         │
                         ▼
                 EnsureCapacity
                         │
                         ▼
                 mItems(mTail) = Value
                         │
                         ▼
             mTail = (mTail + 1) Mod mCapacity
                         │
                         ▼
                     mCount++

（なし） ───────────▶ Dequeue ───────────────────▶ Variant
                         │
                         ▼
                 Result = mItems(mHead)
                         │
                         ▼
                 mItems(mHead) = Empty
                         │
                         ▼
             mHead = (mHead + 1) Mod mCapacity
                         │
                         ▼
                     mCount--

循環バッファの動作イメージ:
┌───┬───┬───┬───┬───┬───┬───┬───┐
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
└───┴───┴───┴───┴───┴───┴───┴───┘
      ↑           ↑
    mHead       mTail
    (先頭)      (次の追加位置)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Queue.cls | `Source/CorLib/System.Collections/Queue.cls` | ソース | メインクラス定義 |
| QueueTests.cls | `Source/Tests/System.Collections/QueueTests.cls` | テスト | 単体テストケース |
| QueueEnumerator.cls | `Source/CorLib/System.Collections/QueueEnumerator.cls` | ソース | For Each用列挙子 |
| ICollection.cls | `Source/CorLib/System.Collections/ICollection.cls` | ソース | コレクションインターフェース |
| Constructors.cls | `Source/CorLib/Constructors.cls` | ソース | NewQueueコンストラクタ |
