# 機能設計書 103-Serialization

## 概要

本ドキュメントは、Julia標準ライブラリ `Serialization` モジュールが提供するJuliaオブジェクトのバイナリシリアライズ・デシリアライズ機能の設計を記述する。`serialize` / `deserialize` 関数により、Juliaの任意のオブジェクトをバイトストリームに変換し、復元することができる。

### 本機能の処理概要

**業務上の目的・背景**：Juliaオブジェクトの永続化、プロセス間通信、分散計算でのデータ転送を実現するため、効率的なバイナリシリアライゼーション機構を提供する。Distributed.jlやプロセス間RPC等で内部的に使用される。

**機能の利用シーン**：オブジェクトのファイル保存・復元、プロセス間でのデータ受け渡し、計算結果のキャッシュ、分散計算でのタスク・データの送受信。

**主要な処理内容**：
1. 255種類のタグベースのバイナリエンコーディング
2. 循環参照の検出と処理（BACKREF_TAG）
3. 型情報（DataType, TypeName, UnionAll等）のシリアライズ
4. 組み込み型（Int, Float, String, Array, Expr等）の高速シリアライズ
5. IdDict/Module/Method/MethodInstance等の特殊型対応
6. バージョン管理（ser_version = 30）による互換性制御

**関連システム・外部連携**：Base.ScopedValues（current_module管理）、Core.IR。

**権限による制御**：特になし。ただし、`deserialize` は信頼できないデータに対する安全性は保証しない。

## 関連画面

本機能に直接関連する画面はない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | バックエンド処理として利用 |

## 機能種別

データ連携 / データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| io | IO | Yes | シリアライズ先/デシリアライズ元のIOストリーム | 読み書き可能なIOオブジェクト |
| value | Any | Yes（serialize時） | シリアライズ対象のJuliaオブジェクト | 任意のJuliaオブジェクト |

### 入力データソース

IOストリーム（ファイル、IOBuffer、ネットワークソケット等）。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| serialized_bytes | Vector{UInt8} | serialize時のバイナリデータ |
| deserialized_object | Any | deserialize時の復元オブジェクト |

### 出力先

IOストリーム（serialize時）、戻り値（deserialize時）。

## 処理フロー

### 処理シーケンス

```
1. serialize(io, value)
   ├─ HEADER_TAG書き込み（バージョン情報）
   ├─ 型タグの判定（sertag）
   ├─ 循環参照チェック（serialize_cycle）
   └─ 型別シリアライズ（各型のserializeメソッド）
2. deserialize(io)
   ├─ HEADERタグ読み込み・バージョン確認
   ├─ タグ読み込み（desertag）
   └─ 型別デシリアライズ（各型のdeserializeメソッド）
```

### フローチャート

```mermaid
flowchart TD
    A["serialize(io, value)"] --> B{"sertag(value)"}
    B -->|既知タグ| C["タグ書き込み + 型別serialize"]
    B -->|循環参照| D["BACKREF_TAG書き込み"]
    B -->|未知型| E["OBJECT_TAG + 型情報 + フィールドシリアライズ"]
    C --> F["完了"]
    D --> F
    E --> F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-103-1 | タグベースエンコーディング | 255種のタグで型を識別。VALUE_TAGS以上はタグ自体が値を表す | 全シリアライズ処理 |
| BR-103-2 | 循環参照検出 | IdDictで参照済みオブジェクトを追跡し、BACKREFタグで参照 | 全serialize呼び出し |
| BR-103-3 | バージョン互換性 | ser_version=30。バージョン変更なしに互換性を壊す変更は不可 | 全serialize/deserialize |
| BR-103-4 | Ptr型の安全性 | Ptr型はC_NULLとしてシリアライズ（アドレス値は保存しない） | Ptr型のシリアライズ時 |

### 計算ロジック

- 小さな整数（0-32）は専用タグで1バイトエンコード
- 頻出シンボル（`:Any`, `:Array`等）は専用タグで1バイトエンコード
- BACKREFはオフセット値のサイズにより UInt16/Int32/Int64 を選択

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ErrorException | 不正なシリアライズデータ | データの整合性を確認 |
| - | MethodError | シリアライズ不可能な型 | カスタムserializeメソッドを定義 |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- 頻出値（小さな整数、Bool、Nothing、頻出シンボル）は1バイトエンコードで高速化
- Tuple/SimpleVectorは長さに応じてショート/ロングタグを使い分け
- @inboundsによるタグ検索の最適化

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

- `deserialize` は任意コード実行の可能性がある（信頼できないデータのデシリアライズは危険）
- Ptr型はC_NULLとしてシリアライズされ、メモリアドレスは保存されない
- Module/Method等のランタイムオブジェクトも復元されるため、環境依存性がある

## 備考

- Serialization形式はJulia内部専用であり、他言語との互換性はない
- 長期保存には `JLD2` や `Arrow.jl` 等の外部パッケージの使用を推奨
- ser_versionの変更はバイナリ互換性を破壊するため、慎重に行う必要がある

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Serialization.jl | `stdlib/Serialization/src/Serialization.jl` | `Serializer{I}` 構造体（20-28行目）: IO、カウンタ、参照テーブルを保持 |
| 1-2 | Serialization.jl | `stdlib/Serialization/src/Serialization.jl` | `TAGS` 定数配列（40-81行目）: 255種のタグ定義。型とタグの対応表 |
| 1-3 | Serialization.jl | `stdlib/Serialization/src/Serialization.jl` | 各種タグ定数（105-146行目）: BACKREF_TAG, OBJECT_TAG等の特殊タグ |

**読解のコツ**: TAGSは255要素の配列で、前半は直接の型対応（Symbol, Int8,...）、中間は特殊タグ（UNDEFREF, BACKREF等）、後半は値タグ（(), Bool, 頻出シンボル, 小さな整数）となっている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Serialization.jl | `stdlib/Serialization/src/Serialization.jl` | `serialize` 関数群: 型ごとのdispatchで処理が分岐 |
| 2-2 | Serialization.jl | `stdlib/Serialization/src/Serialization.jl` | `serialize_cycle`（157-175行目）: 循環参照検出のコアロジック |

#### Step 3: 型別シリアライズ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Serialization.jl | `stdlib/Serialization/src/Serialization.jl` | `serialize(s, t::Tuple)`（197行目〜）: Tupleシリアライズ |
| 3-2 | Serialization.jl | `stdlib/Serialization/src/Serialization.jl` | Bool, Ptr, 空Tupleの1バイトシリアライズ（190-195行目） |

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

```
serialize(io, value) / serialize(s::Serializer, value)
    │
    ├─ sertag(value)                    -- タグ検索
    │
    ├─ serialize_cycle(s, value)        -- 循環参照チェック
    │      └─ s.table[x] = s.counter   -- 参照テーブル登録
    │
    └─ serialize(s, value::T)           -- 型別ディスパッチ
           ├─ Bool: TRUE_TAG/FALSE_TAG
           ├─ Tuple: TUPLE_TAG + 要素シリアライズ
           ├─ Symbol: SYMBOL_TAG + 名前
           ├─ Array: ARRAY_TAG + 型 + サイズ + 要素
           ├─ DataType: DATATYPE_TAG + TypeName
           ├─ Module: MODULE_TAG + 名前パス
           └─ その他: OBJECT_TAG + 型 + フィールド
```

### データフロー図

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

Julia Object ──▶ serialize(s, value)
                     │
                     ├─ sertag(): タグ判定
                     ├─ serialize_cycle(): 循環検出
                     └─ 型別エンコード
                          │
                          ▼
                     IOストリーム ──▶ バイナリデータ

バイナリデータ ──▶ deserialize(io)
                     │
                     ├─ タグ読み込み
                     └─ 型別デコード
                          │
                          ▼
                     Julia Object ──▶ 復元オブジェクト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Serialization.jl | `stdlib/Serialization/src/Serialization.jl` | ソース | Serializationモジュール全体 |
