Appendix C. Sample Single-Pass Encoding Algorithm (シングルパスエンコーディングアルゴリズムのサンプル)
シングルパスエンコーディングの疑似コード。重複の処理、非ブロッキングモード、利用可能なエンコーダーストリームフロー制御、および参照追跡を除く。
ヘルパー関数 (Helper Functions)
# 指定されたプレフィックスと長さを使用して整数をエンコード
encodeInteger(buffer, prefix, value, prefixLength)
# オプションの静的または動的名前インデックス(両方ではない)を持つ動的テーブル挿入命令をエンコード
encodeInsert(buffer, staticNameIndex, dynamicNameIndex, fieldLine)
# 静的インデックス参照をエンコード
encodeStaticIndexReference(buffer, staticIndex)
# Base に対する相対的な動的インデックス参照をエンコード
encodeDynamicIndexReference(buffer, dynamicIndex, base)
# オプションの静的名前インデックスを持つリテラルをエンコード
encodeLiteral(buffer, staticNameIndex, fieldLine)
# Base に対する相対的な動的名前インデックスを持つリテラルをエンコード
encodeDynamicLiteral(buffer, dynamicNameIndex, base, fieldLine)
エンコーディングアルゴリズム (Encoding Algorithm)
base = dynamicTable.getInsertCount()
requiredInsertCount = 0
for line in fieldLines:
staticIndex = staticTable.findIndex(line)
if staticIndex is not None:
encodeStaticIndexReference(streamBuffer, staticIndex)
continue
dynamicIndex = dynamicTable.findIndex(line)
if dynamicIndex is None:
# 一致するエントリなし。挿入+インデックスまたはリテラルエンコード
staticNameIndex = staticTable.findName(line.name)
if staticNameIndex is None:
dynamicNameIndex = dynamicTable.findName(line.name)
if shouldIndex(line) and dynamicTable.canIndex(line):
encodeInsert(encoderBuffer, staticNameIndex,
dynamicNameIndex, line)
dynamicIndex = dynamicTable.add(line)
if dynamicIndex is None:
# インデックス化できない、リテラルを使用
if dynamicNameIndex is not None:
# 動的名前を持つリテラルをエンコード、Base の上の可能性あり
encodeDynamicLiteral(streamBuffer, dynamicNameIndex,
base, line)
requiredInsertCount = max(requiredInsertCount,
dynamicNameIndex)
else:
# 静的名前またはリテラル名を持つリテラルをエンコード
encodeLiteral(streamBuffer, staticNameIndex, line)
else:
# 動的インデックス参照
assert(dynamicIndex is not None)
requiredInsertCount = max(requiredInsertCount, dynamicIndex)
# dynamicIndex をエンコード、Base の上の可能性あり
encodeDynamicIndexReference(streamBuffer, dynamicIndex, base)
# プレフィックスをエンコード
if requiredInsertCount == 0:
encodeInteger(prefixBuffer, 0x00, 0, 8)
encodeInteger(prefixBuffer, 0x00, 0, 7)
else:
wireRIC = (
requiredInsertCount
% (2 * getMaxEntries(maxTableCapacity))
) + 1
encodeInteger(prefixBuffer, 0x00, wireRIC, 8)
if base >= requiredInsertCount:
encodeInteger(prefixBuffer, 0x00,
base - requiredInsertCount, 7)
else:
encodeInteger(prefixBuffer, 0x80,
requiredInsertCount - base - 1, 7)
return encoderBuffer, prefixBuffer + streamBuffer
アルゴリズムの説明
このアルゴリズムは、シングルパスエンコーダーのコアロジックを示しています:
-
初期化: Base を現在の挿入カウントに設定し、requiredInsertCount を 0 に初期化します。
-
フィールド行の反復: 各フィールド行について:
- まず静的テーブルで完全一致を試みます
- 見つからない場合、動的テーブルで検索します
- どちらも見つからない場合、新しいエントリを挿入するかリテラルを使用するかを決定します
-
決定ロジック:
- 完全一致: 直接参照(静的または動的)
- 一致なし: ポリシーに基づいて動的テーブルに挿入するかどうかを決定
- 名前のみ一致: 名前参照を持つリテラルを使用
-
プレフィックスエンコーディング: requiredInsertCount と Base の値に基づいてフィールドセクションプレフィックスをエンコードします。
-
出力: エンコーダーストリームバッファとエンコードされたフィールドセクション(プレフィックス + フィールド行表現)を返します。
重要なポイント
- シングルパス処理: アルゴリズムはフィールド行を反復しながらエンコーディングと挿入の決定を行います
- Base 追跡: 挿入カウントを Base として使用し、Post-Base インデックスを可能にします
- 柔軟な戦略:
shouldIndex()関数はインデックス化戦略をカプセル化し、実装ニーズに応じて調整可能です - 参照カウント:
requiredInsertCountは必要な最大動的テーブル状態を追跡します