Indici hash

a differenza degli Indici ordinati gli indici hash non mantengono l’associazione key -> RID in maniera esplicita ma sfruttano una funzione hash

flowchart LR
A[key k]
B[(hash function H)]
C[RID or records with key = k]
A --> B --> C

Le funzioni hash non sono iniettive quindi sono possibili collisioni fra le chiavi,

ogni possibile valore generabile dalla funzione hash definisce uno spazio logico detto bucket, mentre il numero di elementi che il bucket può contenere e detto capacita, la memoria composta dai bucket e detta primary area

Bucket overflow

Come già detto i bucket hanno una capacita, se l’inserimento di un record avviene all’interno di un bucket pieno si ha un caso di bucket overflow, questo e uno dei problemi principali da gestire in caso di utilizzo di indice hash.

Gli indici hash sono classificati secondo la metodologia di gestione della memoria

STATIC INDICESDYNAMIC INDICES
Il numero di bucket generati dalla funzione e costanteLa dimensione dell’area primaria si adatta all’effettiva dimensione dei dati da indicizzare

Cosa controllare in un indice hash

Per tutti gli indici hash le seguenti considerazioni sono fondamentali:

  • scelta della funzione hash
  • Gestione del Bucket overflow
  • Capacita dei bucket della primary area
  • Capacita dei bucket dell’ area di overflow (se presente)
  • Utilizzo della memoria allocata

Funzioni hash

Alcune delle funzioni hash più utilizzate sono:

  • mid square viene calcolato il quadrato ed estratte le prime cifre e il risultato normalizzato per
  • shifting la chiave e spezzata in parti di lunghezza uguale a quella del numero , le stringhe sono sommate e normalizzate per
  • folding simile allo shifting ma le stringhe sono ribaltate prima di essere sommate
  • division la chiave viene divisa per un valore

Gestire chiavi alfanumeriche

Per le chiavi alfanumeriche e necessaria una conversione in valori numerici per mezzo di una funzione biettiva e poi applicare la funzione di hash

e un coefficiente per evitare problemi con stringhe anagrammi

Valutare una hash function: Degeneracy

Un criterio per valutare le funzioni hash e l’analisi del parametro di degeneracy:

minore il parametro migliori le performance della funzione hash

Dimensionare l’indice hash: Load factor

Data una stima dei record e una capacita dei bucket, determinare il parametro load factor definisce il numero di bucket come

un valore alto di riduce il numero di record nell'area di overflow

Gestire l’overflow

Per gestire l’overflow ci sono diverse tecniche: le principali sono

  • chaining vengono usati puntatori e overflow area
  • open addressing vengono usati i bucket nell’area primaria per gestire gli overflow (no puntatori)

Chaining

Due principali strategie di chaining sono:

  • separate lists i record in overflow vengono inseriti nel primo bucket successivo libero i record sono mantenuti linkati fra loro
  • coalesced chaining i bucket sono linkati fra loro (non i record), meno efficiente ma semplifica la gestione dei bucket

Open addressing

Nel caso di tecniche di open addressing per ogni valore della chiave si predispone una sequenza di possibili indirizzamenti in fase di inserimento si testano tutti gli indirizzamenti fino a trovare un bucket non pieno

Nel caso di una ricerca nell’indice e necessario cercare in tutti i bucket , inoltre l’operazione di eliminazione di un record deve essere effettuata con cautela in quanto trasforma un bucket pieno in un bucket non pieno che può arrestare la ricerca in fase di inserimento

---
title: bucket status in open addressing
---
flowchart LR
A((free))
B((occupied))
C((non occupied))
A -- insert -->B
B -- delete -->C
C -- insert -->B

Possibili tecniche di open addressing sono

  • linear probing ad ogni step viene aggiunto un valore costante
  • quadratic probing come il linear probing ma l’incremento e lineare
  • double hashing vengono usate due funzioni hash per generare l’indirizzamento e

la tecnica di double hashing ha un side effect in memoria secondaria dovuto all'alta variabilità degli indirizzamenti generati, pagine conseguenti sono disposte in settori non consecutivi del disco, aumentando la latenza

Problematiche degli indici statici

Per poter utilizzare gli indici statici lo storage deve essere allocato durante il design iniziale, questo porta a una sovra/sotto stima dello storage che risulta problematica da risolvere a database in produzione, le strategie di hashing dinamico puntano a risolvere a priori questo problema

Le strategie di hashing dinamico si categorizzano in base all’utilizzo o meno della directory

STRATEGIE CON DIRECTORYSTRATEGIE SENZA DIRECTORY
Virtual hashingLinear hashing
Dynamic hashingSpiral hashing
Extendible hashing

Virtual hashing

Al verificarsi di un overflow l’area primaria viene raddoppiata e il record viene inserito nel bucket buddy

E necessaria una struttura di supporto directory per comprendere quale funzione di hash deve essere utilizzata per recuperare un record, un vettore binario viene utilizzato per tenere traccia dello stato dei bucket

Dynamic hashing

La strategia punta a evitare il raddoppio dell’area primaria usando una struttura directory ausiliaria ad albero binario.

La funzione hash in questo caso da in output una pseudo chiave binaria usata per navigare la directory

L’overflow viene gestito aggiungendo un solo bucket all’area primaria e ridistribuendo le chiavi tra i nodi della directory

Extendible hashing

Simile al Dynamic hashing ma la directory e composta da celle che contengono un puntatore a un bucket, la funzione di hash produce uno pseudo address di cui vengono utilizzati solo i primi bits per accedere direttamente la directory

Ogni bucket ha un valore di local depth utilizzato per segnalare il numero di bit utilizzati per allocare chiavi nel bucket

In caso di overflow si procede come segue

flowchart TD
A{se p' < p}
B{se p' = p}
C[si splittano i record nel bucket p'+1]
D[si raddoppiano i bucket incrementando p]
A -- si --> C 
A -- no --> B
B --> D --> C

In caso di eliminazione i bucket possono essere uniti se il numero di record del bucket e del buddy sono inferiori alla capacita

Linear hashing

Nell’approccio a linear hashing il bucket che viene diviso non e quello in overflow ma un altro scelto in base a un dato criterio

flowchart TD
A[splitpointer and bucket initialization]
B[overflow occours]
C[a new bucket is created at SP + P position]
D[SP increase by one]
E[records are re distributed]
A --> B --> C --> D --> E

Uno dei principali contro di questa strategia e che all’aumentare di SP gli split sono sempre più costosi

Recursive Linear hashing

In questa modalità l’area di overflow viene gestita per mezzo del Linear hashing, vengono creati multipli livelli di overflow dove il livello salva i suoi record in overflow nel livello

Spiral hashing

Uno dei problemi del Linear hashing risiede nel fatto che la probabilità che dei bucket che non hanno subito uno split nella espansione corrente e’ alta.

L’idea alla base dello spiral hashing punta a concentrare i record nella prima sezione della primary area sfruttando una funzione esponenziale

PREVIOUS NEXT