引數edit也會被函式修改。
11.4.1 函式流程
下面就來具體分析函式**。
s1 為edit設定log number等4個計數器。
if (edit->has_log_number_) else edit->setlognumber(log_number_);
if(!edit->has_prev_log_number_) edit->setprevlognumber(prev_log_number_);
edit->setnextfile(next_file_number_);
edit->setlastsequence(last_sequence_);
要保證edit自己的log number是比較大的那個,否則就是致命錯誤。保證edit的log number小於next file number,否則就是致命錯誤-見9.1小節。
s2 建立乙個新的version v,並把新的edit變動儲存到v中。
version* v = new version(this);
finalize(v); //如前分析,只是為v計算執行compaction的最佳level
s3 如果manifest檔案指標不存在,就建立並初始化乙個新的manifest檔案。這只會發生在第一次開啟資料庫時。這個manifest檔案儲存了current version的快照。
std::string new_manifest_file;
status s;
if (descriptor_log_ == null)
}
s4 向manifest寫入一條新的log,記錄current version的資訊。在檔案寫操作時unlock鎖,寫入完成後,再重新lock,以防止浪費在長時間的io操作上。
mu->unlock();
if (s.ok()) }}
//如果剛才建立了乙個manifest檔案,通過寫乙個指向它的current檔案
//安裝它;不需要再次檢查manifest是否出錯,因為如果出錯後面會刪除它
if (s.ok() &&!new_manifest_file.empty())
mu->lock();
s5 安裝這個新的version
if (s.ok()) else
}
流程的s4中,函式會檢查manifest檔案是否已經有了這條record,那麼什麼時候會有呢?
主函式使用到了幾個新的輔助函式writesnapshot,manifestcontains和setcurrentfile,下面就來分析。
11.4.2 writesnapshot()
函式宣告:status writesnapshot(log::writer*log)
把currentversion儲存到*log中,資訊包括comparator名字、compaction點和各級sstable檔案,函式邏輯很直觀。
s1 首先宣告乙個新的versionedit edit;
s2 設定comparator:edit.setcomparatorname(icmp_.user_comparator()->name());
s3 遍歷所有level,根據compact_pointer_[level],設定compaction點:
edit.setcompactpointer(level, key);
s4 遍歷所有level,根據current_->files_,設定sstable檔案集合:edit.addfile(level, ***)
std::string record;
edit.encodeto(&record);
returnlog->addrecord(record);
以上就是writesnapshot的**邏輯。
11.4.3 manifestcontains()
函式宣告:bool manifestcontains(conststd::string& record)
如果當前manifest包含指定的record就返回true,來看看函式邏輯。
s1 根據當前的manifest_file_number_檔案編號開啟檔案,建立sequentialfile物件
s2 根據建立的sequentialfile物件建立log::reader,以讀取檔案
s3 呼叫log::reader的readrecord依次讀取record,如果和指定的record相同,就返回true,沒有相同的record就返回false
setcurrentfile很簡單,就是根據指定manifest檔案編號,構造出manifest檔名,並寫入到current即可。
在指定的version中查詢指定key的大概位置。
假設version中有n個sstable檔案,並且落在了地i個sstable的key空間內,那麼返回的位置= sstable1檔案大小+sstable2檔案大小 + … + sstable (i-1)檔案大小
+ key在sstable i中的大概偏移。
可分為兩段邏輯。
1 首先直接和sstable的max key作比較,如果key > max key,直接跳過該檔案,還記得sstable檔案是有序排列的。
對於level >0的檔案集合而言,如果如果key < sstable檔案的min key,則直接跳出迴圈,因為後續的sstable的min key肯定大於key。
versionset的相關函式暫時分析到這裡,compaction部分後需單獨分析。
leveldb原始碼分析1
leveldb是乙個key value型的儲存引擎,由google開發,並宣布在bsd許可下開放源 plain git clone plain cd leveldb make all 此時生成libleveldb.a庫檔案。拷貝leveldb的標頭檔案到 usr include下 plain cp ...
levelDB原始碼分析 SSTable
sstable是bigtable中至關重要的一塊,對於leveldb來說也是如此,對leveldb的sstable實現細節的了解也有助於了解bigtable中一些實現細節。本節內容主要講述sstable的靜態布局結構,sstable檔案形成了不同level的層級結構,至於這個層級結構是如何形成的我們...
Leveldb原始碼分析 1
前言 看了一點oceanbase,沒有意志力繼續堅持下去了,暫時就此中斷,基本上算把master看完了,比較重要的update server和merge server 卻沒有細看。中間又陸續研究了hadoop的原始碼,主要是name node和寫入pipeline。主要的目的是想看看name nod...