Cuckoo-hajautus on algoritmi, joka ratkaisee hash - arvojen törmäykset taulukossa , jossa noutoaika on vakio pahimmassa tapauksessa [ .
Ehdotettu vuonna 2001 [1] . Nimi viittaa joidenkin käkilajien käyttäytymiseen , kun poikanen työntää munia tai muita poikasia ulos pesästä; Samoin algoritmi tarjoaa mahdollisuuden työntää vanha avain ulos, kun uusi avain asetetaan.
Käkihajautus on eräänlainen avoin osoitus , jossa hash-taulukon jokainen ei-tyhjä solu sisältää avaimen tai avain-arvo- parin . Hajautusfunktiota käytetään määrittämään kunkin avaimen sijainti, ja sen läsnäolo taulukossa (tai siihen liittyvä arvo) voidaan löytää tutkimalla kyseistä solua taulukossa. Avoin osoitus kärsii kuitenkin törmäyksistä , joita tapahtuu, kun useampi kuin yksi avain päätyy samaan soluun. Käkihajautuksen perusideana on ratkaista törmäykset käyttämällä kahta hash-funktiota yhden sijasta. Tämä tarjoaa kaksi mahdollista paikkaa hash-taulukossa kullekin avaimelle. Yhdessä algoritmin tavallisista muunnelmista hash-taulukko jaetaan kahteen pienempään taulukkoon, ja jokainen hash-funktio antaa indeksin jompaankumpaan näistä kahdesta taulukosta. On myös mahdollista varmistaa, että molemmat hash-funktiot indeksoidaan samassa taulukossa.
Hakeminen vaatii vain kahden paikan tarkastelemista hash-taulukossa, pahimmassa tapauksessa jatkuvaa aikaa ( katso "o" iso ja "o" pieni ). Tämä on toisin kuin monet muut hash-taulukkoalgoritmit, jotka eivät tarjoa vakioita noutoaikoja pahimmassa tapauksessa. Poistaminen voidaan tehdä myös tyhjentämällä avaimen sisältävä solu pahimmassa tapauksessa vakioajassa, mikä on helpompaa kuin muissa menetelmissä, kuten lineaarisessa luotauksessa .
Kun uusi avain lisätään ja toinen soluista on tyhjä, avain voidaan sijoittaa kyseiseen soluun. Siinä tapauksessa, että molemmat solut ovat varattuina, on tarpeen siirtää muut avaimet muihin paikkoihin (tai päinvastoin niiden aikaisempiin paikkoihin), jotta uudelle avaimelle saadaan tilaa. Käytetään ahnetta algoritmia - avain sijoitetaan johonkin mahdollisista asennoista, "työntämällä" kaikki tässä asennossa olleet avaimet. Poistettu avain asetetaan sitten vaihtoehtoiseen asentoonsa, jolloin kaikki siellä mahdollisesti olleet avain poistetaan. Prosessi jatkuu, kunnes tyhjä paikka löytyy. On kuitenkin mahdollista, että lisäysprosessi epäonnistuu, joutuu äärettömään silmukkaan tai kun ketju on liian pitkä (pidempi kuin ennalta määrätty kynnys, joka riippuu logaritmisesti taulukon pituudesta). Tässä tapauksessa tiivistetaulukko rakennetaan uudelleen paikoilleen uusilla hash-funktioilla :
Uutta taulukkoa ei tarvitse perustaa uudelleenkäsittelyä varten – voimme yksinkertaisesti käydä taulukon läpi ja poistaa ja lisätä uudelleen avaimet, jotka eivät ole oikeassa asennossa. [yksi]Pagh & Rodler, "Cuckoo Hashing"
Odotettu lisäysaika on vakio [1] , vaikka otetaan huomioon mahdollinen taulukon uudelleenrakentamistarve, kunhan avainten määrä on alle puolet hash-taulukon kapasiteetista, eli kuormituskerroin on alle 50 %.
Tämän varmistamiseksi käytetään satunnaisgraafiteoriaa - voit muodostaa ohjaamattoman graafin , jota kutsutaan "käkigraafiksi", jossa kärjet ovat hash-taulukon soluja ja kunkin hajautettavan pisteen reunat yhdistävät kaksi mahdollista paikkaa ( hash-taulukko). Sitten ahne algoritmi arvojoukon lisäämiseksi käkihajautustaulukkoon onnistuu, jos ja vain, jos tämän arvojoukon käkigraafi on pseudometsä , kaavio, jossa on enintään yksi sykli jokaisessa yhdistetyssä komponentissa . Mikä tahansa kärkipisteiden luoma aligraafi, jossa on enemmän särmiä kuin pisteiden lukumäärä, vastaa avaimia, joille tiivistetaulukossa ei ole tarpeeksi paikkoja. Jos hash-funktio valitaan satunnaisesti, käkigraafi on satunnainen graafi Erdős - Rényi-mallissa . Suurella todennäköisyydellä satunnaisessa graafissa, jossa reunojen lukumäärän suhde kärkien lukumäärään on rajattu yli 1/2, graafi on pseudometsä ja käkihajautusalgoritmi paikantaa onnistuneesti kaikki avaimet. Lisäksi sama teoria osoittaa, että käkigraafin yhdistettyjen komponenttien odotettu koko on pieni, mikä varmistaa vakion odotetun lisäysajan [2] .
Kun otetaan huomioon seuraavat kaksi hash-funktiota:
k | h(k) | h'(k) |
---|---|---|
kaksikymmentä | 9 | yksi |
viisikymmentä | 6 | neljä |
53 | 9 | neljä |
75 | 9 | 6 |
100 | yksi | 9 |
67 | yksi | 6 |
105 | 6 | 9 |
3 | 3 | 0 |
36 | 3 | 3 |
39 | 6 | 3 |
Kahden seuraavan taulukon sarakkeet näyttävät tiivistetaulukon tilan elementtien lisäämisen jälkeen.
1. h(k) taulukko | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
kaksikymmentä | viisikymmentä | 53 | 75 | 100 | 67 | 105 | 3 | 36 | 39 | |
0 | ||||||||||
yksi | 100 | 67 | 67 | 67 | 67 | 100 | ||||
2 | ||||||||||
3 | 3 | 36 | 36 | |||||||
neljä | ||||||||||
5 | ||||||||||
6 | viisikymmentä | viisikymmentä | viisikymmentä | viisikymmentä | viisikymmentä | 105 | 105 | 105 | viisikymmentä | |
7 | ||||||||||
kahdeksan | ||||||||||
9 | kaksikymmentä | kaksikymmentä | 53 | 75 | 75 | 75 | 53 | 53 | 53 | 75 |
kymmenen |
2. h'(k) taulukko | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
kaksikymmentä | viisikymmentä | 53 | 75 | 100 | 67 | 105 | 3 | 36 | 39 | |
0 | 3 | 3 | ||||||||
yksi | kaksikymmentä | kaksikymmentä | kaksikymmentä | kaksikymmentä | kaksikymmentä | kaksikymmentä | kaksikymmentä | kaksikymmentä | ||
2 | ||||||||||
3 | 39 | |||||||||
neljä | 53 | 53 | 53 | viisikymmentä | viisikymmentä | viisikymmentä | 53 | |||
5 | ||||||||||
6 | 75 | 75 | 75 | 67 | ||||||
7 | ||||||||||
kahdeksan | ||||||||||
9 | 100 | 100 | 100 | 100 | 105 | |||||
kymmenen |
Jos haluat lisätä elementin 6, saat äärettömän silmukan. Taulukon viimeiseltä riviltä löytyy sama alkutilanne kuin alussa.
avain | pöytä 1 | taulukko 2 | ||
vanha arvo |
uusi arvo |
vanha arvo |
uusi arvo | |
6 | viisikymmentä | 6 | 53 | viisikymmentä |
53 | 75 | 53 | 67 | 75 |
67 | 100 | 67 | 105 | 100 |
105 | 6 | 105 | 3 | 6 |
3 | 36 | 3 | 39 | 36 |
39 | 105 | 39 | 100 | 105 |
100 | 67 | 100 | 75 | 67 |
75 | 53 | 75 | viisikymmentä | 53 |
viisikymmentä | 39 | viisikymmentä | 36 | 39 |
36 | 3 | 36 | 6 | 3 |
6 | viisikymmentä | 6 | 53 | viisikymmentä |
Käkihajautuksen muunnelmia on tutkittu lähinnä tilankäytön parantamiseksi kuormituskerrointa nostamalla . Näissä versioissa voidaan saavuttaa yli 50 %:n kuormituskynnys. Joitakin näistä menetelmistä voidaan käyttää vähentämään merkittävästi tarvittavien tietorakenteen uusien määrää.
Useampaa kuin kahta hash-funktiota käyttävän käkitiivistyksen yleistämisen voidaan odottaa hyödyntävän hash-taulukkoa paremmin, mikä uhraa jonkin verran haku- ja lisäysnopeutta. Kolmen hash-funktion käyttö nostaa latauskertoimen 91 %:iin [3] . Toinen käkihajautuksen yleistys, nimeltään block cuckoo hashing , sisältää useamman kuin yhden avaimen solua kohden. Kahden näppäimen käyttö solua kohti mahdollistaa kuormituksen nostamisen yli 80 % [4] .
Toinen tutkittu vaihtoehto on käkihajautus marginaalilla . "Stock" on vakiopituinen avainten joukko, jota käytetään tallentamaan avaimia, joita ei voida lisätä onnistuneesti päähajautustaulukkoon. Tämä muutos vähentää epäonnistumisten määrää käänteispolynomifunktioon asteella, joka voi olla mielivaltaisen suuri lisäämällä marginaalin kokoa. Suuri marginaali tarkoittaa kuitenkin hitaampaa hakua avaimelle, joka ei ole päätaulukossa tai jos se on marginaalissa. Varastoa voidaan käyttää yhdessä useamman kuin kahden hash-funktion tai estää käkihajautustoiminnon, jotta saavutetaan sekä korkea käyttöaste että alhainen lisäysvirhe [5] . Cuckoo-hajautusanalyysi on laajentunut enemmän kuin käytännön tiivistefunktioihin, ei vain teoreettisessa hash-analyysissä käytettyihin satunnaisiin hajautusmalleihin [6] .
Jotkut tutkijat ehdottavat, että joissakin prosessorin välimuistissa käytetään yksinkertaistettua käkihajautuksen yleistystä, jota kutsutaan epäsymmetriseksi assosiatiiviseksi välimuistiksi . [7]
On muitakin algoritmeja, jotka käyttävät useita hajautusfunktioita, erityisesti Bloom-suodatin , muistitehokas tietorakenne sumeille joukoille. Vaihtoehtoinen tietorakenne samojen sumeiden joukkojen ongelmille, joka perustuu käkihajautusjärjestelmään, nimeltään Käkisuodatin , käyttää vielä vähemmän muistia ja (toisin kuin klassiset Bloom-suodattimet) mahdollistaa elementtien poistamisen, ei vain lisäyksen ja olemassaolon tarkistamista. Näiden menetelmien teoreettinen analyysi on kuitenkin paljon heikompi kuin Bloom-suodattimien analyysi [8] .
Vuonna 2006 tehdyt tutkimukset [9] osoittivat, että käkihajautus on huomattavasti nopeampi kuin nykyaikaisten prosessorien välimuistissa olevien pienten hash-taulukoiden ketjutusmenetelmä . Samana vuonna [10] kehitettiin lohkoversio Cuckoo hashingista (lohko sisältää useamman kuin yhden avaimen), joka on nopeampi kuin perinteiset menetelmät suurille hash-taulukoille korkean kuormituskertoimen tapauksessa. Cuckoo hash -taulukon lohkoversion nopeutta tutkittiin vuonna 2009 [11] .