Il B-tree nasce dalla generalizzazione della struttura di file con indice.
Si accede ad un file attraverso una gerarchia di indici - l’indice a livello più alto (radice) è costituito da un unico blocco e risiede in memoria principale. Ogni blocco di un file indice è costituito da record contenenti una coppia (v,b)
v
⇒ valore della chiave del primo record della porzione del file principale a cui fa riferimento la coppiab
⇒ puntatore (ad un blocco del file indice a livello più basso, o ad un blocco del file principale)
il primo record indice di ogni blocco contiene solo un puntatore (niente chiave) ad un blocco che ha chiavi minori di quelle puntate dal secondo record
- ogni chiave di un record indice ricopre quelle del suo sottoalbero
- ogni blocco del file principale è memorizzato come quello di un ISAM
ogni blocco di un B-tree (sia indice che principale, tranne la radice) deve essere pieno almeno per metà
(per la radice, logicamente, il minimo è invece due record: se ce ne fosse uno solo, sarebbe inutile e la “vera” radice sarebbe quindi il blocco a cui il record punta)
ricerca
(per effettuare una ricerca, si accede agli indici a partire dal livello più alto: scendendo nella gerarchia degli indici, si restringe la porzione del file principale in cui deve trovarsi il record desiderato - fino ad arrivare ad un unico blocco).
Si parte dall’indice a livello più alto, e ad ogni passo si esamina un unico blocco (se è del file principale, deve essere quello - se è di un file indice, si cerca la chiave che ricopre la propria)
(per me è un po’ come il binary search tree ma n-ario) Il costo della ricerca - che è fisso, perché “so dove andare” - è di h+1 accessi (con h altezza dell’albero).
come varia h?
- più i blocchi sono pieni, più h è piccolo (meno costa la ricerca)
- se i blocchi sono completamente pieni, un inserimento può richiedere una modifica dell’indice ad ogni livello
inserimento
L’inserimento ha costo h+1 (ricerca) + 1 (riscrivere il blocco) se c’è spazio sufficiente. Se non c’è spazio sufficiente, ha costo: h+1 (ricerca) + s (s⇐2h+1)
- nel caso peggiore, dobbiamo sdoppiare un blocco per ogni livello, effettuando due accessi in più + uno per la nuova radice
esempio
caso limite: voglio inserire un record, ma non ho spazio:
![]()
![]()
cancellazione
La cancellazione ha costo h+1 (ricerca) + 1 (riscrivere il blocco) se il blocco è pieno almeno per metà dopo la cancellazione. Altrimenti, sono necessari ulteriori accessi
esempio
in alcuni casi, la cancellazione stravolge completamente la struttura dell’albero:
![]()
![]()
modifica
La modifica ha costo h+1 (ricerca) + 1 (riscrivere il blocco) se non coinvolge la chiave. Altrimenti, costo cancellazione + costo inserimento.
massimo valore di h
Siano:
- - numero di record nel file principale
- - numero di reccord del file principale che possono essere memorizzati in un blocco
- - numero di record del file indice che possono essere memorizzati in un bloicco
e quindi (poiché i blocchi devono essere riempiti a metà):
- - minimo di record necessari in ogni blocco del file principale
- - minimo di record necessari in ogni blocco del file indice
L’altezza massima () si ha quando i blocchi sono pieni al minimo, ovvero quando:
- ogni blocco del file principale contiene esattamente record
- ogni blocco del file indice contiene esattamente record
Quindi:
- il file principale ha al massimo blocchi (numero record/record x blocco)
- a livello , il file indice ha
- record (ogni , memorizzati in:
- blocchi (, che viene diviso per ad ogni livello)
- (livello 1: …)
A livello , l’indice avrà esattamente un blocco, quindi dobbiamo fermarci quando: (in realtà sarebbe , ma approssimiamo)
Quindi, il limite superiore dell’altezza dell’albero è
esercizi
esercizio 1
Supponiamo di avere un file di record. Ogni record occupa byte, di cui per il campo chiave. Ogni blocco contiene byte. Un puntatore a blocco occupa byte
- Se usiamo un B-tree e assumiamo che sia i blocchi indice che i blocchi del file sono pieni al minimo, quanti blocchi vengono usati per il livello foglia (file principale) e quanti per l’indice, considerando tutti i livelli foglia? Quale è il costo di una ricerca in questo caso?
Dati:
- il file contiene record ⇒
- ogni record occupa byte ⇒
- il campo chiave occupa byte ⇒
- ogni blocco contiene byte ⇒
- un puntatore a blocco occupa byte ⇒
Avremo: con massimo di record per blocco del file principale (byte per blocco/dimensione record)
Visto che sono pieni al minimo, divido per e prendo la parte intera per ottenere il numero di record effettivamente presenti (per blocco):
Calcolo il numero di blocchi per il file principale (che è anche il numero di record del file indice) (numero di record/record per blocco)
non per forza necessario
Possiamo calcolare il numero (massimo) dei blocchi in un file indice facendo: (sottraggo 4 inizialmente perché il primo record non ha la chiave (quindi elimino lo spazio che il suo puntatore occupa), ma riaggiungo 1 al conto totale dei record perché è presente).
Calcoliamo il numero effettivo di record memorizzabili in un blocco del file indice. Il blocco è a metà capienza, quindi, invece di , useremo
verifica
per questo tipo di calcoli, è sempre utile fare una verifica, facendo il calcolo al contrario (verifichiamo effettivamente di aver occupato metà dei blocchi): okay, è più della metà - ma dobbiamo anche controllare che non sia troppo: proviamo a vedere cosa sarebbe successo con un record in meno , quindi non saremmo arrivati a metà - il nostro risultato è corretto.
Calcoliamo il numero di blocchi per il file principale:
Calcoliamo il numero di blocchi per il file indice al primo livello
Calcoliamo il numero di blocchi per il file indice al secondo livello
Calcoliamo il numero di blocchi per il file indice al terzo livello
Calcoliamo il numero di blocchi per il file indice al quarto livello
A questo punto mi fermo poiché ho trovato la radice (livello con un solo blocco)
Complessivamente quindi si avranno blocchi.
Il costo della ricerca sarà (un blocco per ognuno dei livelli di indice blocco per il file principale)
domande orale
possibili domande orale
- struttura B-tree
- costo operazioni
- quando ha altezza massima? quant’è l’altezza massima?
- qual è l’unico blocco che non deve necessariamente essere pieno a metà?