MiniOB 1
MiniOB is one mini database, helping developers to learn how database works.
载入中...
搜索中...
未找到
bplus_tree.h
1/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
2miniob is licensed under Mulan PSL v2.
3You can use this software according to the terms and conditions of the Mulan PSL v2.
4You may obtain a copy of Mulan PSL v2 at:
5 http://license.coscl.org.cn/MulanPSL2
6THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
7EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
8MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
9See the Mulan PSL v2 for more details. */
10
11//
12//
13// Created by Xie Meiyi
14// Rewritten by Longda & Wangyunlai
15//
16//
17
18#pragma once
19
20#include <string.h>
21#include <sstream>
22#include <functional>
23#include <memory>
24
25#include "storage/record/record_manager.h"
26#include "storage/buffer/disk_buffer_pool.h"
27#include "storage/trx/latch_memo.h"
28#include "sql/parser/parse_defs.h"
29#include "common/lang/comparator.h"
30#include "common/log/log.h"
31
42{
43 READ,
44 INSERT,
45 DELETE,
46};
47
53{
54public:
55 void init(AttrType type, int length)
56 {
57 attr_type_ = type;
58 attr_length_ = length;
59 }
60
61 int attr_length() const
62 {
63 return attr_length_;
64 }
65
66 int operator()(const char *v1, const char *v2) const
67 {
68 switch (attr_type_) {
69 case INTS: {
70 return common::compare_int((void *)v1, (void *)v2);
71 } break;
72 case FLOATS: {
73 return common::compare_float((void *)v1, (void *)v2);
74 }
75 case CHARS: {
76 return common::compare_string((void *)v1, attr_length_, (void *)v2, attr_length_);
77 }
78 default: {
79 ASSERT(false, "unknown attr type. %d", attr_type_);
80 return 0;
81 }
82 }
83 }
84
85private:
86 AttrType attr_type_;
87 int attr_length_;
88};
89
96{
97public:
98 void init(AttrType type, int length)
99 {
100 attr_comparator_.init(type, length);
101 }
102
103 const AttrComparator &attr_comparator() const
104 {
105 return attr_comparator_;
106 }
107
108 int operator()(const char *v1, const char *v2) const
109 {
110 int result = attr_comparator_(v1, v2);
111 if (result != 0) {
112 return result;
113 }
114
115 const RID *rid1 = (const RID *)(v1 + attr_comparator_.attr_length());
116 const RID *rid2 = (const RID *)(v2 + attr_comparator_.attr_length());
117 return RID::compare(rid1, rid2);
118 }
119
120private:
121 AttrComparator attr_comparator_;
122};
123
129{
130public:
131 void init(AttrType type, int length)
132 {
133 attr_type_ = type;
134 attr_length_ = length;
135 }
136
137 int attr_length() const
138 {
139 return attr_length_;
140 }
141
142 std::string operator()(const char *v) const
143 {
144 switch (attr_type_) {
145 case INTS: {
146 return std::to_string(*(int *)v);
147 } break;
148 case FLOATS: {
149 return std::to_string(*(float *)v);
150 }
151 case CHARS: {
152 std::string str;
153 for (int i = 0; i < attr_length_; i++) {
154 if (v[i] == 0) {
155 break;
156 }
157 str.push_back(v[i]);
158 }
159 return str;
160 }
161 default: {
162 ASSERT(false, "unknown attr type. %d", attr_type_);
163 }
164 }
165 return std::string();
166 }
167
168private:
169 AttrType attr_type_;
170 int attr_length_;
171};
172
178{
179public:
180 void init(AttrType type, int length)
181 {
182 attr_printer_.init(type, length);
183 }
184
185 const AttrPrinter &attr_printer() const
186 {
187 return attr_printer_;
188 }
189
190 std::string operator()(const char *v) const
191 {
192 std::stringstream ss;
193 ss << "{key:" << attr_printer_(v) << ",";
194
195 const RID *rid = (const RID *)(v + attr_printer_.attr_length());
196 ss << "rid:{" << rid->to_string() << "}}";
197 return ss.str();
198 }
199
200private:
201 AttrPrinter attr_printer_;
202};
203
211{
213 {
214 memset(this, 0, sizeof(IndexFileHeader));
215 root_page = BP_INVALID_PAGE_NUM;
216 }
217 PageNum root_page;
220 int32_t attr_length;
221 int32_t key_length;
222 AttrType attr_type;
223
224 const std::string to_string()
225 {
226 std::stringstream ss;
227
228 ss << "attr_length:" << attr_length << ","
229 << "key_length:" << key_length << ","
230 << "attr_type:" << attr_type << ","
231 << "root_page:" << root_page << ","
232 << "internal_max_size:" << internal_max_size << ","
233 << "leaf_max_size:" << leaf_max_size << ";";
234
235 return ss.str();
236 }
237};
238
248{
249 static constexpr int HEADER_SIZE = 12;
250
251 bool is_leaf;
252 int key_num;
253 PageNum parent;
254};
255
269struct LeafIndexNode : public IndexNode
270{
271 static constexpr int HEADER_SIZE = IndexNode::HEADER_SIZE + 4;
272
273 PageNum next_brother;
277 char array[0];
278};
279
292{
293 static constexpr int HEADER_SIZE = IndexNode::HEADER_SIZE;
294
298 char array[0];
299};
300
308{
309public:
310 IndexNodeHandler(const IndexFileHeader &header, Frame *frame);
311 virtual ~IndexNodeHandler() = default;
312
313 void init_empty(bool leaf);
314
315 bool is_leaf() const;
316 int key_size() const;
317 int value_size() const;
318 int item_size() const;
319
320 void increase_size(int n);
321 int size() const;
322 int max_size() const;
323 int min_size() const;
324 void set_parent_page_num(PageNum page_num);
325 PageNum parent_page_num() const;
326 PageNum page_num() const;
327
328 bool is_safe(BplusTreeOperationType op, bool is_root_node);
329
330 bool validate() const;
331
332 friend std::string to_string(const IndexNodeHandler &handler);
333
334protected:
335 const IndexFileHeader &header_;
336 PageNum page_num_;
337 IndexNode *node_;
338};
339
345{
346public:
347 LeafIndexNodeHandler(const IndexFileHeader &header, Frame *frame);
348 virtual ~LeafIndexNodeHandler() = default;
349
350 void init_empty();
351 void set_next_page(PageNum page_num);
352 PageNum next_page() const;
353
354 char *key_at(int index);
355 char *value_at(int index);
356
361 int lookup(const KeyComparator &comparator, const char *key, bool *found = nullptr) const;
362
363 void insert(int index, const char *key, const char *value);
364 void remove(int index);
365 int remove(const char *key, const KeyComparator &comparator);
366 RC move_half_to(LeafIndexNodeHandler &other, DiskBufferPool *bp);
367 RC move_first_to_end(LeafIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool);
368 RC move_last_to_front(LeafIndexNodeHandler &other, DiskBufferPool *bp);
373
374 bool validate(const KeyComparator &comparator, DiskBufferPool *bp) const;
375
376 friend std::string to_string(const LeafIndexNodeHandler &handler, const KeyPrinter &printer);
377
378private:
379 char *__item_at(int index) const;
380 char *__key_at(int index) const;
381 char *__value_at(int index) const;
382
383 void append(const char *item);
384 void preappend(const char *item);
385
386private:
387 LeafIndexNode *leaf_node_;
388};
389
395{
396public:
397 InternalIndexNodeHandler(const IndexFileHeader &header, Frame *frame);
398 virtual ~InternalIndexNodeHandler() = default;
399
400 void init_empty();
401 void create_new_root(PageNum first_page_num, const char *key, PageNum page_num);
402
403 void insert(const char *key, PageNum page_num, const KeyComparator &comparator);
404 RC move_half_to(LeafIndexNodeHandler &other, DiskBufferPool *bp);
405 char *key_at(int index);
406 PageNum value_at(int index);
407
411 int value_index(PageNum page_num);
412 void set_key_at(int index, const char *key);
413 void remove(int index);
414
423 int lookup(const KeyComparator &comparator,
424 const char *key,
425 bool *found = nullptr,
426 int *insert_position = nullptr) const;
427
428 RC move_to(InternalIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool);
429 RC move_first_to_end(InternalIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool);
430 RC move_last_to_front(InternalIndexNodeHandler &other, DiskBufferPool *bp);
431 RC move_half_to(InternalIndexNodeHandler &other, DiskBufferPool *bp);
432
433 bool validate(const KeyComparator &comparator, DiskBufferPool *bp) const;
434
435 friend std::string to_string(const InternalIndexNodeHandler &handler, const KeyPrinter &printer);
436
437private:
438 RC copy_from(const char *items, int num, DiskBufferPool *disk_buffer_pool);
439 RC append(const char *item, DiskBufferPool *bp);
440 RC preappend(const char *item, DiskBufferPool *bp);
441
442private:
443 char *__item_at(int index) const;
444 char *__key_at(int index) const;
445 char *__value_at(int index) const;
446
447 int value_size() const;
448 int item_size() const;
449
450private:
451 InternalIndexNode *internal_node_ = nullptr;
452};
453
459{
460public:
465 RC create(const char *file_name,
466 AttrType attr_type,
467 int attr_length,
468 int internal_max_size = -1,
469 int leaf_max_size = -1);
470
476 RC open(const char *file_name);
477
481 RC close();
482
489 RC insert_entry(const char *user_key, const RID *rid);
490
496 RC delete_entry(const char *user_key, const RID *rid);
497
498 bool is_empty() const;
499
505 RC get_entry(const char *user_key, int key_len, std::list<RID> &rids);
506
507 RC sync();
508
514 bool validate_tree();
515
516public:
520 RC print_tree();
521 RC print_leafs();
522
523private:
527 RC print_leaf(Frame *frame);
528 RC print_internal_node_recursive(Frame *frame);
529
530 bool validate_leaf_link(LatchMemo &latch_memo);
531 bool validate_node_recursive(LatchMemo &latch_memo, Frame *frame);
532
533protected:
534 RC find_leaf(LatchMemo &latch_memo, BplusTreeOperationType op, const char *key, Frame *&frame);
535 RC left_most_page(LatchMemo &latch_memo, Frame *&frame);
536 RC find_leaf_internal(LatchMemo &latch_memo, BplusTreeOperationType op,
537 const std::function<PageNum(InternalIndexNodeHandler &)> &child_page_getter,
538 Frame *&frame);
539 RC crabing_protocal_fetch_page(LatchMemo &latch_memo, BplusTreeOperationType op, PageNum page_num, bool is_root_page,
540 Frame *&frame);
541
542 RC insert_into_parent(LatchMemo &latch_memo, PageNum parent_page, Frame *left_frame, const char *pkey,
543 Frame &right_frame);
544
545 RC delete_entry_internal(LatchMemo &latch_memo, Frame *leaf_frame, const char *key);
546
547 template <typename IndexNodeHandlerType>
548 RC split(LatchMemo &latch_memo, Frame *frame, Frame *&new_frame);
549 template <typename IndexNodeHandlerType>
550 RC coalesce_or_redistribute(LatchMemo &latch_memo, Frame *frame);
551 template <typename IndexNodeHandlerType>
552 RC coalesce(LatchMemo &latch_memo, Frame *neighbor_frame, Frame *frame, Frame *parent_frame, int index);
553 template <typename IndexNodeHandlerType>
554 RC redistribute(Frame *neighbor_frame, Frame *frame, Frame *parent_frame, int index);
555
556 RC insert_entry_into_parent(LatchMemo &latch_memo, Frame *frame, Frame *new_frame, const char *key);
557 RC insert_entry_into_leaf_node(LatchMemo &latch_memo, Frame *frame, const char *pkey, const RID *rid);
558 RC create_new_tree(const char *key, const RID *rid);
559
560 void update_root_page_num(PageNum root_page_num);
561 void update_root_page_num_locked(PageNum root_page_num);
562
563 RC adjust_root(LatchMemo &latch_memo, Frame *root_frame);
564
565private:
566 common::MemPoolItem::unique_ptr make_key(const char *user_key, const RID &rid);
567 void free_key(char *key);
568
569protected:
570 DiskBufferPool *disk_buffer_pool_ = nullptr;
571 bool header_dirty_ = false; //
572 IndexFileHeader file_header_;
573
574 // 在调整根节点时,需要加上这个锁。
575 // 这个锁可以使用递归读写锁,但是这里偷懒先不改
576 common::SharedMutex root_lock_;
577
578 KeyComparator key_comparator_;
579 KeyPrinter key_printer_;
580
581 std::unique_ptr<common::MemPoolItem> mem_pool_item_;
582
583private:
584 friend class BplusTreeScanner;
585 friend class BplusTreeTester;
586};
587
593{
594public:
595 BplusTreeScanner(BplusTreeHandler &tree_handler);
597
607 RC open(const char *left_user_key, int left_len, bool left_inclusive,
608 const char *right_user_key, int right_len, bool right_inclusive);
609
610 RC next_entry(RID &rid);
611
612 RC close();
613
614private:
618 RC fix_user_key(const char *user_key, int key_len, bool want_greater, char **fixed_key, bool *should_inclusive);
619
620 void fetch_item(RID &rid);
621 bool touch_end();
622
623private:
624 bool inited_ = false;
625 BplusTreeHandler &tree_handler_;
626
627 LatchMemo latch_memo_;
628
632
633 common::MemPoolItem::unique_ptr right_key_;
634 int iter_index_ = -1;
635 bool first_emitted_ = false;
636};
属性比较(BplusTree)
Definition: bplus_tree.h:53
属性打印,调试使用(BplusTree)
Definition: bplus_tree.h:129
B+树的实现
Definition: bplus_tree.h:459
RC close()
Definition: bplus_tree.cpp:866
RC delete_entry(const char *user_key, const RID *rid)
Definition: bplus_tree.cpp:1621
RC insert_entry_into_parent(LatchMemo &latch_memo, Frame *frame, Frame *new_frame, const char *key)
Definition: bplus_tree.cpp:1193
RC create(const char *file_name, AttrType attr_type, int attr_length, int internal_max_size=-1, int leaf_max_size=-1)
Definition: bplus_tree.cpp:748
bool validate_tree()
Definition: bplus_tree.cpp:1051
RC print_leaf(Frame *frame)
Definition: bplus_tree.cpp:876
RC insert_entry(const char *user_key, const RID *rid)
Definition: bplus_tree.cpp:1363
RC get_entry(const char *user_key, int key_len, std::list< RID > &rids)
Definition: bplus_tree.cpp:1407
RC open(const char *file_name)
Definition: bplus_tree.cpp:822
RC print_tree()
Definition: bplus_tree.cpp:919
RC split(LatchMemo &latch_memo, Frame *frame, Frame *&new_frame)
Definition: bplus_tree.cpp:1293
B+树的扫描器
Definition: bplus_tree.h:593
Frame * current_frame_
使用左右叶子节点和位置来表示扫描的起始位置和终止位置 起始位置和终止位置都是有效的数据
Definition: bplus_tree.h:631
RC fix_user_key(const char *user_key, int key_len, bool want_greater, char **fixed_key, bool *should_inclusive)
Definition: bplus_tree.cpp:1872
RC open(const char *left_user_key, int left_len, bool left_inclusive, const char *right_user_key, int right_len, bool right_inclusive)
扫描指定范围的数据
Definition: bplus_tree.cpp:1663
RC next_entry(RID &rid)
Definition: bplus_tree.cpp:1813
BufferPool的实现
Definition: disk_buffer_pool.h:193
页帧
Definition: frame.h:62
IndexNode 仅作为数据在内存或磁盘中的表示IndexNodeHandler 负责对IndexNode做各种操作。 作为一个类来说,虚函数会影响“结构体”真实的内存布局,所以将数据存储与操作分开
Definition: bplus_tree.h:308
bool is_safe(BplusTreeOperationType op, bool is_root_node)
Definition: bplus_tree.cpp:113
内部节点的操作
Definition: bplus_tree.h:395
int lookup(const KeyComparator &comparator, const char *key, bool *found=nullptr, int *insert_position=nullptr) const
Definition: bplus_tree.cpp:453
int value_index(PageNum page_num)
Definition: bplus_tree.cpp:499
void insert(const char *key, PageNum page_num, const KeyComparator &comparator)
Definition: bplus_tree.cpp:422
RC copy_from(const char *items, int num, DiskBufferPool *disk_buffer_pool)
Definition: bplus_tree.cpp:559
键值比较(BplusTree)
Definition: bplus_tree.h:96
键值打印,调试使用(BplusTree)
Definition: bplus_tree.h:178
Definition: latch_memo.h:50
叶子节点的操作
Definition: bplus_tree.h:345
int lookup(const KeyComparator &comparator, const char *key, bool *found=nullptr) const
Definition: bplus_tree.cpp:202
RC move_to(LeafIndexNodeHandler &other, DiskBufferPool *bp)
Definition: bplus_tree.cpp:271
BplusTreeOperationType
B+树的操作类型
Definition: bplus_tree.h:42
the meta information of bplus tree
Definition: bplus_tree.h:211
PageNum root_page
根节点在磁盘中的页号
Definition: bplus_tree.h:217
int32_t leaf_max_size
叶子节点最大的键值对数
Definition: bplus_tree.h:219
AttrType attr_type
键值的类型
Definition: bplus_tree.h:222
int32_t internal_max_size
内部节点最大的键值对数
Definition: bplus_tree.h:218
int32_t attr_length
键值的长度
Definition: bplus_tree.h:220
int32_t key_length
attr length + sizeof(RID)
Definition: bplus_tree.h:221
the common part of page describtion of bplus tree
Definition: bplus_tree.h:248
internal page of bplus tree
Definition: bplus_tree.h:292
char array[0]
Definition: bplus_tree.h:298
leaf page of bplus tree
Definition: bplus_tree.h:270
char array[0]
Definition: bplus_tree.h:277
标识一个记录的位置 一个记录是放在某个文件的某个页面的某个槽位。这里不记录文件信息,记录页面和槽位信息
Definition: record.h:35