概要
- Segment Array は、動的配列の代替として使えるデータ構造
- 安定したポインタ を保証し、アリーナアロケータと相性が良い
- 各セグメントは前の2倍のサイズで、必要時のみ確保
- 高速なランダムアクセス と高いメモリ効率を両立
- 実装はシンプルで120行未満、C言語のシングルヘッダとして提供
セグメント配列(Segment Array)の概要
- Segment Arrayは、 動的配列 の代替として利用可能なデータ構造
- ポインタの安定性 を確保し、アイテムの移動が発生しない設計
- 各セグメントは 前のセグメントの2倍のアイテム数 を保持
- 必要な時だけ新しいセグメントを 動的確保 する方式
- アリーナアロケータ との高い親和性
構造とメモリレイアウト
- Segment Arrayは、 固定長のポインタ配列 (segments)を持つ
- 各ポインタは個別のセグメント領域を指し、 セグメントサイズは2のべき乗
- 先頭6セグメント(1,2,4,8,16,32)は省略し、 64アイテムから開始
- 26セグメントで 最大約42億個 のアイテムを格納可能(u32インデックス対応)
- セグメント配列自体が キャッシュ効率 を高める役割
インデックス計算と高速アクセス
- インデックスから該当セグメントとオフセットを ビット演算 で高速算出
log2i関数で セグメント番号 を決定capacity_for_segment_countで 累積容量 を計算
- アクセスは 定数時間 で実現
- 順次アクセス時は、 各セグメントを直接ループ 可能
アイテム追加と容量管理
- 新規アイテム追加時、 必要に応じてセグメントを確保
- セグメントサイズは
slots_in_segmentで計算 - 容量を2のべき乗に揃える調整 も可能(ハッシュテーブル用途向け)
ジェネリクス(型安全な利用)
- マクロを用いて 任意の型 に対応
SegmentArray(type)で型付き共用体を宣言sa_get,sa_alloc等のマクロで 型安全なアクセス を提供
- typeofやマクロが不要な場合は 省略可能
使用例
- シングルヘッダ(segment_array.h)をインクルードし、 簡単なAPI で利用可能
- アイテム追加、取得、全件ループ、解放(arena未使用時のみ)
他データ構造との比較
- 固定長配列 :拡張不可、ランダムアクセス・連続性・効率良
- 動的配列 :拡張可、アイテム移動あり、ランダムアクセス良
- チャンク付きリスト :拡張可、ランダムアクセス不可、メモリ効率高
- ハイブリッド方式 :一括生成時に有効、最終的に固定長配列へ
- 仮想メモリアレイ :巨大な仮想空間予約、組込み等では利用不可
- Segment Array :拡張可、アリーナ親和性・ランダムアクセス良、連続性なし
メモリ効率(平均値)
- 固定長配列: 100%
- 動的配列: 75~83% (成長率による)
- チャンクリスト: ほぼ100%
- ハイブリッド: 100%
- 仮想メモリアレイ: 100%
- Segment Array: 75%
適用場面とまとめ
- アイテム数が事前に不明 かつ アリーナアロケータ を使う場面で有用
- 例:プロファイラ等で 動的生成される大量データ の管理
- 高速・安定・アリーナ親和性 の三拍子
- シングルヘッダ実装は 120行未満 で完結
- 詳細実装やダウンロードは ニュースレター登録 で入手可能
参考情報
- Per Vognsen による名称「Segment Array」
- Zig では「Segmented List」と呼称
- C++のstd::deque は類似だが設計思想が異なる
- アリーナアロケータ 利用時に特に真価発揮
結論
- Segment Arrayは、 拡張性・速度・安定性・メモリ効率 をバランス良く実現
- C言語で簡潔に実装可能 な汎用データ構造
- 特定用途(アリーナ・動的生成)で 他構造より優位性 あり
- 実装や利用に関するフィードバック歓迎