3. Tabelle di riferimento (Reference Tables)
A differenza di HPACK, QPACK utilizza due tabelle per fare riferimento alle righe di campo: una tabella statica e una tabella dinamica.
3.1 Tabella statica (Static Table)
La tabella statica consiste in un elenco predefinito di righe di campo, ognuna delle quali ha un valore fisso e immutabile, potenzialmente vuoto. La sua definizione completa è fornita nell'Appendice A. Le voci nella tabella statica non cambiano mai.
La tabella statica può essere referenziata utilizzando un indice statico.
Poiché la tabella statica è definita in questa specifica e l'insieme di righe di campo è relativamente piccolo e stabile, un'implementazione efficiente può essere realizzata utilizzando hashing perfetto o altre tecniche per localizzare le voci.
3.2 Tabella dinamica (Dynamic Table)
La tabella dinamica consiste in un elenco ordinato di righe di campo mantenute in ordine First In First Out (FIFO) nell'ordine in cui sono state inserite. Come la tabella statica, una voce nella tabella dinamica è una riga di campo con un nome e un valore.
La tabella dinamica può essere referenziata utilizzando un indice dinamico. La tabella dinamica è inizialmente vuota. Le voci vengono aggiunte quando le istruzioni di inserimento vengono ricevute sullo stream encoder (vedere la sezione 4.3).
La tabella dinamica può contenere righe di campo duplicate (cioè, una voce con un nome e un valore identici a quelli di un'altra voce). Pertanto, le righe di campo duplicate NON DEVONO essere trattate come un errore dal decoder.
3.2.1 Dimensione della tabella dinamica (Dynamic Table Size)
La dimensione della tabella dinamica è la somma della dimensione delle sue voci.
La dimensione di una voce è la somma della lunghezza in ottetti del suo nome (come definito nella sezione 4.1.2), della lunghezza in ottetti del suo valore (definita nella sezione 4.1.2) e di 32.
La dimensione della voce è calcolata come:
dimensione = lunghezza(nome) + lunghezza(valore) + 32
La dimensione di una voce è maggiore della dimensione della riga di campo di un overhead fisso. L'overhead include un importo di allocazione overhead stimato di 32 ottetti. Ciò potrebbe includere la struttura dati sovrastante o approssimativa per fare riferimento alla voce in una struttura hash, buffer di stringa o altri dati strutturati. Un'implementazione può scegliere di utilizzare diverse strutture dati o avere un diverso importo di overhead; ciò non modifica il calcolo della dimensione applicato dall'encoder e dal decoder.
3.2.2 Capacità della tabella dinamica (Dynamic Table Capacity)
La capacità della tabella dinamica è fissata dal decoder e comunicata all'encoder; vedere la sezione 3.2.3.
Un encoder DEVE garantire che la dimensione della tabella dinamica sia inferiore o uguale alla capacità della tabella dinamica.
In HTTP/3, la capacità è determinata dal valore del parametro SETTINGS_QPACK_MAX_TABLE_CAPACITY (vedere la sezione 5) che l'encoder riceve dal decoder. L'encoder DEVE impostare la capacità al valore del parametro quando lo riceve. In HTTP/3, l'encoder DEVE interpretare la ricezione di questo parametro come un'autorizzazione a utilizzare la tabella dinamica.
Se un encoder non ha ricevuto un valore per questo parametro, DEVE utilizzare il valore predefinito di 0. Una capacità di 0 significa che la tabella dinamica non è utilizzata e nessuna voce può essere aggiunta.
3.2.3 Evacuazione dalla tabella dinamica (Eviction from the Dynamic Table)
Prima che una nuova voce venga aggiunta alla tabella dinamica, le voci vengono evacuate dalla fine della tabella dinamica fino a quando la dimensione della tabella dinamica è inferiore o uguale a (capacità della tabella dinamica - nuova dimensione della voce) o fino a quando la tabella è vuota.
L'encoder NON DEVE causare l'evacuazione di una voce della tabella dinamica a meno che:
-
La voce non sia più presente in un gruppo di conteggi di inserimento richiesti in elaborazione su uno stream bloccato noto all'encoder, o
-
L'encoder ha ricevuto un acknowledgment di sezione (vedere la sezione 4.4.1) che fa riferimento al conteggio di inserimento richiesto più recente in cui la voce era inclusa.
Quando la voce più vecchia della tabella dinamica viene evacuata, il suo indice viene riutilizzato per fare riferimento alla nuova voce.
3.2.4 Indicizzazione assoluta e relativa (Absolute Indexing)
Ogni voce ha un indice assoluto univoco e immutabile che viene assegnato quando una voce viene inserita nella tabella dinamica; vedere la sezione 4.3.1. Alla prima voce inserita nella tabella dinamica viene assegnato l'indice assoluto 0.
Si noti che il valore assoluto dell'indice per una data voce può essere maggiore del numero di voci attualmente nella tabella. Pertanto, non può essere utilizzato come un indice di array in un'implementazione.
3.2.5 Indicizzazione relativa (Relative Indexing)
Le istruzioni dello stream encoder (vedere la sezione 4.3) e le rappresentazioni di righe di campo (vedere la sezione 4.5) che utilizzano l'indicizzazione relativa fanno riferimento alle voci specificando il valore di un indice relativo.
L'indice relativo di una voce è la differenza tra l'indice assoluto della voce e l'indice assoluto più grande dell'insieme referenziabile. L'indice assoluto più grande è uguale al conteggio di inserimento richiesto meno uno o al valore della Base, a seconda del contesto.
Per le istruzioni dello stream encoder, l'indice assoluto più grande fa riferimento alla voce inserita più di recente:
indice_assoluto_più_grande = conteggio_inserimenti - 1
Per le rappresentazioni di righe di campo, l'indice assoluto più grande fa riferimento alla Base nella sezione di campo codificata; vedere la sezione 4.5.1.
indice_assoluto_più_grande = Base
La voce con l'indice assoluto più grande ha un indice relativo di 0. Il primo elemento inserito ha un indice relativo di (conteggio di inserimenti - 1), che aumenta solo con ogni nuovo inserimento.
3.2.6 Indicizzazione Post-Base (Post-Base Indexing)
Le rappresentazioni di righe di campo nelle sezioni di campo codificate (vedere la sezione 4.5) possono utilizzare l'indicizzazione Post-Base per fare riferimento alle voci aggiunte dopo il valore della Base, a partire da zero. L'encoder può decidere di fare riferimento alle voci inserite di recente che non sono ancora disponibili nella tabella dinamica del decoder. La determinazione dell'indice assoluto di queste voci utilizza il valore della Base della sezione di campo codificata e l'indice Post-Base della voce come segue:
indice_assoluto = Base + indice_Post_Base
Un encoder DEVE garantire che l'indice assoluto calcolato in questo modo faccia riferimento a una voce Post-Base, e un decoder DEVE trattare un riferimento a una voce che non è una voce Post-Base come un errore di stream di tipo QPACK_DECOMPRESSION_FAILED.