精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

LevelDB源碼之三SSTable

數據庫
  上一節提到的MemTable是內存表,而當內存表增長到一定程度時(memtable.size> Options::write_buffer_size),會將當前的MemTable數據持久化(LevelDB中實際有兩份MemTable,后面LevelDB數據庫備忘時會講)。持久化的文件(sst文件)稱之為Table,LevelDB中的Table分為不同的層級,當前版本的最大層級為7(0-6),table中level0的數據最新,level6的數據最舊。

  上一節提到的MemTable是內存表,而當內存表增長到一定程度時(memtable.size> Options::write_buffer_size),會將當前的MemTable數據持久化(LevelDB中實際有兩份MemTable,后面LevelDB數據庫備忘時會講)。持久化的文件(sst文件)稱之為Table,LevelDB中的Table分為不同的層級,當前版本的***層級為7(0-6),table中level0的數據***,level6的數據最舊。

  Compaction動作負責觸發內存表到SSTable的轉換,LOG恢復時也會執行,這里不關心Compaction或恢復的任何細節,后面會單獨備忘。

  LevelDB通過BuildTable方法完成SSTable的構建,其創建SSTable文件并將memtable中的記錄依次寫入文件。BuildTable帶了一個輸出參數,FileMetaData:

 

  1. 1     struct FileMetaData { 
  2.  2         int refs; 
  3.  3         int allowed_seeks;          // Seeks allowed until compaction 
  4.  4         uint64_t number; 
  5.  5         uint64_t file_size;         // File size in bytes 
  6.  6         InternalKey smallest;       // Smallest internal key served by table 
  7.  7         InternalKey largest;        // Largest internal key served by table 
  8.  8 
  9.  9         FileMetaData() : refs(0), allowed_seeks(1 << 30), file_size(0) { } 

 

  number為一個遞增的序號,用于創建文件名,allowed_seeks作者有提到,是當前文件在Compaction到下一級之前允許Seek的次數,這個次數和文件大小相關,文件越大,Compaction之前允許Seek的次數越多,這個Version備忘時也會提。

  BuildTable方法中真正做事的時TableBuilder,通過調用Add方法將所有記錄添加到數據表中,完成SSTable創建。

  TableBuilder主要做了如下幾件事:

  創建Index Block:用于Data Block的快速定位

  將數據分為一個個的Data Block

  如文件需要壓縮,執行壓縮動作

  依次寫入Data Block、Meta Block、Index Block、Footer Block,形成完整的SSTable文件結構

  其中階段1-3由Add方法完成,階段4由Finish方法完成,先來看Add方法:

 

  1. 1 void TableBuilder::Add(const Slice& key, const Slice& value) { 
  2.  2         Rep* r = rep_; 
  3.  3         assert(!r->closed); 
  4.  4         if (!ok()) return
  5.  5         if (r->num_entries > 0) { 
  6.  6             assert(r->options.comparator->Compare(key, Slice(r->last_key)) > 0); 
  7.  7         } 
  8.  8 
  9.  9         //Index Block:Data Block的索引元數據。 
  10. 10         if (r->pending_index_entry) { 
  11. 11             assert(r->data_block.empty()); 
  12. 12             r->options.comparator->FindShortestSeparator(&r->last_key, key); 
  13. 13             std::string handle_encoding; 
  14. 14             r->pending_handle.EncodeTo(&handle_encoding); 
  15. 15             r->index_block.Add(r->last_key, Slice(handle_encoding)); 
  16. 16             r->pending_index_entry = false
  17. 17         } 
  18. 18 
  19. 19         r->last_key.assign(key.data(), key.size()); 
  20. 20         r->num_entries++; 
  21. 21         r->data_block.Add(key, value); 
  22. 22 
  23. 23         const size_t estimated_block_size = r->data_block.CurrentSizeEstimate(); 
  24. 24         if (estimated_block_size >= r->options.block_size) { 
  25. 25             Flush();    //超過單數據塊大小,寫入文件。 
  26. 26         } 
  27. 27     } 

 

  Add方法創建Data Block、IndexBlock,DataBlcok通過Flush刷入磁盤文件。

  再來看Finish方法:

 

  1. 1     Status TableBuilder::Finish() { 
  2.  2         //Data Block 
  3.  3         Rep* r = rep_; 
  4.  4         Flush(); 
  5.  5 
  6.  6         assert(!r->closed); 
  7.  7         r->closed = true
  8.  8         
  9.  9         //Meta Block 
  10. 10         BlockHandle metaindex_block_handle; 
  11. 11         BlockHandle index_block_handle; 
  12. 12         if (ok())  
  13. 13         { 
  14. 14             BlockBuilder meta_index_block(&r->options); 
  15. 15             // TODO(postrelease): Add stats and other meta blocks 
  16. 16             WriteBlock(&meta_index_block, &metaindex_block_handle); 
  17. 17         } 
  18. 18 
  19. 19         //Index Block 
  20. 20         if (ok()) { 
  21. 21             if (r->pending_index_entry) { 
  22. 22                 r->options.comparator->FindShortSuccessor(&r->last_key); 
  23. 23                 std::string handle_encoding; 
  24. 24                 r->pending_handle.EncodeTo(&handle_encoding); 
  25. 25                 r->index_block.Add(r->last_key, Slice(handle_encoding)); 
  26. 26                 r->pending_index_entry = false
  27. 27             } 
  28. 28             WriteBlock(&r->index_block, &index_block_handle); 
  29. 29         } 
  30. 30 
  31. 31         //Footer 
  32. 32         if (ok())  
  33. 33         { 
  34. 34             Footer footer; 
  35. 35             footer.set_metaindex_handle(metaindex_block_handle);    // 
  36. 36             footer.set_index_handle(index_block_handle); 
  37. 37             std::string footer_encoding; 
  38. 38             footer.EncodeTo(&footer_encoding); 
  39. 39             r->status = r->file->Append(footer_encoding); 
  40. 40             if (r->status.ok()) { 
  41. 41                 r->offset += footer_encoding.size(); 
  42. 42             } 
  43. 43         } 
  44. 44         return r->status; 
  45. 45     } 

 

  Finish依次寫入:尚未寫入的***一塊Data Block及Meta Block、Index Block、Footer。Meta Block暫未使用,Footer則保存了meta block、index block的位置信息。

  Block

  Data Block、Meta Block、Index Block是業務劃分,分別代表用戶數據塊、元數據塊及用戶數據索引塊。其存儲格式均為Block結構:

  

 

 

  Record代表一條數據,藍色及紅色部分(統一稱作”重啟點”)為附加信息,而這些是做什么的呢?兩點:性能優化、節省空間。

  我們先來看Restart列表的構建邏輯:

 

  1. 1 void BlockBuilder::Add(const Slice& key, const Slice& value) { 
  2.  2         Slice last_key_piece(last_key_); 
  3.  3         ...... 
  4.  4         size_t shared = 0; 
  5.  5         if (counter_ < options_->block_restart_interval) { 
  6.  6             // See how much sharing to do with previous string 
  7.  7             const size_t min_length = std::min(last_key_piece.size(), key.size()); 
  8.  8             while ((shared < min_length) && (last_key_piece[shared] == key[shared])) { 
  9.  9                 shared++; 
  10. 10             } 
  11. 11         } 
  12. 12         else {    //restart時保存完整的key值 
  13. 13             // Restart compression 
  14. 14             restarts_.push_back(buffer_.size()); 
  15. 15             counter_ = 0; 
  16. 16         } 
  17. 17         const size_t non_shared = key.size() - shared; 
  18. 18 
  19. 19         //Record信息 
  20. 20         // shared size | no shared size | value size | no shared key data | value data 
  21. 21         // Add "<shared><non_shared><value_size>" to buffer_ 
  22. 22         PutVarint32(&buffer_, shared); 
  23. 23         PutVarint32(&buffer_, non_shared); 
  24. 24         PutVarint32(&buffer_, value.size()); 
  25. 25         // Add string delta to buffer_ followed by value 
  26. 26         buffer_.append(key.data() + shared, non_shared); 
  27. 27         buffer_.append(value.data(), value.size()); 
  28. 28 
  29. 29         // Update state 
  30. 30         last_key_.resize(shared); 
  31. 31         last_key_.append(key.data() + shared, non_shared); 
  32. 32         assert(Slice(last_key_) == key); 
  33. 33         counter_++; 
  34. 34     } 

 

  每隔一定間隔(block_restart_interval)Record就會創建一個新的重啟點,重啟點內容為當前block的大小,即重啟點在block內的偏移。

  每當添加一個新的重啟點時,重啟點指向位置的Record中一定保存了完整的key值(shared size = 0),隨后的Record中保存的key值僅為和上一個Record的差異值。因為Key在Block中是有序排列的,所以相鄰key值重疊區域節省的空間還是非常可觀的。

  基于上述實現,問題來了:當需要定位一條記錄時,因為record中key的信息是不完整的,僅包含了和上一條的差異項,但上一條記錄本身也只包含了和再上一條的差異項,那么定位一條記錄時如何做key比較?如果需要一直向上查找完成key值拼接,性能上會不會有損傷?

  分析這個問題就要了解重啟點的定位:Block的一級索引,SSTable的二級索引(Index Block是SSTable的一級索引)。本文將每個重啟點記錄位置所屬的Record列表稱為一個Restart Block

  假設每條record記錄的都是完整的key值時,從SSTable中查找一條記錄的工作流如下:

  根據Key值從Index Block中找到所屬的Data Block

  根據Key值從“重啟點”列表中找到所屬的Restart Block,從Restart Block的起始位置進行key值比較,找到正確的記錄。

  在上述流程中,我們必定會先找到一個Restart Point,隨后進行key值比較,而Restart Point記錄本身包含了完整的key值信息,后續key值均可基于此key得到。

  Restart列表本身做為索引,提升了查找性能,而key值存儲的小技巧又降低了空間使用率,在不損傷性能的情況小降低空間利用率,這是一個很好的例子。

  即使這樣,作者覺得還不夠,空間利用率還可以進一步優化,并且不損傷任何讀取數據的性能。

  做法和Restart列表的做法類似,是在Index Block中,通過調用FindShortestSeparator / FindShortSuccessor方法實現。

 

  1. 1         // If *start < limit, changes *start to a short string in [start,limit). 
  2. 2         // Simple comparator implementations may return with *start unchanged, 
  3. 3         // i.e., an implementation of this method that does nothing is correct. 
  4. 4         virtual void FindShortestSeparator(std::string* start, const Slice& limit) const = 0; 
  5. 6         // Changes *key to a short string >= *key
  6. 7         // Simple comparator implementations may return with *key unchanged, 
  7. 8         // i.e., an implementation of this method that does nothing is correct. 
  8. 9         virtual void FindShortSuccessor(std::string* key) const = 0; 

 

  FindShortestSeparator找到start、limit之間最短的key值,如“helloworld”和”hellozoomer”之間最短的key值可以是”hellox”。FindShortSuccessor則更極端,用于找到比key值大的最小key,如傳入“helloworld”,返回的key值可能是“i”而已。

責任編輯:honglu 來源: 音符、時間、走走停停
相關推薦

2022-03-31 16:26:49

鴻蒙源碼分析進程管理

2021-07-10 10:02:30

ZooKeeperCurator并發

2012-03-15 17:18:33

JavaHashMap

2012-02-15 10:37:38

JavaJava Socket

2011-06-24 16:26:20

SEO

2019-07-30 12:36:10

云計算微軟亞馬遜

2021-02-04 07:22:07

NPOI操作Excel

2017-06-01 22:59:45

Akka層次結構Actors

2021-02-22 14:04:47

Vue框架項目

2019-09-28 23:17:41

zabbix運維監控

2013-12-11 10:40:31

虛擬化實戰Cluster

2011-06-14 10:35:15

性能優化

2022-03-22 11:33:13

AT模塊Harmony鴻蒙

2013-05-28 09:33:47

虛擬化虛擬化存儲

2012-05-03 11:35:56

ApacheCXFJava

2011-04-12 14:43:08

XML

2013-06-08 11:10:36

虛擬化虛擬化存儲

2022-12-20 16:10:31

2021-10-29 09:44:50

C++指針變量

2018-03-28 15:21:52

虛擬化類型
點贊
收藏

51CTO技術棧公眾號

成人蜜桃视频| 久久久久久国产精品久久| 一道本在线免费视频| 中文字幕日本在线| 成人免费视频caoporn| 55夜色66夜色国产精品视频| 超碰人人人人人人人| 亚洲高清在线一区| 在线免费观看一区| 大胆欧美熟妇xx| 国产视频福利在线| 国产成人在线视频播放| 日韩av手机在线观看| 成人免费黄色小视频| 日本一道高清一区二区三区| 欧美片网站yy| 777米奇影视第四色| 黄色一级大片在线免费看产| 97超碰欧美中文字幕| 国产在线久久久| 中文字幕一区二区人妻电影| 欧美午夜久久| xxxxx91麻豆| 国产全是老熟女太爽了| 1204国产成人精品视频| 欧美网站一区二区| 欧美激情国产精品日韩| 污片在线免费观看| 中文字幕一区二区三| 欧美亚洲一级二级| 人人妻人人澡人人爽人人欧美一区| 男人的j进女人的j一区| 日本a级片电影一区二区| 久久成人国产精品入口| 99久久亚洲精品| 国产一区二区激情| 久久精品国产亚洲AV熟女| 成人三级毛片| 91精品国产一区二区三区| 国产 porn| 欧美xxxxxx| 日韩欧美在线视频免费观看| 男女激情无遮挡| 狂野欧美激情性xxxx欧美| 综合久久久久综合| 正在播放一区二区三区| 三区在线观看| 91免费在线看| 美国av一区二区三区| 国产一区二区自拍视频| 久久精品国产亚洲高清剧情介绍 | 亚洲精美色品网站| 91人妻一区二区| 荡女精品导航| 欧美mv日韩mv国产网站| 五月天丁香社区| 97久久综合精品久久久综合| 精品国产3级a| 99久久人妻无码中文字幕系列| 久久午夜影院| 日韩精品欧美国产精品忘忧草| xxxx黄色片| 农村少妇一区二区三区四区五区| 精品成a人在线观看| 91在线|亚洲| 欧美日韩国产免费一区二区三区 | 亚洲高清不卡av| 四虎精品一区二区| 日韩mv欧美mv国产网站| 亚洲精品自拍第一页| 女性生殖扒开酷刑vk| 爱高潮www亚洲精品| 亚洲国产欧美在线成人app| 国产999免费视频| 国产欧美一区二区三区米奇| 亚洲精品成人免费| 久久成人激情视频| 色综合天天爱| 欧美激情精品久久久久久变态 | 精品福利电影| 国产成人av在线播放| 怡红院男人天堂| 国产一区二区不卡老阿姨| 国产精品一区二区三区不卡| 涩爱av在线播放一区二区| 欧美激情中文字幕一区二区| 先锋影音网一区| 在线观看小视频| 国产精品高清乱码在线观看| 免费高清不卡av| 91在线视频精品| 污视频在线免费观看| 中文在线资源观看网站视频免费不卡 | 日韩av资源在线| 国产69精品久久久久9999人| 日韩一级大片在线| 在线免费看黄视频| 91精品综合久久久久久久久久久 | 亚洲午夜久久久影院| 国产午夜精品理论片在线| 欧美特黄一级| 国产精品久久久久久久久| 性一交一乱一透一a级| 久久久亚洲午夜电影| 在线看成人av电影| 中文字幕高清在线播放| 欧美在线视频全部完| 2018国产精品| 日韩欧美视频| 欧美一区二区三区图| 国产精品伦理一区| 久久亚洲二区三区| 欧美一级欧美一级| 一级欧美视频| 国产亚洲欧美一区| 免费三级在线观看| 奇米影视一区二区三区小说| 久久久久国色av免费看影院| 久久视频精品在线| 天天干天天干天天| 成人黄色综合网站| 精品一区二区成人免费视频| 日韩美女在线看免费观看| 亚洲成人精品久久久| frxxee中国xxx麻豆hd| 久久先锋影音| 精品一区国产| av今日在线| 日韩欧美自拍偷拍| 人妻互换一区二区激情偷拍| 久久精品1区| 国产日韩一区二区| 欧美人与性动交α欧美精品图片| 欧美剧情电影在线观看完整版免费励志电影 | 久久天天躁狠狠躁老女人| 国产成人精品777777| 成人av电影在线| 日韩亚洲欧美视频| 国产精品色婷婷在线观看| 最近2019中文字幕mv免费看| 夜夜爽妓女8888视频免费观看| 成人影院在线| 日韩激情综合| 欧洲人成人精品| 风间由美一二三区av片| 亚洲国产高清视频| 91在线免费视频| av片在线观看免费| 6080亚洲精品一区二区| 国内精品卡一卡二卡三| 亚洲国产美女| 久久综合狠狠综合久久综青草| 青春草在线视频| 欧美xxxxxxxx| 日本a级片视频| 国产成人三级在线观看| 免费看黄色a级片| silk一区二区三区精品视频| 色综合色综合久久综合频道88| 亚洲AV无码国产精品午夜字幕 | 欧美成人aaa| 日韩在线视频免费观看| 国产精品久久久久久久久毛片| 1024视频在线| 成人亚洲一区二区一| 欧美亚洲黄色片| 天天躁日日躁狠狠躁欧美巨大小说 | 影音先锋在线播放| 亚洲国产另类 国产精品国产免费| 日本一区二区三区免费视频| 91亚洲永久精品| 一区二区在线播放视频| 欧美韩日一区| 99一区二区三区| 中文字幕在线直播| 日韩视频在线一区| 亚洲国产精品视频在线| 婷婷成人激情在线网| 亚洲精品一区二区三区影院忠贞| 久久伊人亚洲| 亚洲精品偷拍视频| www国产精品| 国产成人一区二| 超碰免费公开在线| 亚洲成色777777在线观看影院| 日韩在线视频不卡| 亚洲精品欧美激情| 成人免费无码大片a毛片| 蜜臀av一区二区在线观看| 日本女人高潮视频| 亚洲色图丝袜| 亚洲r级在线观看| 中文字幕资源网在线观看免费 | 日本免费一二三区| 欧美高清在线一区二区| 人妻 丝袜美腿 中文字幕| 亚洲专区欧美专区| 裸体裸乳免费看| 一区二区精彩视频| 国产精品白嫩初高中害羞小美女| 91高清在线观看视频| 亚洲欧美一区二区激情| www日本视频| 91黄色免费看| 久久久久久福利| 国产精品久久久一本精品| 亚洲色偷偷色噜噜狠狠99网| 免费在线成人网| 少妇久久久久久被弄到高潮| 精品国产乱码久久久久久果冻传媒| 99re在线播放| 欧美男女视频| 日本成熟性欧美| 1stkiss在线漫画| 在线日韩日本国产亚洲| 五月婷婷六月丁香| 欧美一级xxx| 亚洲怡红院av| 亚洲一区二区三区四区在线观看 | 日韩欧美视频第二区| 91精品尤物| 国产精品99久久久久久久久| 国产777精品精品热热热一区二区| 久久综合88中文色鬼| 啊v在线视频| 亚洲欧美精品一区二区| 欧美一级性视频| 日韩欧美一级在线播放| 国产精品特级毛片一区二区三区| 在线免费观看视频一区| 日日骚av一区二区| 黄色精品一区二区| 日本亚洲色大成网站www久久| 一区二区在线观看av| 国产探花在线免费观看| 中文字幕一区二区三区乱码在线| 日韩一级av毛片| 久久综合久久综合久久综合| 亚洲精品在线视频免费观看| 成人av资源在线| 女人扒开双腿让男人捅| 国产一本一道久久香蕉| 波多野结衣网页| 国产成人综合自拍| 永久看看免费大片| 国产成人免费视| 国产a√精品区二区三区四区| 国产乱码精品1区2区3区| 日本亚洲一区二区三区| 国产精品一区二区黑丝| 中文字幕无码毛片免费看| 国产精品12区| 亚洲午夜久久久久久久久| 成人晚上爱看视频| 在线视频 日韩| 91玉足脚交白嫩脚丫在线播放| 国产肉体xxxx裸体784大胆| 91在线国内视频| 亚洲av无码国产精品久久| 久久精品夜色噜噜亚洲a∨ | 一区二区三区成人| 久久中文字幕无码| 五月综合激情网| 国产精品久久久久久人| 欧美亚洲综合另类| 国产精品热久久| 精品国产网站在线观看| 国产精品国产高清国产| 亚洲人成自拍网站| 免费观看在线午夜影视| 精品少妇v888av| 91丝袜在线| 国产精品极品尤物在线观看| 国产成人免费视频网站视频社区 | 日本伊人精品一区二区三区介绍| 91精品韩国| 成人欧美在线观看| 美女视频亚洲色图| 色一情一乱一伦一区二区三区丨| 91综合在线| 女人帮男人橹视频播放| 日韩精品免费视频人成| 被黑人猛躁10次高潮视频| 99久久99久久精品国产片果冻| 无码人妻aⅴ一区二区三区69岛| 亚洲美女在线国产| 久久久久久少妇| 在线不卡的av| 视频一区二区三区在线看免费看| 影音先锋日韩有码| 日本性爱视频在线观看| 国产成人精品视频| 日韩精品视频中文字幕| 欧美日韩国产综合在线| 欧美极品一区二区三区| 久久无码高潮喷水| 国产精品一区二区男女羞羞无遮挡| 日批在线观看视频| 最新热久久免费视频| 91九色丨porny丨肉丝| 91精品国产综合久久久久久| 天堂中文在线8| 九九热在线精品视频| 免费成人美女女| 肥熟一91porny丨九色丨| 成人情趣视频| 少妇高潮喷水久久久久久久久久| 精品一区二区日韩| 中文字幕av网址| 亚洲午夜国产一区99re久久| 一级做a爱片久久毛片| 亚洲免费av片| 超碰在线中文字幕| 成人免费视频97| 日韩精品欧美| 免费观看精品视频| 成人毛片在线观看| 天堂网avav| 欧美欧美欧美欧美首页| 日本高清中文字幕二区在线| 欧美极品欧美精品欧美视频| 四虎成人精品一区二区免费网站| 欧美日韩国产精品一卡| 国产欧美日韩一级| 激情综合激情五月| 亚洲精品乱码久久久久久| 中文字幕二区三区| 亚洲系列中文字幕| 成人美女视频| 欧美日韩一区二| 亚洲一区欧美二区| 精品无码国产一区二区三区51安| 一级女性全黄久久生活片免费| 91精品国产乱码久久久| 少妇激情综合网| 日本电影久久久| 一本色道久久综合亚洲二区三区| 日韩精品亚洲一区二区三区免费| 亚洲欧美色图视频| 日韩欧美精品在线观看| 深夜视频在线免费| 欧美一级黄色网| 美女av一区| 99re在线视频免费观看| 91在线视频免费91| 天天干天天干天天操| 亚洲欧美成人精品| 老司机成人影院| 日韩精品久久久免费观看| 日日欢夜夜爽一区| 亚洲天堂精品一区| 欧美日韩久久久| 国产在线激情| 99精品国产高清一区二区| 亚洲成人在线| 9.1成人看片| 日本丰满少妇一区二区三区| 高清毛片在线看| 成人xxxxx| 欧美va天堂在线| 中文字幕一区二区三区乱码不卡| 欧美日韩国产一区二区三区| 色鬼7777久久| 国产美女高潮久久白浆| 中文一区一区三区免费在线观看| 无码国产精品一区二区高潮| 午夜精品一区二区三区三上悠亚| 婷婷色在线观看| 国产成人久久久| 国产精品久久久久蜜臀| 日本美女视频网站| 色欧美乱欧美15图片| 免费黄网站在线播放| 高清视频在线观看一区| 香蕉久久夜色精品| 国产又黄又粗又猛又爽的| 精品日本一线二线三线不卡| 天堂av在线网| 亚洲最大免费| 不卡高清视频专区| 影音先锋黄色网址| 国内精品久久久| 欧美亚洲国产激情| 亚洲成a人无码| 欧美性做爰猛烈叫床潮| 最新日本在线观看| 免费在线一区二区| 国内久久精品视频| 91精品国产乱码久久久张津瑜| 在线成人激情黄色| jizz久久精品永久免费| 亚洲三级视频网站| 一片黄亚洲嫩模| 国产香蕉视频在线看| 99高清视频有精品视频| 日韩国产一区二| 国产成人免费观看视频| 日韩中文字幕网站| 亚洲免费观看高清完整版在线观| 午夜福利123|