Leveldb原始碼分析 19

2021-06-14 17:05:14 字數 2781 閱讀 1341

引數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...