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 key_ = other.key_;
116 data_ = other.data_;
117 len_ = other.len_;
118 owner_ = other.owner_;
119
120 if (other.owner_) {
121 char *tmp = (char *)malloc(other.len_);
122 ASSERT(nullptr != tmp, "failed to allocate memory. size=%d", other.len_);
123 memcpy(tmp, other.data_, other.len_);
124 data_ = tmp;
125 }
126 }
127
128 Record &operator=(const Record &other)
129 {
130 if (this == &other) {
131 return *this;
132 }
133
134 if (!owner_ || len_ != other.len_) {
135 this->~Record();
136 new (this) Record(other);
137 return *this;
138 }
139 this->rid_ = other.rid_;
140 this->key_ = other.key_;
141 memcpy(data_, other.data_, other.len_);
142 return *this;
143 }
144
145 Record(Record &&other)
146 {
147 rid_ = other.rid_;
148 key_ = other.key_;
149 if (!other.owner_) {
150 data_ = other.data_;
151 len_ = other.len_;
152 other.data_ = nullptr;
153 other.len_ = 0;
154 this->owner_ = false;
155 } else {
156 data_ = other.data_;
157 len_ = other.len_;
158 other.data_ = nullptr;
159 other.len_ = 0;
160 this->owner_ = true;
161 }
162 }
163
164 Record &operator=(Record &&other)
165 {
166 if (this == &other) {
167 return *this;
168 }
169
170 this->~Record();
171 new (this) Record(std::move(other));
172 return *this;
173 }
174
175 void set_data(char *data, int len = 0)
176 {
177 this->data_ = data;
178 this->len_ = len;
179 }
180 void set_data_owner(char *data, int len)
181 {
182 ASSERT(len != 0, "the len of data should not be 0");
183 this->~Record();
184
185 this->data_ = data;
186 this->len_ = len;
187 this->owner_ = true;
188 }
189
190 RC copy_data(const char *data, int len)
191 {
192 ASSERT(len!= 0, "the len of data should not be 0");
193 char *tmp = (char *)malloc(len);
194 if (nullptr == tmp) {
195 LOG_WARN("failed to allocate memory. size=%d", len);
196 return RC::NOMEM;
197 }
198
199 memcpy(tmp, data, len);
200 set_data_owner(tmp, len);
201 return RC::SUCCESS;
202 }
203
204 RC new_record(int len)
205 {
206 ASSERT(len!= 0, "the len of data should not be 0");
207 char *tmp = (char *)malloc(len);
208 if (nullptr == tmp) {
209 LOG_WARN("failed to allocate memory. size=%d", len);
210 return RC::NOMEM;
211 }
212 set_data_owner(tmp, len);
213 return RC::SUCCESS;
214 }
215
216 RC set_field(int field_offset, int field_len, char *data)
217 {
218 if (!owner_) {
219 LOG_ERROR("cannot set field when record does not own the memory");
220 return RC::INTERNAL;
221 }
222 if (field_offset + field_len > len_) {
223 LOG_ERROR("invalid offset or length. offset=%d, length=%d, total length=%d", field_offset, field_len, len_);
224 return RC::INVALID_ARGUMENT;
225 }
226
227 memcpy(data_ + field_offset, data, field_len);
228 return RC::SUCCESS;
229 }
230
231 RC reset_filed(int field_offset, int field_len)
232 {
233 if (!owner_) {
234 LOG_ERROR("cannot set field when record does not own the memory");
235 return RC::INTERNAL;
236 }
237 if (field_offset + field_len > len_) {
238 LOG_ERROR("invalid offset or length. offset=%d, length=%d, total length=%d", field_offset, field_len, len_);
239 return RC::INVALID_ARGUMENT;
240 }
241
242 memset(data_ + field_offset, 0, field_len);
243 return RC::SUCCESS;
244 }
245
246 char *data() { return this->data_; }
247 const char *data() const { return this->data_; }
248 int len() const { return this->len_; }
249
250 void set_rid(const RID &rid) { this->rid_ = rid; }
251 void set_rid(const PageNum page_num, const SlotNum slot_num)
252 {
253 this->rid_.page_num = page_num;
254 this->rid_.slot_num = slot_num;
255 }
256
257 RID &rid() { return rid_; }
258 const RID &rid() const { return rid_; }
259 void set_key(const string &key) { key_ = key; }
260 const string &key() const { return key_; }
261
262private:
263 RID rid_;
264 string key_;
265 char *data_ = nullptr;
266 int len_ = 0;
267 bool owner_ = false;
268};
字段
Definition: field.h:25
表示一个记录
Definition: record.h:101
bool owner_
如果不是record自己来管理内存,这个字段可能是无效的
Definition: record.h:267
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