MiniOB 1
MiniOB is one mini database, helping developers to learn how database works.
载入中...
搜索中...
未找到
record.h
1/* Copyright (c) 2021 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// Created by Wangyunlai on 2022/5/4.
13//
14
15#pragma once
16
17#include <stddef.h>
18
19#include "common/log/log.h"
20#include "common/sys/rc.h"
21#include "common/types.h"
22#include "common/lang/vector.h"
23#include "common/lang/sstream.h"
24#include "common/lang/limits.h"
25#include "storage/field/field_meta.h"
26#include "storage/index/index_meta.h"
27
28class Field;
29
34struct RID
35{
36 PageNum page_num; // record's page number
37 SlotNum slot_num; // record's slot number
38
39 RID() = default;
40 RID(const PageNum _page_num, const SlotNum _slot_num) : page_num(_page_num), slot_num(_slot_num) {}
41
42 const string to_string() const
43 {
44 stringstream ss;
45 ss << "PageNum:" << page_num << ", SlotNum:" << slot_num;
46 return ss.str();
47 }
48
49 bool operator==(const RID &other) const { return page_num == other.page_num && slot_num == other.slot_num; }
50
51 bool operator!=(const RID &other) const { return !(*this == other); }
52
53 static int compare(const RID *rid1, const RID *rid2)
54 {
55 int page_diff = rid1->page_num - rid2->page_num;
56 if (page_diff != 0) {
57 return page_diff;
58 } else {
59 return rid1->slot_num - rid2->slot_num;
60 }
61 }
62
68 static RID *min()
69 {
70 static RID rid{0, 0};
71 return &rid;
72 }
73
78 static RID *max()
79 {
80 static RID rid{numeric_limits<PageNum>::max(), numeric_limits<SlotNum>::max()};
81 return &rid;
82 }
83};
84
85struct RIDHash
86{
87 size_t operator()(const RID &rid) const noexcept
88 {
89 return hash<PageNum>()(rid.page_num) ^ hash<SlotNum>()(rid.slot_num);
90 }
91};
92
101{
102public:
103 Record() = default;
104 ~Record()
105 {
106 if (owner_ && data_ != nullptr) {
107 free(data_);
108 data_ = nullptr;
109 }
110 }
111
112 Record(const Record &other)
113 {
114 rid_ = other.rid_;
115 data_ = other.data_;
116 len_ = other.len_;
117 owner_ = other.owner_;
118
119 if (other.owner_) {
120 char *tmp = (char *)malloc(other.len_);
121 ASSERT(nullptr != tmp, "failed to allocate memory. size=%d", other.len_);
122 memcpy(tmp, other.data_, other.len_);
123 data_ = tmp;
124 }
125 }
126
127 Record &operator=(const Record &other)
128 {
129 if (this == &other) {
130 return *this;
131 }
132
133 if (!owner_ || len_ != other.len_) {
134 this->~Record();
135 new (this) Record(other);
136 return *this;
137 }
138 this->rid_ = other.rid_;
139 memcpy(data_, other.data_, other.len_);
140 return *this;
141 }
142
143 Record(Record &&other)
144 {
145 rid_ = other.rid_;
146
147 if (!other.owner_) {
148 data_ = other.data_;
149 len_ = other.len_;
150 other.data_ = nullptr;
151 other.len_ = 0;
152 this->owner_ = false;
153 } else {
154 data_ = other.data_;
155 len_ = other.len_;
156 other.data_ = nullptr;
157 other.len_ = 0;
158 this->owner_ = true;
159 }
160 }
161
162 Record &operator=(Record &&other)
163 {
164 if (this == &other) {
165 return *this;
166 }
167
168 this->~Record();
169 new (this) Record(std::move(other));
170 return *this;
171 }
172
173 void set_data(char *data, int len = 0)
174 {
175 this->data_ = data;
176 this->len_ = len;
177 }
178 void set_data_owner(char *data, int len)
179 {
180 ASSERT(len != 0, "the len of data should not be 0");
181 this->~Record();
182
183 this->data_ = data;
184 this->len_ = len;
185 this->owner_ = true;
186 }
187
188 RC copy_data(const char *data, int len)
189 {
190 ASSERT(len!= 0, "the len of data should not be 0");
191 char *tmp = (char *)malloc(len);
192 if (nullptr == tmp) {
193 LOG_WARN("failed to allocate memory. size=%d", len);
194 return RC::NOMEM;
195 }
196
197 memcpy(tmp, data, len);
198 set_data_owner(tmp, len);
199 return RC::SUCCESS;
200 }
201
202 RC new_record(int len)
203 {
204 ASSERT(len!= 0, "the len of data should not be 0");
205 char *tmp = (char *)malloc(len);
206 if (nullptr == tmp) {
207 LOG_WARN("failed to allocate memory. size=%d", len);
208 return RC::NOMEM;
209 }
210 set_data_owner(tmp, len);
211 return RC::SUCCESS;
212 }
213
214 RC set_field(int field_offset, int field_len, char *data)
215 {
216 if (!owner_) {
217 LOG_ERROR("cannot set field when record does not own the memory");
218 return RC::INTERNAL;
219 }
220 if (field_offset + field_len > len_) {
221 LOG_ERROR("invalid offset or length. offset=%d, length=%d, total length=%d", field_offset, field_len, len_);
222 return RC::INVALID_ARGUMENT;
223 }
224
225 memcpy(data_ + field_offset, data, field_len);
226 return RC::SUCCESS;
227 }
228
229 char *data() { return this->data_; }
230 const char *data() const { return this->data_; }
231 int len() const { return this->len_; }
232
233 void set_rid(const RID &rid) { this->rid_ = rid; }
234 void set_rid(const PageNum page_num, const SlotNum slot_num)
235 {
236 this->rid_.page_num = page_num;
237 this->rid_.slot_num = slot_num;
238 }
239 RID &rid() { return rid_; }
240 const RID &rid() const { return rid_; }
241
242private:
243 RID rid_;
244
245 char *data_ = nullptr;
246 int len_ = 0;
247 bool owner_ = false;
248};
字段
Definition: field.h:25
表示一个记录
Definition: record.h:101
bool owner_
如果不是record自己来管理内存,这个字段可能是无效的
Definition: record.h:247
Definition: record.h:86
标识一个记录的位置 一个记录是放在某个文件的某个页面的某个槽位。这里不记录文件信息,记录页面和槽位信息
Definition: record.h:35
static RID * min()
Definition: record.h:68
static RID * max()
返回一个“最大的”RID 我们假设page num和slot num都不会使用对应数值类型的最大值
Definition: record.h:78