Upgrade to Pro — share decks privately, control downloads, hide ads and more …

B-trees

 B-trees

tom--bo

July 10, 2020
Tweet

More Decks by tom--bo

Other Decks in Programming

Transcript

  1. B tree実装してみた
    LT-slide (2020/07/10)
    @tom__bo

    View Slide

  2. 目次
    ● 目的
    ● B, B+, B* tree 整理
    ● (僕 )実装方針
    ● パフォーマンス比較 方法
    ● 現時点 実験結果
    ● 今後 課題

    View Slide

  3. 目的
    Database Internals 輪読会に合わせて
    ● 気になっていたB木, LSM木 比較をしたい
    ● B木 亜種も実装してみる
    ● 勉強 ためにC++で書いてみる
    ○ MySQLいじろうと思うと必須
    ○ C++まともに書いたことない (学生 頃、授業でC書いたくらいか?)
    ● GitHub repo: https://github.com/tom--bo/trees

    View Slide

  4. B, B+, B*木 整理
    ● B tree
    ○ アルゴリズムイントロダクション第 3版に詳細な実装例
    ● B+ tree
    ○ リーフノードだけにデータを持つ
    ○ リーフノード同士 左右 リンクを持つ
    ○ 提案論文?
    ● B* tree
    ○ 連続する2つ ノードがいっ いになったときに split(3つめを追加して2/3ずつ配分)
    ○ 提案論文: BAYER, R., and MCCREIGHT, E. “Organization and maintenance of large ordered indexes.”, Acta Inf. 1, 1972,
    173-189

    View Slide

  5. (僕 )実装方針
    ● Primary index as an Indirectionを想定
    ● key(Item.key) 固定
    ● key 重複可, NULLなし
    ● まず シングルスレッドで実装
    ● 各木
    ○ B tree : アルゴリズムイントロダクションを参考
    ■ https://github.com/tom--bo/trees/tree/5e4f5554ef239ef9af45d426e67ea1f0e3574899/btree
    ○ B+ tree: B treeを独自で拡張
    ■ https://github.com/tom--bo/trees/tree/5e4f5554ef239ef9af45d426e67ea1f0e3574899/bplustree
    ○ B* tree : B treeを独自で拡張
    ■ https://github.com/tom--bo/trees/tree/5e4f5554ef239ef9af45d426e67ea1f0e3574899/bstartree

    View Slide

  6. B tree 実装
    ● アルゴリズムイントロダクションを参考
    ○ RootからLeafに向けてノードをたどるときにノード 状態によって予め Split, Mergeする
    ○ Merge 連続するノードが最低 key数にならない限り兄弟ノードから keyを移動する

    View Slide

  7. B+ tree 実装
    ● リーフノードにすべて Itemを持つ
    ● 中間ノード Item そ 右 子 sub-tree中 最小Item

    View Slide

  8. B* tree 実装
    ● 基本的に B tree
    ● 連続する2ノードがいっ いになったらsplit

    View Slide

  9. パフォーマンス比較
    方法
    ● ランダムにデータ生成
    ● ここで insert み
    環境
    ● CPU: AMD Ryzen 9 3950X (16core 32threads)
    ● OS: Ubuntu 19.10, Kernel: 5.3.0-61-generic
    ● Clang: 9.0.0-2 (Compile: `clang++ -O2 … ` )
    ● ブログ: Ryzen 3950x でPC組んだ

    View Slide

  10. 結果(Node count)
    ● 1,000,000 Insert keys後 ノード数 平均 (t = 4, 8, 16, …, 512)

    View Slide

  11. 結果(Total time)
    ● 1,000,000 Insert keys にかかった時間 平均 (t = 4, 8, 16, …, 512)

    View Slide

  12. LRU cache
    ● もっと現実的な(?)比較をしたい
    ● LRU cacheで簡易的なbuffer_poolを実装
    ○ std::unordered_map, std::listを使ったシンプルな実装
    ● アクセスしようとするノードがcacheになけれ ペナルティ(sleep 100us)
    ○ dirty page(node) flushなどもあるが、adaptive flushingとか考え始めるときりがない

    View Slide

  13. 結果 (Node count with LRU cache)
    ● 100,000 Insert keys (t = 64, 128 …, 512)
    ● Cache size: 200 (nodes)
    ノード数 実行時間 キャッシュヒット率

    View Slide

  14. 今後やりたいこと
    ● 実験
    ○ B, B+間で range scan比較
    ○ Read / write 比重を変化
    ○ LRUサイズ 変化
    ● 実装
    ○ 他 木: B-link tree, LSM tree, Skip list, (Masstree)
    ○ UPDATE (?)
    ● 各種最適化
    ○ 未定
    ● Thread-safe化
    ○ B-link tree以降で頑張る
    ○ 現在 実装で root->leafへ 探索を再帰で書いていて大幅な修正が必要

    View Slide

  15. 疑問
    ● UPDATE 方法
    ○ 現状 Delete & Insertしか思いついていない ...
    ● Thread-safe化
    ○ B-link tree以降で頑張る
    ○ 現在 実装で root->leafへ 探索を再帰で書いていて大幅な修正が必要
    ● テスト 方法
    ○ 現状ランダムなテストケース作って ”対象 木”と”単純なHashMap” 両方に操作して最後に差分
    がないか比較している
    ○ B木 状態を理解してテストケースを作っていない
    ■ コーナーケースを想定しきれずに早々に諦め

    View Slide