3. 参照テーブル (Reference Tables)
HPACK とは異なり、QPACK はフィールド行を参照するために 2 つのテーブルを使用します:静的テーブルと動的テーブルです。
3.1 静的テーブル (Static Table)
静的テーブルは、事前定義されたフィールド行のリストで構成され、それぞれが固定された不変の値(空の可能性がある)を持ちます。その完全な定義は付録 A に記載されています。静的テーブルのエントリは変更されません。
静的テーブルは、静的インデックスを使用して参照できます。
静的テーブルはこの仕様で定義されており、フィールド行のセットは比較的小さく安定しているため、完全ハッシュや他の技術を使用してエントリを見つける効率的な実装が可能です。
3.2 動的テーブル (Dynamic Table)
動的テーブルは、挿入された順序で First In First Out (FIFO) 順に維持されるフィールド行の順序付きリストで構成されます。静的テーブルと同様に、動的テーブルのエントリは名前と値を持つフィールド行です。
動的テーブルは、動的インデックスを使用して参照できます。動的テーブルは最初は空です。エンコーダストリームで挿入命令が受信されると、エントリが追加されます(セクション 4.3 を参照)。
動的テーブルには重複するフィールド行が含まれる可能性があります(つまり、別のエントリと同じ名前と値を持つエントリ)。したがって、重複するフィールド行はデコーダによってエラーとして扱われてはなりません(MUST NOT)。
3.2.1 動的テーブルのサイズ (Dynamic Table Size)
動的テーブルのサイズは、そのエントリのサイズの合計です。
エントリのサイズは、その名前のオクテット長(セクション 4.1.2 で定義)、その値のオクテット長(セクション 4.1.2 で定義)、および 32 の合計です。
エントリのサイズは次のように計算されます:
サイズ = 長さ(名前) + 長さ(値) + 32
エントリのサイズは、固定オーバーヘッドによってフィールド行のサイズよりも大きくなります。オーバーヘッドには、32 オクテットと推定される割り当てオーバーヘッド量が含まれます。これには、ハッシュ構造でエントリを参照するための上位または近似データ構造、文字列バッファ、またはその他の構造化データが含まれる場合があります。実装は、異なるデータ構造を使用するか、異なるオーバーヘッド量を持つことを選択できます。これは、エンコーダとデコーダによって適用されるサイズ計算を変更しません。
3.2.2 動的テーブルの容量 (Dynamic Table Capacity)
動的テーブルの容量は、デコーダによって固定され、エンコーダに通信されます。セクション 3.2.3 を参照してください。
エンコーダは、動的テーブルのサイズが動的テーブルの容量以下であることを確認しなければなりません(MUST)。
HTTP/3 では、容量はエンコーダがデコーダから受信する SETTINGS_QPACK_MAX_TABLE_CAPACITY パラメータ(セクション 5 を参照)の値によって決定されます。エンコーダは、パラメータを受信したときに容量をパラメータの値に設定しなければなりません(MUST)。HTTP/3 では、エンコーダはこのパラメータの受信を動的テーブルの使用許可として解釈しなければなりません(MUST)。
エンコーダがこのパラメータの値を受信していない場合、デフォルト値の 0 を使用しなければなりません(MUST)。容量 0 は、動的テーブルが使用されず、エントリを追加できないことを意味します。
3.2.3 動的テーブルからの削除 (Eviction from the Dynamic Table)
新しいエントリが動的テーブルに追加される前に、動的テーブルのサイズが(動的テーブル容量 - 新しいエントリサイズ)以下になるか、テーブルが空になるまで、動的テーブルの末尾からエントリが削除されます。
エンコーダは、次の場合を除き、動的テーブルエントリの削除を引き起こしてはなりません(MUST NOT):
-
エントリが、エンコーダに知られているブロックされたストリームで処理中の必要挿入カウントのグループにもう存在しない、または
-
エンコーダが、エントリが含まれていた最新の必要挿入カウントを参照するセクション確認応答(セクション 4.4.1 を参照)を受信した。
動的テーブルの最も古いエントリが削除されると、そのインデックスは新しいエントリを参照するために再利用されます。
3.2.4 絶対インデックスと相対インデックス (Absolute Indexing)
各エントリには、エントリが動的テーブルに挿入されたときに割り当てられる絶対的な一意で不変のインデックスがあります。セクション 4.3.1 を参照してください。動的テーブルに挿入された最初のエントリには、絶対インデックス 0 が割り当てられます。
特定のエントリの絶対値は、現在テーブルにあるエントリの数よりも大きい場合があることに注意してください。したがって、実装では配列インデックスとして使用できません。
3.2.5 相対インデックス (Relative Indexing)
エンコーダストリームの命令(セクション 4.3 を参照)と相対インデックスを使用するフィールド行表現(セクション 4.5 を参照)は、相対インデックスの値を指定することによってエントリを参照します。
エントリの相対インデックスは、エントリの絶対インデックスと参照可能セットの最大絶対インデックスの差です。最大絶対インデックスは、コンテキストに応じて、必要挿入カウントから 1 を引いたものまたは Base の値に等しくなります。
エンコーダストリームの命令の場合、最大絶対インデックスは最も最近挿入されたエントリを参照します:
最大絶対インデックス = 挿入カウント - 1
フィールド行表現の場合、最大絶対インデックスはエンコードされたフィールドセクションの Base を参照します。セクション 4.5.1 を参照してください。
最大絶対インデックス = Base
最大絶対インデックスを持つエントリの相対インデックスは 0 です。最初に挿入された要素の相対インデックスは(挿入カウント - 1)であり、新しい挿入ごとに増加するだけです。
3.2.6 Post-Base インデックス (Post-Base Indexing)
エンコードされたフィールドセクションのフィールド行表現(セクション 4.5 を参照)は、Post-Base インデックスを使用して、Base の値の後に追加されたエントリを参照できます(ゼロから始まる)。エンコーダは、デコーダの動的テーブルでまだ利用できない最近挿入されたエントリを参照することを決定できます。これらのエントリの絶対インデックスの決定は、エンコードされたフィールドセクションの Base の値とエントリの Post-Base インデックスを次のように使用します:
絶対インデックス = Base + Post_Base_インデックス
エンコーダは、この方法で計算された絶対インデックスが Post-Base エントリを参照することを確認しなければならず(MUST)、デコーダは Post-Base エントリではないエントリへの参照を QPACK_DECOMPRESSION_FAILED タイプのストリームエラーとして扱わなければなりません(MUST)。