Fájlszervezési módszerek - Heap + Hash
Quick Disclaimer
A jegyzetelő (Kotlin 👋) által használt bucket - vödör fordítás az EA szerint bucket - kosár
Csak ha lenne szódoga, plz don't kill me, kthxbye
- kupac
- heap
- hasító index
- hash
- [rendezett állomány]
- [elsődleges index]
- ritka index
- [másodlagos index]
- sűrű index
- [többszintű index]
- indexek indexei
- [\(B^+\) és \(B^*\) fa]
ezeket fogjuk vizsgálni
Feltételezzük, hogy most elég az első találattal számolni
Módosítási műveletek
- insert
- update
- delete
Egyszerűsített esetben a chache-ről "megfeledkezünk", ok?
Kupac
- A rekordokat a blokk első üres helyére tesszük
- érkezési sorrendben
Heap - A=a keresési idő
- Tárméret:
B Blegrosszabb esetB/2átlagos eset
Heap - Beszúrás
- Utolsó blokkba tesszük a rekordot
- 1 olvasás + 1 írás
Heap - Módosítás
- 1 keresés + 1 írás
Heap - Törlés
- 1 keresés + 1 írás
- Üres hely marad , vagy törlési bit
Hasítóindex-szervezés (Hashelés)
- A rekordokat blokkláncokba (bucket - kosár) soroljuk
- A lánc utolsó blokjának első üres helyére teszünk rekodot
- érkezési sorrend szerint
- Blokklánccok száma
- statikus hasításkor
- előre adott:
K
- előre adott:
- dinamikus hasításkor
- a tárolt adatok alapján változhat
- statikus hasításkor
- Besorolás az indexmező értékei alapján történik
- Egy \(h(x)\in\{1,\ldots,K\}\) hasító függvény dönti el a rekord helyét
- ahol \(x\) az indexmező értéke
- jellemzően modulo-n alapszik
- Ha jó a hasító fügvény, akkor nagyjából egyforma hosszúak lesznek a blokkláncok
- tehát a besorolás egyenletes
- Jó hasító függvénby esetén a blokklánc
B/Kblokkból áll
Hash (Statikus) - A=a keresési idő
- Ha az index és keresési mező eltér, akkor kupac szervezés jön
- Ha az index és keresési mező egyezik, akkor elég csak a
h(a)sorszámú kosarakat végignézni - Tárméret:
B, ha minden blokk tele
Nagy K nem jó öttlet, trust me bro
Kijöhetnek olyan blokklánccok, amikben csak egy rekord van
Így annyi blokk lenne foglalva, ahány rekord
(60% more empty space per empty space)
- Módosítások
Bkupacon végzett módosítás, oszd be...
a < A < b féle intervallumos keresésre nem alkalmas
Hash with 🪣 detour
Példa szerint a vödör mérete 2, a hash függvény \(h\in\{0,1,2,3\}\)
- Látni, hogy új elem beszúrása blokklánc bővítését jelenti
atörlésénélcfeljebb tolható,e-t pedig kihozhatjuk a blokkból- A blokk memóriába töltése a leg költségesebb, ha már memóriában van, az átszervezés nem nagy baj
- üres blokkot nem érdemes tárolni
- A jelen példában a hasító függvény láthatóan nem olyan jó, az utolsó 3-as vödörbe nem került adat, de az első vödröt (még ha üres is), el kell tárolni
Hash (dinamikus)
Előre nem rögzítjük a vödrök számát, a vödrök száma beszúráskor/törléskor változhat
Kiterjeszhető
- Minden vödör egy blokkból áll
- Keresési költség:
1 - Legyen \(k > \log (f)\)
fa rekordok várható számának felső korlátjakhosszú bináris sorozatból több van, mint ahány rekord
- A
hhasító függvény értéke egykhosszú bináris sorozat - Minden kosárhoz tartozik egy legfeljebb
khosszú bináris sorozat- kódszó
- A kosarakhoz rendelt kód prefix kód
- maximális kód hossza legyen
i
- maximális kód hossza legyen
Hash (Dinamikus) - Beszúrás
- Vegyük a
khosszúh(x)kódihosszú elejét, és az ennek megfelelő vödröt - ha van benne hely, win
- ha nincs benne, akkor csináljunk egy új vödröt és a következő bit szerint osszuk ketté a teli vödör tartalmát
- ha ez a bit mindegyikre megegyezik, akkor vegyük ezt a szétosztáshoz
A keresés hossza erősen változó lenne, mert ez az implementáció (még) kiegyensúllyozatlan fát képez
- A bináris fa levelei a kosárblokkok kódszavai
- A hasító függvény értékeiből annyi bitet tárolunk, ahányadik szinten járunk a fában
- A gráfot a memóriában tároljuk
Ha az új sor hasító értéke sok pontton megegyezik, akkor a gráf ágai is hosszúak lesznek
Hash (Dinamikus) "Kiegyensúllyozása"
This is mega brain time, you can't proceed if you don't have your papers close
before we start, let's assume our buckets can hold exactly two values, okay?
First, make an array of buckets and give it a nice label:
| 0 | 1 |
|---|---|
| - | - |
| - | - |
Put in three values with their h(x) value 0001, 1100 and 1001 using their first bit only:
| 0 | 1 |
|---|---|
| 0001 | 1001 |
| - | 1100 |
So, I want another value with their h(x) bein' 1010, but the 1 labeled field is full, I can't magically put in, right?
Oh, yes, we can with a simple trick:
| 00 | 01 | 10 | 11 |
|---|---|---|---|
| 0001 | - | 1001 | 1100 |
| - | - | 1010 | - |
- Ok, but that means instead of puttin' another bucket in, we just dubled the array
- ...yes, and now we identify a bucket with two bits, that's right, don't forget to rearrange the values to match their criteria
Egy fontos kitérő. Ha a vödör nem kell létezzen, ebben a modellben a párjának mutatója lesz a helyén mindaddig, míg nem kell oda beszúrni rekordot
Párja: 1 bitben tér csak el, példa
| 00 | 01 | 10 | 11 | |
|---|---|---|---|---|
| 0001 | - | - | 1100 | |
| Points to: | b1 | b1 | b4 | b4 |
...Igen, a tömbbünk nyilván vödrök mutatójával van tele
Lineáris hasító index
- A vödrök 1 vagy több blokkból is álhattnak
- Új vödröt akkor hozunk létre,ha egy előre megadott értéket elér a vödrökre jutó átlagos rekordszám
- 0-val kezdődik a sorszámozás, binárisan
- Adott \(n\) vödör esetén a hasitó függvény értékének utolsó \(\log(n)\) bitjét nézzük
- Van benne hely, letsgoo
- Nincs hely: új vödör és láncolhatjuk utána
- Ha nics megfelelő sorszámú vödör, akkor az első bitjén különböző párjához megyünk
Szabály
- \(h(x)_i\le m:\) a rekordot tegyük a \(h(x)_i\) vödörbe
- \(h(x)_i\le m\) ugye azt mondja, hogy a keresett indexen vödör (még) nem létezik
- else: \(h(x)_i - 2^{i-1}\) the place it goes
Példa - 1
- Hasító érték: 4 bit
- \(i=2\)
- 1
block= 2record- Küszöb: 3
\(m = 01\) (a legnagyobb sorszámú létező) blokk sorszáma
| 00 | 01 | 10 | 11 | |
|---|---|---|---|---|
| 0000 | 0101 | - | - | |
| 1010 | 1111 | - | - | |
| Overflow: | - | - | - | - |
Szúrjunk be az előző példábal egy 0101-es rekordot
\(m = 01\)
| 00 | 01 | 10 | 11 | |
|---|---|---|---|---|
| 0000 | 0101 | - | - | |
| 1010 | 1111 | - | - | |
| Overflow: | - | 01 | - | - |
| 01 |
|---|
| 0101 |
Tehát mivel az átlagos rekordszámunk nem lépte át a küszöbszámot, ezért túlcsorduló vödröt hozunk létre, és láncoljuk a heap-hez hasonlóan
Példa - 2
- Hasító érték: 4 bit
- \(i=2\)
- 1
block= 2record- Küszöb: 2
| 00 | 01 | 10 | 11 | |
|---|---|---|---|---|
| 0000 | 0101 | - | - | |
| 1010 | 1111 | - | - | |
| Overflow: | - | - | - | - |
\(m = 01\) (a legnagyobb sorszámú létező) blokk sorszáma
Szúrjunk be az előző példábal egy 0101-es rekordot, ha a küszöbszám 2
\(m = 10\)
| 00 | 01 | 10 | 11 | |
|---|---|---|---|---|
| 0000 | 0101 | 1010 | - | |
| 0101 | 1111 | - | ||
| Overflow: | - | - | - | - |
Tehát mivel az átlagos rekordszámunk átlépte a küszöbszámot, ezért a tömbünk felrobban, létrehozunk egy új vödröt, és az egészet átrendezzük, hogy az invariánsunk ne sérüljön
What next?
Ha elértük az \(m=11\) állapotot, tehát minden vödör létezik, de megint átlépnénk a küszöbátlagot, akkor duplázzuk meg a tömbböt, és a 4 bites kódból már 3-at használunk fel az azonosításra
Tehát duplán felrobban az egész, nice 👍