# 画面設計書 10-Speedtest1（Worker版）

## 概要

本ドキュメントは、SQLite3のベンチマークツールspeedtest1のWorkerスレッド実行版（speedtest1-worker.html）の画面設計書です。

### 本画面の処理概要

この画面は、SQLite3の主要ベンチマークツールであるspeedtest1をWASM版でWorkerスレッドで実行し、対話的なフラグ選択UIを提供します。

**業務上の目的・背景**：メインスレッド版（speedtest1.html）と異なり、Workerスレッドで実行することでUIがブロックされず、ユーザーはベンチマーク実行中も画面操作が可能です。また、フラグ選択UIにより、様々な設定でベンチマークを繰り返し実行でき、性能比較が容易になります。VFS選択（memdb、kvvfs、opfs、opfs-sahpool）やスレッドモード設定など、詳細な実験が可能です。

**画面へのアクセス方法**：HTTPサーバー経由で `speedtest1-worker.html` にアクセスします。フラグを選択後、Runボタンでベンチマークを開始します。

**主要な操作・処理内容**：
1. Worker初期化 - speedtest1-worker.jsをWorkerとしてロード
2. フラグ選択 - UIでベンチマークフラグを選択
3. ベンチマーク実行 - Runボタンクリックで実行開始
4. リアルタイム結果表示 - 実行中の出力をリアルタイム表示
5. 他ページへのリンク生成 - 選択フラグ付きでメインスレッド版等へのリンク生成

**画面遷移**：
- 遷移先画面：speedtest1.html（選択フラグ付き）、speedtest1.html?vfs=kvvfs（kvvfs版）
- 遷移元画面：index.html

**権限による表示制御**：なし

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | SQLiteライブラリ初期化 | 主機能 | Worker内でのspeedtest1初期化 |
| 17 | VDBE（仮想データベースエンジン） | 主機能 | Worker内でのVDBE実行ベンチマーク |
| 23 | WAL（Write-Ahead Logging） | 補助機能 | journal_mode設定によるWAL使用 |
| 43 | OS抽象化層（VFS） | 補助機能 | VFS選択（memdb/kvvfs/opfs/opfs-sahpool） |
| 42 | ミューテックス | 補助機能 | --singlethread/--multithread/--serializedフラグ対応 |

## 画面種別

ベンチマーク（対話型）

## URL/ルーティング

`ext/wasm/speedtest1-worker.html`

**URLパラメータ**:
- `vfs`: 使用するVFS名（memdb、kvvfs、opfs、opfs-sahpool）
- `flags`: カンマ区切りの事前選択フラグ
- `size`: テストサイズ
- `journal`: ジャーナルモード
- `cachesize`: キャッシュサイズ
- `opfs-verbose`: OPFS詳細ログ
- `opfs-disable`: OPFS無効化

## 入出力項目

| 項目名 | 入出力 | 型 | 説明 |
|--------|--------|-----|------|
| フラグ選択リスト | 入力 | 複数選択 | ベンチマークフラグの選択 |
| Runボタン | 入力 | クリック | ベンチマーク実行開始 |
| Reset Flagsボタン | 入力 | クリック | フラグ選択をリセット |
| Clear outputボタン | 入力 | クリック | 出力エリアをクリア |
| Reverse log orderチェックボックス | 入力 | チェック | ログ表示順序の反転 |
| speedtest1リンク | 入力 | クリック | メインスレッド版へ遷移 |
| speedtest1-kvvfsリンク | 入力 | クリック | kvvfs版へ遷移 |

## 表示項目

| 項目名 | 表示位置 | 説明 |
|--------|----------|------|
| タイトルバー | ヘッダー | "speedtest1.wasm Worker" |
| メインスレッド版リンク | ヘッダー下 | "See also: A main-thread variant of this page." |
| 初期化スピナー | 中央 | WASM初期化中に表示 |
| オプションフィールドセット | 上部 | フラグ選択UIとボタン |
| 選択フラグ表示 | 右側 | 現在選択中のフラグ一覧 |
| 出力エリア | 下部 | ベンチマーク結果のリアルタイム表示 |
| Tips | 最下部 | 使用上のヒント |

## イベント仕様

### 1-ページロード（Worker初期化）

**トリガー**: ページロード完了時

**処理内容**:
1. **行171-177**: `new Worker("speedtest1-worker.js?sqlite3.dir=jswasm")` でWorker作成
2. **行214-283**: フラグ選択リストの初期化
3. **行301-307**: Reset Flagsボタン設定
4. **行308-311**: Runボタン設定
5. **行346-370**: `W.onmessage` でメッセージハンドラ設定

### 2-Worker準備完了

**トリガー**: Worker内でWASM初期化完了時

**処理内容**:
```javascript
case 'ready':
  log("Worker is ready.");
  eControls.classList.remove('hidden');
  break;
```

**行番号**: 349-352

### 3-フラグ選択変更

**トリガー**: フラグ選択リストの変更

**処理内容**:
```javascript
eFlags.addEventListener('change', updateSelectedFlags);

const updateSelectedFlags = function(){
  eSelectedFlags.innerText = '';
  const flags = getSelectedFlags();
  flags.forEach(function(f){
    const e = document.createElement('span');
    e.innerText = f;
    eSelectedFlags.appendChild(e);
  });
  // リンクURLの更新
  eLinkMainThread.href = 'speedtest1.html?flags='+comma;
  eLinkKvvfs.href = 'speedtest1.html?vfs=kvvfs&flags='+comma;
};
```

**行番号**: 196-212, 213

### 4-ベンチマーク実行（Runボタン）

**トリガー**: Runボタンクリック

**処理内容**:
```javascript
E('#btn-run').addEventListener('click',function(){
  log("Running speedtest1. UI controls will be disabled until it completes.");
  mPost('run', getSelectedFlags());
});
```

**行番号**: 308-311

**Workerへのメッセージ**:
```javascript
const mPost = function(msgType,payload){
  W.postMessage({type: msgType, data: payload});
};
```

### 5-ベンチマーク結果受信

**トリガー**: Workerからのstdout/stderrメッセージ

**処理内容**:
```javascript
case 'stdout': log(msg.data); break;
case 'stderr': logErr(msg.data); break;
case 'run-start':
  eControls.disabled = true;
  log("Running speedtest1 with argv =",msg.data.join(' '));
  break;
case 'run-end':
  log("speedtest1 finished.");
  eControls.disabled = false;
  break;
```

**行番号**: 353-362

### 6-出力クリア

**トリガー**: Clear outputボタンクリック

**処理内容**:
```javascript
E('#btn-output-clear').addEventListener('click', ()=>{
  eOut.innerText = '';
});
```

**行番号**: 301-303

### 7-フラグリセット

**トリガー**: Reset Flagsボタンクリック

**処理内容**:
```javascript
E('#btn-reset-flags').addEventListener('click',()=>{
  eFlags.value = '';
  updateSelectedFlags();
});
```

**行番号**: 304-307

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ベンチマーク実行 | speedtest1.sqlite3 | 全種 | ベンチマーク用のCREATE/INSERT/SELECT/UPDATE/DELETE |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| LOG-001 | 情報 | "Worker is ready." | Worker準備完了時 |
| LOG-002 | 情報 | "Running speedtest1. UI controls will be disabled until it completes." | 実行開始時 |
| LOG-003 | 情報 | "Running speedtest1 with argv = {argv}" | 実行開始時 |
| LOG-004 | 情報 | "speedtest1 finished." | 実行完了時 |
| LOG-005 | 情報 | ベンチマーク出力 | 実行中（リアルタイム） |
| ERR-001 | エラー | エラーメッセージ | エラー発生時 |

## 例外処理

| 例外状況 | 対応処理 |
|---------|----------|
| Workerエラー | 'error'メッセージでlogErr()出力 |
| 未対応メッセージタイプ | logErr("Unhandled worker message type:", msg) |

## 備考

- Workerスレッドで実行されるためUIがブロックされない
- ctrl-クリックで複数フラグを選択可能
- --big-transactionsフラグはテスト410と510で重要
- OPFS VFSは対応ブラウザとCOOP/COEPヘッダーが必要
- opfs-sahpoolは実験的VFS
- 最適化レベル（-O2等）でmakeし直すことで速度改善可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | speedtest1-worker.html | `ext/wasm/speedtest1-worker.html` | フラグオブジェクトとメッセージ形式 |

**読解のコツ**:
- `flags` オブジェクトでフラグ名と説明を管理（行215-264）
- Worker通信は `{type, data}` 形式
- 'run'メッセージでフラグ配列を送信

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | speedtest1-worker.html | `ext/wasm/speedtest1-worker.html` | インラインスクリプトの初期化処理 |

**主要処理フロー**:
1. **行128-130**: 即時関数開始、ログ関数定義
2. **行171-177**: Worker作成（URLパラメータ付き）
3. **行214-299**: フラグ選択UI初期化
4. **行346-370**: W.onmessageハンドラ設定

#### Step 3: Worker側処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | speedtest1-worker.js | `ext/wasm/speedtest1-worker.js` | Worker側のメッセージハンドリング |

**主要処理フロー**:
- **行95-106**: globalThis.onmessage で'run'メッセージを処理
- **行52-93**: runSpeedtest() でargv構築とwasm_main()実行
- **行37-39**: mPost()でメインスレッドに結果送信

#### Step 4: メインスレッド版との比較

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | speedtest1.html | `ext/wasm/speedtest1.html` | メインスレッド版との違い |

**主要な違い**:
- メインスレッド版: 自動実行、UIブロック、出力バッファリング
- Worker版: 対話的UI、リアルタイム出力、フラグ選択可能

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

```
speedtest1-worker.html (ページロード)
    │
    ├─ <script> 即時関数
    │      │
    │      ├─ new Worker("speedtest1-worker.js")
    │      │
    │      ├─ フラグ選択UI初期化
    │      │      └─ eFlags.addEventListener('change', ...)
    │      │
    │      └─ W.onmessage 設定
    │
    └─ ユーザー操作
           │
           └─ Runボタンクリック
                  │
                  └─ mPost('run', flags)
                         │
                         └─ [Worker] speedtest1-worker.js
                                │
                                ├─ globalThis.onmessage
                                │      └─ runSpeedtest(flags)
                                │
                                └─ mPost('stdout/stderr/run-end', ...)
                                       │
                                       └─ [Main] W.onmessage
                                              └─ log()/logErr()
```

### データフロー図

```
[メインスレッド]                              [Workerスレッド]

フラグ選択UI
    │
    └── Runボタン
           │
           └── postMessage({type:'run', data:flags})
                        │
                        └─────────────────────▶ onmessage
                                                    │
                                                    └─ runSpeedtest()
                                                           │
                                                           ├─ sqlite3InitModule()
                                                           │
                                                           └─ wasm.xCall('wasm_main', ...)
                                                                  │
onmessage ◀───────────────────────────────────────── postMessage({type:'stdout/stderr',...})
    │
    └── log()/logErr()
           │
           ▼
        出力エリア（リアルタイム更新）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| speedtest1-worker.html | `ext/wasm/speedtest1-worker.html` | テンプレート | Worker版ベンチマークページ |
| speedtest1-worker.js | `ext/wasm/speedtest1-worker.js` | ソース | Worker側実行ロジック |
| speedtest1.js | `ext/wasm/jswasm/speedtest1.js` | ソース | WASM初期化ローダー |
| speedtest1.wasm | `ext/wasm/jswasm/speedtest1.wasm` | バイナリ | speedtest1 WASMモジュール |
| speedtest1.html | `ext/wasm/speedtest1.html` | テンプレート | メインスレッド版（比較参照用） |
