利用C++實(shí)現(xiàn)?然連接操作算法
1. 實(shí)驗(yàn)?zāi)康?/h2>
本次實(shí)驗(yàn)三需要完成的內(nèi)容為實(shí)現(xiàn)然連接(natural join)操作算法,對(duì)兩個(gè)關(guān)系進(jìn)然連接,具體實(shí)現(xiàn)基于塊的嵌套循環(huán)連接(Block-based Nested Loop Join)算法。
我們要實(shí)現(xiàn)的函數(shù)在 executer.cpp 文件中。
bool NestedLoopJoinOperator::execute(int numAvailableBufPages,
File &resultFile)2. 實(shí)驗(yàn)內(nèi)容
首先,我們讀取兩個(gè)表頭的信息
TableId leftTableId = catalog->getTableId("r");
TableId rightTableId = catalog->getTableId("s");
badgerdb::File left = File::open(catalog->getTableFilename(leftTableId));
badgerdb::File right = File::open(catalog->getTableFilename(rightTableId));運(yùn)用兩層循環(huán)尋找兩個(gè)表中名稱與類型完全相同的屬性,將他們?nèi)繕?biāo)記出來,用于之后的自然連接操作。
vector<int> leftForeignKeyId;
vector<int> rightForeignKeyId;
for (int i = 0; i < leftTableSchema.getAttrCount(); i++)
{
for (int j = 0; j < rightTableSchema.getAttrCount(); j++)
{
if ((leftTableSchema.getAttrName(i) == rightTableSchema.getAttrName(j)) && (leftTableSchema.getAttrType(i) == rightTableSchema.getAttrType(j)))
{
leftForeignKeyId.push_back(i);
rightForeignKeyId.push_back(j);
break;
}
}
}準(zhǔn)備操作做完后,開始進(jìn)行自然連接操作。
用循環(huán)從磁盤中讀取兩個(gè)頁(yè)面的信息,記錄 io 操作次數(shù)
for (badgerdb::FileIterator leftPage = left.begin(); leftPage != left.end(); leftPage++)
{
badgerdb::Page *bufferedLeftPage;
bufMgr->readPage(&left, (*leftPage).page_number(), bufferedLeftPage);
numIOs += 1;
for (badgerdb::FileIterator rightPage = right.begin(); rightPage != right.end(); rightPage++)
{
badgerdb::Page *bufferedRightPage;
bufMgr->readPage(&right, (*rightPage).page_number(), bufferedRightPage);
numIOs += 1;之后,從表中讀取全部的元組的信息,進(jìn)行對(duì)比。
讀取的元組信息有特殊的格式,并不能直接利用,所以需要先了解元組在表中儲(chǔ)存的格式,然后進(jìn)行解讀。元組的存儲(chǔ)方式可以從 storage.cpp 中的 createTupleFromSQLStatement 函數(shù)中得知。
switch (dataType) { // (int) 56 (0011 1000) -> (char) '\0''\0''\0''8'
case INT: { // convert int value into 4 byte representation
case CHAR: { // (char(5) ) 'abc' -> 'abc00'
case VARCHAR: { // (varchar(8) ) 'abc' -> '3''abc' (3 refer to the ascii
// code number correspond alpha)于是,我們根據(jù)注釋的存儲(chǔ)方式編寫解析函數(shù),該函數(shù)輸入為文件中存儲(chǔ)的元組,輸出為數(shù)組表示的直觀的元組內(nèi)容。
vector<string> analyze(string record, badgerdb::TableSchema schema)
先讀取其中一個(gè)表的元組,用塊來存儲(chǔ)。
for (badgerdb::PageIterator leftRecord = bufferedLeftPage->begin(); leftRecord != bufferedLeftPage->end(); leftRecord++)
{
vector<string> leftInfo = analyze(*leftRecord, leftTableSchema);
numUsedBufPages += 1;
block.push_back(leftInfo);
if (block.size() < BLOCK_SIZE)
{
continue;
}然后讀取另一個(gè)表的元組信息,
for (badgerdb::PageIterator rightRecord = bufferedRightPage->begin(); rightRecord != bufferedRightPage->end(); rightRecord++)
{
numUsedBufPages += 1;將兩個(gè)元組當(dāng)中的屬性名相同的屬性列信息進(jìn)行對(duì)比,
bool f = true;
for(int i = 0; i < leftForeignKeyId.size(); i++)
{
if(leftInfo[leftForeignKeyId[i]] != rightInfo[rightForeignKeyId[i]])
{
f = false;
break;
}
}如果全部相同,則代表需要進(jìn)行自然連接操作。
if(f)
{
string current_line = "INSERT INTO TEMP_TABLE VALUES (" + leftInfo[0];
for (int i = 1; i < leftTableSchema.getAttrCount(); i++)
{
current_line = current_line + ", " + leftInfo[i];
}
for (int i = 0; i < rightTableSchema.getAttrCount(); i++)
{
current_line = current_line + ", " + rightInfo[i];
}
current_line = current_line + ");";
string tuple = HeapFileManager::createTupleFromSQLStatement(current_line, catalog);
numResultTuples += 1;
HeapFileManager::insertTuple(tuple, resultFile, bufMgr);
}否則不進(jìn)行任何操作。
在全部循環(huán)都結(jié)束之后,塊中可能還會(huì)有剩余的信息沒有進(jìn)行處理,此時(shí)再單獨(dú)對(duì)剩余信息進(jìn)行處理,代碼基本相同。
3. 實(shí)驗(yàn)結(jié)果
代碼運(yùn)行結(jié)果如下:

到此這篇關(guān)于利用C++實(shí)現(xiàn)?然連接操作算法的文章就介紹到這了,更多相關(guān)C++連接操作算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言詳細(xì)講解qsort函數(shù)的使用
排序方法有很多種:選擇排序,冒泡排序,歸并排序,快速排序等。看名字都知道快速排序是目前公認(rèn)的一種比較好的排序算法。因?yàn)樗俣群芸欤韵到y(tǒng)也在庫(kù)里實(shí)現(xiàn)這個(gè)算法,便于我們的使用。這就是qsort函數(shù)2022-04-04
C++構(gòu)造函數(shù)和析構(gòu)函數(shù)的使用與講解
今天小編就為大家分享一篇關(guān)于C++構(gòu)造函數(shù)和析構(gòu)函數(shù)的使用與講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12
VC動(dòng)態(tài)生成菜單項(xiàng)的實(shí)現(xiàn)方法
這篇文章主要介紹了VC動(dòng)態(tài)生成菜單項(xiàng)的實(shí)現(xiàn)方法,在桌面應(yīng)用程序開發(fā)中常會(huì)用到的一個(gè)功能,需要的朋友可以參考下2014-08-08
C語(yǔ)言基于EasyX庫(kù)實(shí)現(xiàn)有圖形界面時(shí)鐘
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言基于EasyX庫(kù)實(shí)現(xiàn)有圖形界面時(shí)鐘,獲得本地時(shí)間,輸出文字,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
解析C++編程中異常相關(guān)的堆棧展開和throw()異常規(guī)范
這篇文章主要介紹了C++編程中異常相關(guān)的堆棧展開和throw()異常規(guī)范,throw()規(guī)范部分文中結(jié)合了C++11標(biāo)準(zhǔn)的新特性來講,需要的朋友可以參考下2016-01-01
C語(yǔ)言 數(shù)據(jù)結(jié)構(gòu)雙向鏈表簡(jiǎn)單實(shí)例
這篇文章主要介紹了C語(yǔ)言 數(shù)據(jù)結(jié)構(gòu)雙向鏈表簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-03-03
C++ 中的虛函數(shù)表及虛函數(shù)執(zhí)行原理詳解
這篇文章主要介紹了C++ 中的虛函數(shù)表及虛函數(shù)執(zhí)行原理詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
C++編程中使用設(shè)計(jì)模式中的policy策略模式的實(shí)例講解
這篇文章主要介紹了C++編程中使用設(shè)計(jì)模式中的policy策略模式的實(shí)例講解,文章最后對(duì)策略模式的優(yōu)缺點(diǎn)有一個(gè)簡(jiǎn)單的總結(jié),需要的朋友可以參考下2016-03-03

