# 機能設計書 18-BitArray

## 概要

本ドキュメントは、Julia言語におけるBitArray機能の設計を記述する。ビット単位で格納するメモリ効率の良いブーリアン配列を提供する。

### 本機能の処理概要

BitArray{N}はBool値をビット単位でパック格納する多次元配列型であり、Array{Bool,N}と比較して8倍のメモリ効率を実現する。64個のBool値を1つのUInt64チャンクに格納し、ビット演算による64要素同時処理を可能にする。

**業務上の目的・背景**：論理マスク、フィルタリング、比較演算結果など、大量のBool値を扱う場面は数値計算で頻繁に発生する。Array{Bool}では各要素に8ビット（1バイト）を使用するが、BitArrayでは1ビットで格納するため、メモリ使用量を1/8に削減できる。さらに、64要素をまとめてビット演算で処理できるため、論理演算の性能も向上する。

**機能の利用シーン**：（1）ブロードキャスト比較演算（A .> 0等）の結果格納、（2）trues/falses関数による論理マスク生成、（3）論理インデックス（A[mask]）でのフィルタリング、（4）集合演算の内部表現、（5）大規模ビットフラグ管理。

**主要な処理内容**：
1. BitArray{N}型定義（chunks::Vector{UInt64}, len::Int, dims::NTuple{N,Int}）
2. BitVector/BitMatrix型エイリアス
3. trues/falses関数によるBitArray生成
4. ビット単位のgetindex/setindex!実装
5. 論理演算（.&, .|, .⊻, .!）の64要素同時処理
6. num_bit_chunks関数によるチャンク数計算
7. ブロードキャストとの統合（Bool結果のデフォルト格納先）

**関連システム・外部連携**：Broadcast（base/broadcast.jl）との統合。Bool要素のブロードキャスト結果はデフォルトでBitArrayに格納される。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Juliaプロンプト（julia>） | 参照画面 | REPL上でBitArray操作を実行 |

## 機能種別

データ管理（メモリ効率的ブーリアン配列）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| dims | Vararg{Int,N} | Yes | 各次元のサイズ | 各次元が0以上 |
| init | UndefInitializer | No | 初期化方法 | - |

### 入力データソース

Julia式からの直接入力。trues/falses関数。ブロードキャスト比較演算の結果。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| bitarray | BitArray{N} | ビットパック格納のブーリアン配列 |
| element | Bool | getindexによる要素取得 |

### 出力先

メモリ上のBitArrayオブジェクトとして返却。

## 処理フロー

### 処理シーケンス

```
1. BitArray生成
   └─ 要素数nを計算 → num_bit_chunks(n)でチャンク数計算 → Vector{UInt64}確保
   └─ 最終チャンクを0初期化（未使用ビットは常に0）
2. 要素アクセス (getindex)
   └─ チャンクインデックス計算: (i-1)>>6 + 1
   └─ ビット位置計算: (i-1)&63
   └─ chunks[ci] >> bp & 1 で値取得
3. 要素設定 (setindex!)
   └─ 値がtrueならORで1をセット、falseならANDで0をクリア
4. 論理演算 (64要素同時)
   └─ チャンク単位でビットAND/OR/XOR/NOT
```

### フローチャート

```mermaid
flowchart TD
    A[BitArray生成] --> B[要素数n計算]
    B --> C["チャンク数 = (n+63)>>6"]
    C --> D["Vector{UInt64}(undef, nc)確保"]
    D --> E[最終チャンクを0初期化]
    E --> F[BitArrayオブジェクト返却]
    F --> G{操作種別}
    G -->|getindex| H["chunks[(i-1)>>6+1] >> ((i-1)&63) & 1"]
    G -->|setindex! true| I["chunks[ci] |= (1 << bp)"]
    G -->|setindex! false| J["chunks[ci] &= ~(1 << bp)"]
    G -->|論理演算| K[チャンク単位ビット演算]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 未使用ビットゼロ | 最終チャンクの未使用ビットは常に0でなければならない | 全BitArray操作 |
| BR-02 | 8倍メモリ効率 | Bool値を1ビットで格納（Array{Bool}の1/8） | 全BitArray |
| BR-03 | スレッド非安全 | パック格納のため並行read/writeはスレッドセーフでない | 並行アクセス時 |
| BR-04 | ブロードキャストデフォルト | Bool結果のブロードキャストはBitArrayを返す | broadcast |
| BR-05 | 1次元の場合dims省略 | N==1の場合dims is not stored (dims tuple is empty) | BitVector |

### 計算ロジック

- num_bit_chunks(n) = (n + 63) >> 6 （64要素ごとに1チャンク）
- チャンクインデックス: (i-1) >> 6 + 1
- ビット位置: (i-1) & 63
- getindex: (chunks[ci] >> bp) & 1 != 0
- setindex!(true): chunks[ci] |= UInt64(1) << bp
- setindex!(false): chunks[ci] &= ~(UInt64(1) << bp)

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentError | 次元サイズが負 | 0以上のサイズを指定 |
| - | BoundsError | インデックスが範囲外 | 有効なインデックスを使用 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 8倍のメモリ効率（1ビット/要素 vs 8ビット/要素）
- 64要素同時のビット演算による論理演算の高速化
- キャッシュ効率の向上（データサイズ1/8）

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

- 並行アクセス時のスレッド安全性に注意（パック格納による隣接ビットへの影響）
- 最終チャンクの未使用ビットが0であることの不変条件を維持

## 備考

- BitArrayはmutable struct（chunks::Vector{UInt64}のリサイズが可能）
- BitVector() = BitVector(undef, 0)で空のBitVectorを生成可能
- BitVector(nt::Tuple{Vararg{Bool}})でタプルからの生成をサポート

---

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

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

### 推奨読解順序

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

BitArrayの内部構造とチャンク管理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | bitarray.jl | `base/bitarray.jl` | BitArray{N}構造体定義（24-43行目）：chunks, len, dims |
| 1-2 | bitarray.jl | `base/bitarray.jl` | BitVector/BitMatrix型エイリアス（74-75行目） |
| 1-3 | bitarray.jl | `base/bitarray.jl` | コンストラクタ（28-42行目）：チャンク確保と最終チャンクゼロ初期化 |

**読解のコツ**: BitArrayの内部はVector{UInt64}（chunks）に64個のBool値をパック。lenが実際の要素数、dimsはN>1の場合のみ設定。最終チャンクの未使用ビットは常に0に保つ不変条件がある。

#### Step 2: 要素アクセスを理解する

ビット単位のgetindex/setindex!。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | bitarray.jl | `base/bitarray.jl` | getindex実装（チャンクインデックス+ビットシフト） |
| 2-2 | bitarray.jl | `base/bitarray.jl` | setindex!実装（ビットOR/ANDマスク） |

#### Step 3: 生成関数と論理演算を理解する

trues/falses/ブロードキャスト統合。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | bitarray.jl | `base/bitarray.jl` | BitVector(nt::Tuple{Vararg{Bool}})（96-99行目） |
| 3-2 | bitarray.jl | `base/bitarray.jl` | 論理演算の64要素同時処理 |

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

```
BitArray{N}(undef, dims...)
    |
    +-- num_bit_chunks(n)              [チャンク数計算]
    +-- Vector{UInt64}(undef, nc)      [チャンク配列確保]
    +-- chunks[end] = UInt64(0)        [最終チャンクゼロ初期化]
    |
    +-- getindex(B, i)
    |       +-- @boundscheck
    |       +-- chunks[(i-1)>>6 + 1] >> ((i-1)&63) & 1
    |
    +-- setindex!(B, v, i)
    |       +-- @boundscheck
    |       +-- v ? (chunks[ci] |= mask) : (chunks[ci] &= ~mask)
    |
    +-- .& / .| / .⊻ / .!
            +-- チャンク単位ビット演算
```

### データフロー図

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

dims             ──────> チャンク確保 → BitArray   ──────> BitArray{N}
BitArray, index  ──────> チャンク→ビットシフト→get ──────> Bool
BitArray, Bool,i ──────> ビットOR/ANDマスク→set   ──────> BitArray（変更済み）
A .> 0           ──────> broadcast → BitArray格納   ──────> BitArray{N}
trues(dims)      ──────> 全チャンクを0xFF...F      ──────> BitArray（全true）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| bitarray.jl | `base/bitarray.jl` | ソース | BitArray型定義、getindex/setindex!、論理演算 |
| broadcast.jl | `base/broadcast.jl` | ソース | Bool結果ブロードキャストのBitArray格納 |
| abstractarray.jl | `base/abstractarray.jl` | ソース | AbstractArray基本インタフェース |
