自己實(shí)現(xiàn)基于key-value的NoSQL數(shù)據(jù)庫(kù)(三)—— B+樹(shù)和Hash算法

前一篇文章中秘血,效率成了很關(guān)鍵的問(wèn)題奶卓,比較數(shù)據(jù)庫(kù)還是需要能高效查找數(shù)據(jù)才行

那么如何解決查找問(wèn)題呢?一個(gè)很好的辦法是使用B+樹(shù)存炮,關(guān)于B+樹(shù)就不做多的介紹了炬搭,網(wǎng)上有很多
這里只貼出定義

B-樹(shù)

是一種多路搜索樹(shù)(并不是二叉的):  
1.定義任意非葉子結(jié)點(diǎn)最多只有M個(gè)兒子;且M>2穆桂;  
2.根結(jié)點(diǎn)的兒子數(shù)為[2, M]宫盔;  
3.除根結(jié)點(diǎn)以外的非葉子結(jié)點(diǎn)的兒子數(shù)為[M/2, M];  
4.每個(gè)結(jié)點(diǎn)存放至少M(fèi)/2-1(取上整)和至多M-1個(gè)關(guān)鍵字享完;(至少2個(gè)關(guān)鍵字)  
5.非葉子結(jié)點(diǎn)的關(guān)鍵字個(gè)數(shù)=指向兒子的指針個(gè)數(shù)-1灼芭;
6.非葉子結(jié)點(diǎn)的關(guān)鍵字:K[1], K[2], …, K[M-1];且K[i] < K[i+1]般又;  
7.非葉子結(jié)點(diǎn)的指針:P[1], P[2], …, P[M]彼绷;其中P[1]指向關(guān)鍵字小于K[1]的子樹(shù),P[M]指向關(guān)鍵字大于K[M-1]的子樹(shù)茴迁,其它P[i]指向關(guān)鍵字屬于(K[i-1], K[i])的子樹(shù)寄悯;
8.所有葉子結(jié)點(diǎn)位于同一層;  
如:(M=3)  

B+樹(shù)

B+樹(shù)是B-樹(shù)的變體堕义,也是一種多路搜索樹(shù):  
1.其定義基本與B-樹(shù)同猜旬,除了:  
2.非葉子結(jié)點(diǎn)的子樹(shù)指針與關(guān)鍵字個(gè)數(shù)相同;  
3.非葉子結(jié)點(diǎn)的子樹(shù)指針P[i],指向關(guān)鍵字值屬于[K[i], K[i+1])的子樹(shù)(B-樹(shù)是開(kāi)區(qū)間)洒擦;  
5.為所有葉子結(jié)點(diǎn)增加一個(gè)鏈指針椿争;  
6.所有關(guān)鍵字都在葉子結(jié)點(diǎn)出現(xiàn);  

至于實(shí)現(xiàn)秘遏,給出一個(gè)連接可以看看 https://github.com/begeekmyfriend/bplustree
然后數(shù)據(jù)庫(kù)的鍵是字符串型的丘薛,如果轉(zhuǎn)換出數(shù)字呢嘉竟?答案是用hash算法邦危,網(wǎng)上也有很多經(jīng)典的實(shí)現(xiàn)
這里給出Bizzard公司的經(jīng)典算法(采用了部分,不是全部)

#pragma once  
  
#include <string>  
  
unsigned long cryptTable[0x500];  
  
void prepareCryptTable()  
{  
    unsigned long seed = 0x00100001, index1 = 0, index2 = 0, i;  
  
    for (index1 = 0; index1 < 0x100; index1++)  
    {  
        for (index2 = index1, i = 0; i < 5; i++, index2 += 0x100)  
        {  
            unsigned long temp1, temp2;  
            seed = (seed * 125 + 3) % 0x2AAAAB;  
            temp1 = (seed & 0xFFFF) << 0x10;  
            seed = (seed * 125 + 3) % 0x2AAAAB;  
            temp2 = (seed & 0xFFFF);  
            cryptTable[index2] = (temp1 | temp2);  
        }  
    }  
}  
  
unsigned long HashString(const std::string& key, unsigned long dwHashType)  
{  
    unsigned char *ckey = (unsigned char *)key.c_str();  
    unsigned long seed1 = 0x7FED7FED, seed2 = 0xEEEEEEEE;  
    int ch;  
    while (*ckey != 0)  
    {  
        ch = toupper(*ckey++);  
        seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2);  
        seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;  
    }  
    return seed1;  
}  

暴雪的源碼中是用了三次hash值來(lái)決定一個(gè)數(shù)據(jù)的舍扰,數(shù)據(jù)沖突的幾率是1: 18889465931478580854784幾乎不可能出現(xiàn)
而我們這里由于純粹的學(xué)習(xí)原理而已倦蚪,所以采用一次就行了

接下來(lái)就是要把這兩個(gè)算法整合進(jìn)數(shù)據(jù)庫(kù)中,用來(lái)代替以前的搜索算法
需要對(duì)算法進(jìn)行一定的修改

在下一張章中實(shí)現(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末边苹,一起剝皮案震驚了整個(gè)濱河市陵且,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌个束,老刑警劉巖慕购,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異茬底,居然都是意外死亡沪悲,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)阱表,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)殿如,“玉大人,你說(shuō)我怎么就攤上這事最爬∩婺伲” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵爱致,是天一觀的道長(zhǎng)烤送。 經(jīng)常有香客問(wèn)我,道長(zhǎng)糠悯,這世上最難降的妖魔是什么胯努? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮逢防,結(jié)果婚禮上叶沛,老公的妹妹穿的比我還像新娘。我一直安慰自己忘朝,他們只是感情好灰署,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般溉箕。 火紅的嫁衣襯著肌膚如雪晦墙。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,046評(píng)論 1 285
  • 那天肴茄,我揣著相機(jī)與錄音晌畅,去河邊找鬼。 笑死寡痰,一個(gè)胖子當(dāng)著我的面吹牛抗楔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拦坠,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼连躏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了贞滨?” 一聲冷哼從身側(cè)響起入热,我...
    開(kāi)封第一講書(shū)人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晓铆,沒(méi)想到半個(gè)月后勺良,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡骄噪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年尚困,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腰池。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡尾组,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出示弓,到底是詐尸還是另有隱情讳侨,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布奏属,位于F島的核電站跨跨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏囱皿。R本人自食惡果不足惜勇婴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嘱腥。 院中可真熱鬧耕渴,春花似錦、人聲如沸齿兔。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至添诉,卻和暖如春屁桑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背栏赴。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工蘑斧, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人须眷。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓竖瘾,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親柒爸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子准浴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容