record_manager.h 4.9 KB
Newer Older
羽飞's avatar
羽飞 已提交
1 2 3 4 5 6 7 8 9 10 11
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */

//
12
// Created by Meiyi & Longda on 2021/4/13.
羽飞's avatar
羽飞 已提交
13
//
羽飞's avatar
羽飞 已提交
14
#pragma once
羽飞's avatar
羽飞 已提交
15

L
Longda 已提交
16
#include <sstream>
羽飞's avatar
羽飞 已提交
17
#include <limits>
羽飞's avatar
羽飞 已提交
18
#include "storage/default/disk_buffer_pool.h"
羽飞's avatar
羽飞 已提交
19
#include "storage/record/record.h"
羽飞's avatar
羽飞 已提交
20
#include "common/lang/bitmap.h"
羽飞's avatar
羽飞 已提交
21 22 23

class ConditionFilter;

L
Longda 已提交
24
struct PageHeader {
羽飞's avatar
羽飞 已提交
25 26 27 28 29
  int32_t record_num;           // 当前页面记录的个数
  int32_t record_capacity;      // 最大记录个数
  int32_t record_real_size;     // 每条记录的实际大小
  int32_t record_size;          // 每条记录占用实际空间大小(可能对齐)
  int32_t first_record_offset;  // 第一条记录的偏移量
L
Longda 已提交
30 31
};

羽飞's avatar
羽飞 已提交
32 33 34 35 36 37 38 39 40 41 42 43
class RecordPageHandler;
class RecordPageIterator
{
public:
  RecordPageIterator();
  ~RecordPageIterator();

  void init(RecordPageHandler &record_page_handler);

  bool has_next();
  RC   next(Record &record);

羽飞's avatar
羽飞 已提交
44 45 46
  bool is_valid() const {
    return record_page_handler_ != nullptr;
  }
羽飞's avatar
羽飞 已提交
47 48 49 50 51 52 53
private:
  RecordPageHandler *record_page_handler_ = nullptr;
  PageNum page_num_ = BP_INVALID_PAGE_NUM;
  common::Bitmap  bitmap_;
  SlotNum next_slot_num_ = 0;
};

羽飞's avatar
羽飞 已提交
54 55
class RecordPageHandler {
public:
羽飞's avatar
羽飞 已提交
56
  RecordPageHandler() = default;
羽飞's avatar
羽飞 已提交
57
  ~RecordPageHandler();
羽飞's avatar
羽飞 已提交
58
  RC init(DiskBufferPool &buffer_pool, PageNum page_num);
羽飞's avatar
羽飞 已提交
59
  RC recover_init(DiskBufferPool &buffer_pool, PageNum page_num);
羽飞's avatar
羽飞 已提交
60
  RC init_empty_page(DiskBufferPool &buffer_pool, PageNum page_num, int record_size);
L
Longda 已提交
61
  RC cleanup();
羽飞's avatar
羽飞 已提交
62 63

  RC insert_record(const char *data, RID *rid);
羽飞's avatar
羽飞 已提交
64
  RC recover_insert_record(const char *data, RID *rid);
羽飞's avatar
羽飞 已提交
65 66 67
  RC update_record(const Record *rec);

  template <class RecordUpdater>
L
Longda 已提交
68 69
  RC update_record_in_place(const RID *rid, RecordUpdater updater)
  {
羽飞's avatar
羽飞 已提交
70 71 72 73 74 75
    Record record;
    RC rc = get_record(rid, &record);
    if (rc != RC::SUCCESS) {
      return rc;
    }
    rc = updater(record);
羽飞's avatar
羽飞 已提交
76
    frame_->mark_dirty();
羽飞's avatar
羽飞 已提交
77 78 79 80 81 82 83 84 85 86 87
    return rc;
  }

  RC delete_record(const RID *rid);

  RC get_record(const RID *rid, Record *rec);

  PageNum get_page_num() const;

  bool is_full() const;

L
Longda 已提交
88 89 90
protected:
  char *get_record_data(SlotNum slot_num)
  {
羽飞's avatar
羽飞 已提交
91
    return frame_->data() + page_header_->first_record_offset + (page_header_->record_size * slot_num);
L
Longda 已提交
92 93 94
  }

protected:
羽飞's avatar
羽飞 已提交
95 96 97 98
  DiskBufferPool *disk_buffer_pool_ = nullptr;
  Frame *frame_ = nullptr;
  PageHeader *page_header_ = nullptr;
  char *bitmap_ = nullptr;
羽飞's avatar
羽飞 已提交
99 100 101

private:
  friend class RecordPageIterator;
羽飞's avatar
羽飞 已提交
102 103 104 105
};

class RecordFileHandler {
public:
羽飞's avatar
羽飞 已提交
106 107
  RecordFileHandler() = default;
  RC init(DiskBufferPool *buffer_pool);
羽飞's avatar
羽飞 已提交
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
  void close();

  /**
   * 更新指定文件中的记录,rec指向的记录结构中的rid字段为要更新的记录的标识符,
   * pData字段指向新的记录内容
   */
  RC update_record(const Record *rec);

  /**
   * 从指定文件中删除标识符为rid的记录
   */
  RC delete_record(const RID *rid);

  /**
   * 插入一个新的记录到指定文件中,pData为指向新纪录内容的指针,返回该记录的标识符rid
   */
  RC insert_record(const char *data, int record_size, RID *rid);
羽飞's avatar
羽飞 已提交
125
  RC recover_insert_record(const char *data, int record_size, RID *rid);
羽飞's avatar
羽飞 已提交
126 127 128 129 130 131

  /**
   * 获取指定文件中标识符为rid的记录内容到rec指向的记录结构中
   */
  RC get_record(const RID *rid, Record *rec);

L
Longda 已提交
132 133 134
  template <class RecordUpdater>  // 改成普通模式, 不使用模板
  RC update_record_in_place(const RID *rid, RecordUpdater updater)
  {
羽飞's avatar
羽飞 已提交
135 136 137

    RC rc = RC::SUCCESS;
    RecordPageHandler page_handler;
羽飞's avatar
羽飞 已提交
138
    if ((rc != page_handler.init(*disk_buffer_pool_, rid->page_num)) != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
139 140 141 142 143 144
      return rc;
    }

    return page_handler.update_record_in_place(rid, updater);
  }

羽飞's avatar
羽飞 已提交
145 146 147
private:
  RC init_free_pages();
  
羽飞's avatar
羽飞 已提交
148
private:
羽飞's avatar
羽飞 已提交
149
  DiskBufferPool *disk_buffer_pool_ = nullptr;
羽飞's avatar
羽飞 已提交
150
  std::unordered_set<PageNum>  free_pages_; // 没有填充满的页面集合
羽飞's avatar
羽飞 已提交
151 152
};

L
Longda 已提交
153
class RecordFileScanner {
羽飞's avatar
羽飞 已提交
154
public:
羽飞's avatar
羽飞 已提交
155
  RecordFileScanner() = default;
羽飞's avatar
羽飞 已提交
156 157 158 159 160

  /**
   * 打开一个文件扫描。
   * 如果条件不为空,则要对每条记录进行条件比较,只有满足所有条件的记录才被返回
   */
羽飞's avatar
羽飞 已提交
161
  RC open_scan(DiskBufferPool &buffer_pool, ConditionFilter *condition_filter);
羽飞's avatar
羽飞 已提交
162 163 164 165 166 167

  /**
   * 关闭一个文件扫描,释放相应的资源
   */
  RC close_scan();

羽飞's avatar
羽飞 已提交
168 169
  bool has_next();
  RC   next(Record &record);
羽飞's avatar
羽飞 已提交
170

羽飞's avatar
羽飞 已提交
171 172
private:
  RC fetch_next_record();
羽飞's avatar
羽飞 已提交
173
  RC fetch_next_record_in_page();
羽飞's avatar
羽飞 已提交
174
private:
羽飞's avatar
羽飞 已提交
175
  DiskBufferPool *disk_buffer_pool_ = nullptr;
羽飞's avatar
羽飞 已提交
176

羽飞's avatar
羽飞 已提交
177
  BufferPoolIterator bp_iterator_;
羽飞's avatar
羽飞 已提交
178
  ConditionFilter *condition_filter_ = nullptr;
L
Longda 已提交
179
  RecordPageHandler record_page_handler_;
羽飞's avatar
羽飞 已提交
180 181
  RecordPageIterator record_page_iterator_;
  Record next_record_;
羽飞's avatar
羽飞 已提交
182
};