table.cpp 15.6 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 & Wangyunlai on 2021/5/13.
羽飞's avatar
羽飞 已提交
13 14 15 16 17 18
//

#include <limits.h>
#include <string.h>
#include <algorithm>

L
Longda 已提交
19
#include "common/defs.h"
羽飞's avatar
羽飞 已提交
20 21 22 23 24
#include "storage/common/table.h"
#include "storage/common/table_meta.h"
#include "common/log/log.h"
#include "common/lang/string.h"
#include "storage/default/disk_buffer_pool.h"
羽飞's avatar
羽飞 已提交
25
#include "storage/record/record_manager.h"
羽飞's avatar
羽飞 已提交
26 27
#include "storage/common/condition_filter.h"
#include "storage/common/meta_util.h"
羽飞's avatar
羽飞 已提交
28 29
#include "storage/index/index.h"
#include "storage/index/bplus_tree_index.h"
羽飞's avatar
羽飞 已提交
30 31
#include "storage/trx/trx.h"

L
Longda 已提交
32 33 34 35 36 37
Table::~Table()
{
  if (record_handler_ != nullptr) {
    delete record_handler_;
    record_handler_ = nullptr;
  }
羽飞's avatar
羽飞 已提交
38

羽飞's avatar
羽飞 已提交
39 40
  if (data_buffer_pool_ != nullptr) {
    data_buffer_pool_->close_file();
羽飞's avatar
羽飞 已提交
41 42 43
    data_buffer_pool_ = nullptr;
  }

L
Longda 已提交
44 45 46 47 48 49
  for (std::vector<Index *>::iterator it = indexes_.begin(); it != indexes_.end(); ++it) {
    Index *index = *it;
    delete index;
  }
  indexes_.clear();

羽飞's avatar
羽飞 已提交
50 51 52
  LOG_INFO("Table has been closed: %s", name());
}

羽飞's avatar
羽飞 已提交
53 54 55 56 57
RC Table::create(const char *path, 
                 const char *name, 
                 const char *base_dir, 
                 int attribute_count, 
                 const AttrInfo attributes[])
L
Longda 已提交
58
{
羽飞's avatar
羽飞 已提交
59

L
Longda 已提交
60
  if (common::is_blank(name)) {
羽飞's avatar
羽飞 已提交
61 62 63 64 65 66
    LOG_WARN("Name cannot be empty");
    return RC::INVALID_ARGUMENT;
  }
  LOG_INFO("Begin to create table %s:%s", base_dir, name);

  if (attribute_count <= 0 || nullptr == attributes) {
L
Longda 已提交
67
    LOG_WARN("Invalid arguments. table_name=%s, attribute_count=%d, attributes=%p", name, attribute_count, attributes);
羽飞's avatar
羽飞 已提交
68 69 70 71 72 73 74 75
    return RC::INVALID_ARGUMENT;
  }

  RC rc = RC::SUCCESS;

  // 使用 table_name.table记录一个表的元数据
  // 判断表文件是否已经存在
  int fd = ::open(path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0600);
L
Longda 已提交
76
  if (fd < 0) {
羽飞's avatar
羽飞 已提交
77
    if (EEXIST == errno) {
L
Longda 已提交
78
      LOG_ERROR("Failed to create table file, it has been created. %s, EEXIST, %s", path, strerror(errno));
羽飞's avatar
羽飞 已提交
79 80
      return RC::SCHEMA_TABLE_EXIST;
    }
L
Longda 已提交
81
    LOG_ERROR("Create table file failed. filename=%s, errmsg=%d:%s", path, errno, strerror(errno));
羽飞's avatar
羽飞 已提交
82
    return RC::IOERR_OPEN;
羽飞's avatar
羽飞 已提交
83 84 85 86 87 88 89
  }

  close(fd);

  // 创建文件
  if ((rc = table_meta_.init(name, attribute_count, attributes)) != RC::SUCCESS) {
    LOG_ERROR("Failed to init table meta. name:%s, ret:%d", name, rc);
L
Longda 已提交
90
    return rc;  // delete table file
羽飞's avatar
羽飞 已提交
91 92 93 94 95 96
  }

  std::fstream fs;
  fs.open(path, std::ios_base::out | std::ios_base::binary);
  if (!fs.is_open()) {
    LOG_ERROR("Failed to open file for write. file name=%s, errmsg=%s", path, strerror(errno));
羽飞's avatar
羽飞 已提交
97
    return RC::IOERR_OPEN;
羽飞's avatar
羽飞 已提交
98 99 100 101 102 103
  }

  // 记录元数据到文件中
  table_meta_.serialize(fs);
  fs.close();

L
Longda 已提交
104
  std::string data_file = table_data_file(base_dir, name);
羽飞's avatar
羽飞 已提交
105 106
  BufferPoolManager &bpm = BufferPoolManager::instance();
  rc = bpm.create_file(data_file.c_str());
羽飞's avatar
羽飞 已提交
107 108 109 110 111 112
  if (rc != RC::SUCCESS) {
    LOG_ERROR("Failed to create disk buffer pool of data file. file name=%s", data_file.c_str());
    return rc;
  }

  rc = init_record_handler(base_dir);
L
Longda 已提交
113 114 115 116 117
  if (rc != RC::SUCCESS) {
    LOG_ERROR("Failed to create table %s due to init record handler failed.", data_file.c_str());
    // don't need to remove the data_file
    return rc;
  }
羽飞's avatar
羽飞 已提交
118 119 120 121 122 123

  base_dir_ = base_dir;
  LOG_INFO("Successfully create table %s:%s", base_dir, name);
  return rc;
}

羽飞's avatar
羽飞 已提交
124
RC Table::open(const char *meta_file, const char *base_dir)
L
Longda 已提交
125
{
羽飞's avatar
羽飞 已提交
126 127
  // 加载元数据文件
  std::fstream fs;
L
Longda 已提交
128
  std::string meta_file_path = std::string(base_dir) + common::FILE_PATH_SPLIT_STR + meta_file;
羽飞's avatar
羽飞 已提交
129 130
  fs.open(meta_file_path, std::ios_base::in | std::ios_base::binary);
  if (!fs.is_open()) {
L
Longda 已提交
131
    LOG_ERROR("Failed to open meta file for read. file name=%s, errmsg=%s", meta_file_path.c_str(), strerror(errno));
羽飞's avatar
羽飞 已提交
132
    return RC::IOERR_OPEN;
羽飞's avatar
羽飞 已提交
133 134
  }
  if (table_meta_.deserialize(fs) < 0) {
L
Longda 已提交
135 136
    LOG_ERROR("Failed to deserialize table meta. file name=%s", meta_file_path.c_str());
    fs.close();
羽飞's avatar
羽飞 已提交
137
    return RC::INTERNAL;
羽飞's avatar
羽飞 已提交
138 139 140 141 142
  }
  fs.close();

  // 加载数据文件
  RC rc = init_record_handler(base_dir);
L
Longda 已提交
143 144 145 146 147
  if (rc != RC::SUCCESS) {
    LOG_ERROR("Failed to open table %s due to init record handler failed.", base_dir);
    // don't need to remove the data_file
    return rc;
  }
羽飞's avatar
羽飞 已提交
148 149 150 151 152 153 154 155

  base_dir_ = base_dir;

  const int index_num = table_meta_.index_num();
  for (int i = 0; i < index_num; i++) {
    const IndexMeta *index_meta = table_meta_.index(i);
    const FieldMeta *field_meta = table_meta_.field(index_meta->field());
    if (field_meta == nullptr) {
L
Longda 已提交
156
      LOG_ERROR("Found invalid index meta info which has a non-exists field. table=%s, index=%s, field=%s",
羽飞's avatar
羽飞 已提交
157
                name(), index_meta->name(), index_meta->field());
L
Longda 已提交
158 159
      // skip cleanup
      //  do all cleanup action in destructive Table function
羽飞's avatar
羽飞 已提交
160
      return RC::INTERNAL;
羽飞's avatar
羽飞 已提交
161 162 163
    }

    BplusTreeIndex *index = new BplusTreeIndex();
L
Longda 已提交
164
    std::string index_file = table_index_file(base_dir, name(), index_meta->name());
羽飞's avatar
羽飞 已提交
165 166 167
    rc = index->open(index_file.c_str(), *index_meta, *field_meta);
    if (rc != RC::SUCCESS) {
      delete index;
羽飞's avatar
羽飞 已提交
168 169
      LOG_ERROR("Failed to open index. table=%s, index=%s, file=%s, rc=%s",
                name(), index_meta->name(), index_file.c_str(), strrc(rc));
L
Longda 已提交
170 171
      // skip cleanup
      //  do all cleanup action in destructive Table function.
羽飞's avatar
羽飞 已提交
172 173 174 175
      return rc;
    }
    indexes_.push_back(index);
  }
羽飞's avatar
羽飞 已提交
176

羽飞's avatar
羽飞 已提交
177 178 179
  return rc;
}

羽飞's avatar
羽飞 已提交
180
RC Table::insert_record(Record &record)
L
Longda 已提交
181
{
羽飞's avatar
羽飞 已提交
182
  RC rc = RC::SUCCESS;
羽飞's avatar
羽飞 已提交
183
  rc = record_handler_->insert_record(record.data(), table_meta_.record_size(), &record.rid());
羽飞's avatar
羽飞 已提交
184
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
185
    LOG_ERROR("Insert record failed. table name=%s, rc=%s", table_meta_.name(), strrc(rc));
羽飞's avatar
羽飞 已提交
186 187 188
    return rc;
  }

羽飞's avatar
羽飞 已提交
189 190 191
  rc = insert_entry_of_indexes(record.data(), record.rid());
  if (rc != RC::SUCCESS) { // 可能出现了键值重复
    RC rc2 = delete_entry_of_indexes(record.data(), record.rid(), false/*error_on_not_exists*/);
羽飞's avatar
羽飞 已提交
192
    if (rc2 != RC::SUCCESS) {
L
Longda 已提交
193
      LOG_ERROR("Failed to rollback index data when insert index entries failed. table name=%s, rc=%d:%s",
羽飞's avatar
羽飞 已提交
194
                name(), rc2, strrc(rc2));
羽飞's avatar
羽飞 已提交
195
    }
羽飞's avatar
羽飞 已提交
196
    rc2 = record_handler_->delete_record(&record.rid());
羽飞's avatar
羽飞 已提交
197 198
    if (rc2 != RC::SUCCESS) {
      LOG_PANIC("Failed to rollback record data when insert index entries failed. table name=%s, rc=%d:%s",
羽飞's avatar
羽飞 已提交
199
                name(), rc2, strrc(rc2));
羽飞's avatar
羽飞 已提交
200 201 202 203 204
    }
  }
  return rc;
}

羽飞's avatar
羽飞 已提交
205
RC Table::visit_record(const RID &rid, bool readonly, std::function<void(Record &)> visitor)
羽飞's avatar
羽飞 已提交
206
{
羽飞's avatar
羽飞 已提交
207
  return record_handler_->visit_record(rid, readonly, visitor);
羽飞's avatar
羽飞 已提交
208
}
羽飞's avatar
羽飞 已提交
209

羽飞's avatar
羽飞 已提交
210
RC Table::get_record(const RID &rid, Record &record)
L
Longda 已提交
211
{
羽飞's avatar
羽飞 已提交
212 213 214
  const int record_size = table_meta_.record_size();
  char *record_data = (char *)malloc(record_size);
  ASSERT(nullptr != record_data, "failed to malloc memory. record data size=%d", record_size);
羽飞's avatar
羽飞 已提交
215

羽飞's avatar
羽飞 已提交
216 217 218 219 220
  auto copier = [&record, record_data, record_size](Record &record_src) {
    memcpy(record_data, record_src.data(), record_size);
    record.set_rid(record_src.rid());
  };
  RC rc = record_handler_->visit_record(rid, true/*readonly*/, copier);
羽飞's avatar
羽飞 已提交
221
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
222 223
    free(record_data);
    LOG_WARN("failed to visit record. rid=%s, table=%s, rc=%s", rid.to_string().c_str(), name(), strrc(rc));
羽飞's avatar
羽飞 已提交
224 225 226
    return rc;
  }

羽飞's avatar
羽飞 已提交
227
  record.set_data_owner(record_data, record_size);
羽飞's avatar
羽飞 已提交
228 229 230
  return rc;
}

L
Longda 已提交
231 232
const char *Table::name() const
{
羽飞's avatar
羽飞 已提交
233 234 235
  return table_meta_.name();
}

L
Longda 已提交
236 237
const TableMeta &Table::table_meta() const
{
羽飞's avatar
羽飞 已提交
238 239 240
  return table_meta_;
}

羽飞's avatar
羽飞 已提交
241
RC Table::make_record(int value_num, const Value *values, Record &record)
L
Longda 已提交
242
{
羽飞's avatar
羽飞 已提交
243 244
  // 检查字段类型是否一致
  if (value_num + table_meta_.sys_field_num() != table_meta_.field_num()) {
L
Longda 已提交
245
    LOG_WARN("Input values don't match the table's schema, table name:%s", table_meta_.name());
羽飞's avatar
羽飞 已提交
246 247 248 249 250 251 252 253
    return RC::SCHEMA_FIELD_MISSING;
  }

  const int normal_field_start_index = table_meta_.sys_field_num();
  for (int i = 0; i < value_num; i++) {
    const FieldMeta *field = table_meta_.field(i + normal_field_start_index);
    const Value &value = values[i];
    if (field->type() != value.type) {
L
Longda 已提交
254
      LOG_ERROR("Invalid value type. table name =%s, field name=%s, type=%d, but given=%d",
羽飞's avatar
羽飞 已提交
255
                table_meta_.name(), field->name(), field->type(), value.type);
羽飞's avatar
羽飞 已提交
256 257 258 259 260 261
      return RC::SCHEMA_FIELD_TYPE_MISMATCH;
    }
  }

  // 复制所有字段的值
  int record_size = table_meta_.record_size();
羽飞's avatar
羽飞 已提交
262
  char *record_data = (char *)malloc(record_size);
羽飞's avatar
羽飞 已提交
263 264 265 266

  for (int i = 0; i < value_num; i++) {
    const FieldMeta *field = table_meta_.field(i + normal_field_start_index);
    const Value &value = values[i];
羽飞's avatar
羽飞 已提交
267 268
    size_t copy_len = field->len();
    if (field->type() == CHARS) {
羽飞's avatar
羽飞 已提交
269
      const size_t data_len = value.string_value.size();
羽飞's avatar
羽飞 已提交
270 271 272 273
      if (copy_len > data_len) {
        copy_len = data_len + 1;
      }
    }
羽飞's avatar
羽飞 已提交
274
    memcpy(record_data + field->offset(), value.data(), copy_len);
羽飞's avatar
羽飞 已提交
275 276
  }

羽飞's avatar
羽飞 已提交
277
  record.set_data_owner(record_data, record_size);
羽飞's avatar
羽飞 已提交
278 279 280
  return RC::SUCCESS;
}

L
Longda 已提交
281 282 283
RC Table::init_record_handler(const char *base_dir)
{
  std::string data_file = table_data_file(base_dir, table_meta_.name());
羽飞's avatar
羽飞 已提交
284

羽飞's avatar
羽飞 已提交
285
  RC rc = BufferPoolManager::instance().open_file(data_file.c_str(), data_buffer_pool_);
羽飞's avatar
羽飞 已提交
286
  if (rc != RC::SUCCESS) {
L
Longda 已提交
287
    LOG_ERROR("Failed to open disk buffer pool for file:%s. rc=%d:%s", data_file.c_str(), rc, strrc(rc));
羽飞's avatar
羽飞 已提交
288 289 290 291
    return rc;
  }

  record_handler_ = new RecordFileHandler();
羽飞's avatar
羽飞 已提交
292
  rc = record_handler_->init(data_buffer_pool_);
羽飞's avatar
羽飞 已提交
293
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
294
    LOG_ERROR("Failed to init record handler. rc=%s", strrc(rc));
羽飞's avatar
羽飞 已提交
295 296
    data_buffer_pool_->close_file();
    data_buffer_pool_ = nullptr;
L
Longda 已提交
297 298
    delete record_handler_;
    record_handler_ = nullptr;
羽飞's avatar
羽飞 已提交
299 300 301 302 303 304
    return rc;
  }

  return rc;
}

羽飞's avatar
羽飞 已提交
305
RC Table::get_record_scanner(RecordFileScanner &scanner, Trx *trx, bool readonly)
L
Longda 已提交
306
{
羽飞's avatar
羽飞 已提交
307
  RC rc = scanner.open_scan(this, *data_buffer_pool_, trx, readonly, nullptr);
羽飞's avatar
羽飞 已提交
308
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
309
    LOG_ERROR("failed to open scanner. rc=%s", strrc(rc));
羽飞's avatar
羽飞 已提交
310 311 312 313
  }
  return rc;
}

羽飞's avatar
羽飞 已提交
314
RC Table::create_index(Trx *trx, const FieldMeta *field_meta, const char *index_name)
L
Longda 已提交
315
{
羽飞's avatar
羽飞 已提交
316
  if (common::is_blank(index_name) || nullptr == field_meta) {
L
Longda 已提交
317
    LOG_INFO("Invalid input arguments, table name is %s, index_name is blank or attribute_name is blank", name());
羽飞's avatar
羽飞 已提交
318 319 320 321 322 323
    return RC::INVALID_ARGUMENT;
  }

  IndexMeta new_index_meta;
  RC rc = new_index_meta.init(index_name, *field_meta);
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
324 325
    LOG_INFO("Failed to init IndexMeta in table:%s, index_name:%s, field_name:%s", 
             name(), index_name, field_meta->name());
羽飞's avatar
羽飞 已提交
326 327 328 329 330
    return rc;
  }

  // 创建索引相关数据
  BplusTreeIndex *index = new BplusTreeIndex();
L
Longda 已提交
331
  std::string index_file = table_index_file(base_dir_.c_str(), name(), index_name);
羽飞's avatar
羽飞 已提交
332 333 334 335 336 337 338 339
  rc = index->create(index_file.c_str(), new_index_meta, *field_meta);
  if (rc != RC::SUCCESS) {
    delete index;
    LOG_ERROR("Failed to create bplus tree index. file name=%s, rc=%d:%s", index_file.c_str(), rc, strrc(rc));
    return rc;
  }

  // 遍历当前的所有数据,插入这个索引
羽飞's avatar
羽飞 已提交
340 341
  RecordFileScanner scanner;
  rc = get_record_scanner(scanner, trx, true/*readonly*/);
羽飞's avatar
羽飞 已提交
342
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
343 344
    LOG_WARN("failed to create scanner while creating index. table=%s, index=%s, rc=%s", 
             name(), index_name, strrc(rc));
羽飞's avatar
羽飞 已提交
345 346
    return rc;
  }
羽飞's avatar
羽飞 已提交
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365

  Record record;
  while (scanner.has_next()) {
    rc = scanner.next(record);
    if (rc != RC::SUCCESS) {
      LOG_WARN("failed to scan records while creating index. table=%s, index=%s, rc=%s",
               name(), index_name, strrc(rc));
      return rc;
    }
    rc = index->insert_entry(record.data(), &record.rid());
    if (rc != RC::SUCCESS) {
      LOG_WARN("failed to insert record into index while creating index. table=%s, index=%s, rc=%s",
               name(), index_name, strrc(rc));
      return rc;         
    }
  }
  scanner.close_scan();
  LOG_INFO("inserted all records into new index. table=%s, index=%s", name(), index_name);
  
羽飞's avatar
羽飞 已提交
366 367
  indexes_.push_back(index);

羽飞's avatar
羽飞 已提交
368
  /// 接下来将这个索引放到表的元数据中
羽飞's avatar
羽飞 已提交
369 370 371 372 373 374
  TableMeta new_table_meta(table_meta_);
  rc = new_table_meta.add_index(new_index_meta);
  if (rc != RC::SUCCESS) {
    LOG_ERROR("Failed to add index (%s) on table (%s). error=%d:%s", index_name, name(), rc, strrc(rc));
    return rc;
  }
羽飞's avatar
羽飞 已提交
375 376 377

  /// 内存中有一份元数据,磁盘文件也有一份元数据。修改磁盘文件时,先创建一个临时文件,写入完成后再rename为正式文件
  /// 这样可以防止文件内容不完整
羽飞's avatar
羽飞 已提交
378 379 380 381 382 383
  // 创建元数据临时文件
  std::string tmp_file = table_meta_file(base_dir_.c_str(), name()) + ".tmp";
  std::fstream fs;
  fs.open(tmp_file, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
  if (!fs.is_open()) {
    LOG_ERROR("Failed to open file for write. file name=%s, errmsg=%s", tmp_file.c_str(), strerror(errno));
羽飞's avatar
羽飞 已提交
384
    return RC::IOERR_OPEN;  // 创建索引中途出错,要做还原操作
羽飞's avatar
羽飞 已提交
385 386 387
  }
  if (new_table_meta.serialize(fs) < 0) {
    LOG_ERROR("Failed to dump new table meta to file: %s. sys err=%d:%s", tmp_file.c_str(), errno, strerror(errno));
羽飞's avatar
羽飞 已提交
388
    return RC::IOERR_WRITE;
羽飞's avatar
羽飞 已提交
389 390 391 392 393 394 395
  }
  fs.close();

  // 覆盖原始元数据文件
  std::string meta_file = table_meta_file(base_dir_.c_str(), name());
  int ret = rename(tmp_file.c_str(), meta_file.c_str());
  if (ret != 0) {
L
Longda 已提交
396 397
    LOG_ERROR("Failed to rename tmp meta file (%s) to normal meta file (%s) while creating index (%s) on table (%s). "
              "system error=%d:%s",
羽飞's avatar
羽飞 已提交
398
              tmp_file.c_str(), meta_file.c_str(), index_name, name(), errno, strerror(errno));
羽飞's avatar
羽飞 已提交
399
    return RC::IOERR_WRITE;
羽飞's avatar
羽飞 已提交
400 401 402 403
  }

  table_meta_.swap(new_table_meta);

L
Longda 已提交
404
  LOG_INFO("Successfully added a new index (%s) on the table (%s)", index_name, name());
羽飞's avatar
羽飞 已提交
405 406 407
  return rc;
}

羽飞's avatar
羽飞 已提交
408
RC Table::delete_record(const Record &record)
羽飞's avatar
羽飞 已提交
409 410
{
  RC rc = RC::SUCCESS;
羽飞's avatar
羽飞 已提交
411 412 413 414 415
  for (Index *index : indexes_) {
    rc = index->delete_entry(record.data(), &record.rid());
    ASSERT(RC::SUCCESS == rc, 
           "failed to delete entry from index. table name=%s, index name=%s, rid=%s, rc=%s",
           name(), index->index_meta().name(), record.rid().to_string().c_str(), strrc(rc));
羽飞's avatar
羽飞 已提交
416
  }
羽飞's avatar
羽飞 已提交
417
  rc = record_handler_->delete_record(&record.rid());
羽飞's avatar
羽飞 已提交
418 419 420
  return rc;
}

L
Longda 已提交
421 422
RC Table::insert_entry_of_indexes(const char *record, const RID &rid)
{
羽飞's avatar
羽飞 已提交
423 424 425 426 427 428 429 430 431 432
  RC rc = RC::SUCCESS;
  for (Index *index : indexes_) {
    rc = index->insert_entry(record, &rid);
    if (rc != RC::SUCCESS) {
      break;
    }
  }
  return rc;
}

L
Longda 已提交
433 434
RC Table::delete_entry_of_indexes(const char *record, const RID &rid, bool error_on_not_exists)
{
羽飞's avatar
羽飞 已提交
435 436 437 438 439 440 441 442 443 444 445 446
  RC rc = RC::SUCCESS;
  for (Index *index : indexes_) {
    rc = index->delete_entry(record, &rid);
    if (rc != RC::SUCCESS) {
      if (rc != RC::RECORD_INVALID_KEY || !error_on_not_exists) {
        break;
      }
    }
  }
  return rc;
}

L
Longda 已提交
447 448 449
Index *Table::find_index(const char *index_name) const
{
  for (Index *index : indexes_) {
羽飞's avatar
羽飞 已提交
450 451 452 453 454 455
    if (0 == strcmp(index->index_meta().name(), index_name)) {
      return index;
    }
  }
  return nullptr;
}
羽飞's avatar
羽飞 已提交
456 457 458 459 460 461 462 463 464
Index *Table::find_index_by_field(const char *field_name) const
{
  const TableMeta &table_meta = this->table_meta();
  const IndexMeta *index_meta = table_meta.find_index_by_field(field_name);
  if (index_meta != nullptr) {
    return this->find_index(index_meta->name());
  }
  return nullptr;
}
羽飞's avatar
羽飞 已提交
465

L
Longda 已提交
466 467
RC Table::sync()
{
羽飞's avatar
羽飞 已提交
468
  RC rc = RC::SUCCESS;
L
Longda 已提交
469
  for (Index *index : indexes_) {
羽飞's avatar
羽飞 已提交
470 471 472
    rc = index->sync();
    if (rc != RC::SUCCESS) {
      LOG_ERROR("Failed to flush index's pages. table=%s, index=%s, rc=%d:%s",
L
Longda Feng 已提交
473 474 475 476
          name(),
          index->index_meta().name(),
          rc,
          strrc(rc));
羽飞's avatar
羽飞 已提交
477 478 479 480 481 482
      return rc;
    }
  }
  LOG_INFO("Sync table over. table=%s", name());
  return rc;
}