bplus_tree.cpp 60.4 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. */

//
L
Longda 已提交
12
// Created by Xie Meiyi
13
// Rewritten by Longda & Wangyunlai
羽飞's avatar
羽飞 已提交
14 15 16 17 18 19 20
//
#include "storage/common/bplus_tree.h"
#include "storage/default/disk_buffer_pool.h"
#include "rc.h"
#include "common/log/log.h"
#include "sql/parser/parse_defs.h"

L
Longda 已提交
21 22
#define FIRST_INDEX_PAGE 1

羽飞's avatar
羽飞 已提交
23
int calc_internal_page_capacity(int attr_length)
L
Longda 已提交
24
{
羽飞's avatar
羽飞 已提交
25
  int item_size = attr_length + sizeof(RID) + sizeof(PageNum);
L
Longda 已提交
26 27

  int capacity =
羽飞's avatar
羽飞 已提交
28
    ((int)BP_PAGE_DATA_SIZE - InternalIndexNode::HEADER_SIZE) / item_size;
L
Longda 已提交
29
  return capacity;
羽飞's avatar
羽飞 已提交
30 31
}

羽飞's avatar
羽飞 已提交
32
int calc_leaf_page_capacity(int attr_length)
L
Longda 已提交
33
{
羽飞's avatar
羽飞 已提交
34 35 36 37
  int item_size = attr_length + sizeof(RID) + sizeof(RID);
  int capacity =
    ((int)BP_PAGE_DATA_SIZE - LeafIndexNode::HEADER_SIZE) / item_size;
  return capacity;
羽飞's avatar
羽飞 已提交
38 39
}

羽飞's avatar
羽飞 已提交
40 41 42 43 44 45
/////////////////////////////////////////////////////////////////////////////////
IndexNodeHandler::IndexNodeHandler(const IndexFileHeader &header, BPPageHandle &page_handle)
  : header_(header), page_num_(page_handle.page_num()), node_((IndexNode *)page_handle.data())
{}

bool IndexNodeHandler::is_leaf() const
L
Longda 已提交
46
{
羽飞's avatar
羽飞 已提交
47 48 49 50 51 52 53 54 55 56 57
  return node_->is_leaf;
}
void IndexNodeHandler::init_empty(bool leaf)
{
  node_->is_leaf = leaf;
  node_->key_num = 0;
  node_->parent = BP_INVALID_PAGE_NUM;
}
PageNum IndexNodeHandler::page_num() const
{
  return page_num_;
羽飞's avatar
羽飞 已提交
58 59
}

羽飞's avatar
羽飞 已提交
60
int IndexNodeHandler::key_size() const
羽飞's avatar
羽飞 已提交
61
{
羽飞's avatar
羽飞 已提交
62 63
  return header_.key_length;
}
羽飞's avatar
羽飞 已提交
64

羽飞's avatar
羽飞 已提交
65 66 67 68 69
int IndexNodeHandler::value_size() const
{
  // return header_.value_size;
  return sizeof(RID);
}
L
Longda 已提交
70

羽飞's avatar
羽飞 已提交
71 72 73 74
int IndexNodeHandler::item_size() const
{
  return key_size() + value_size();
}
L
Longda 已提交
75

羽飞's avatar
羽飞 已提交
76 77 78 79
int IndexNodeHandler::size() const
{
  return node_->key_num;
}
羽飞's avatar
羽飞 已提交
80

羽飞's avatar
羽飞 已提交
81 82 83 84
void IndexNodeHandler::increase_size(int n)
{
  node_->key_num += n;
}
L
Longda 已提交
85

羽飞's avatar
羽飞 已提交
86 87 88 89
PageNum IndexNodeHandler::parent_page_num() const
{
  return node_->parent;
}
羽飞's avatar
羽飞 已提交
90

羽飞's avatar
羽飞 已提交
91 92 93 94 95 96 97
void IndexNodeHandler::set_parent_page_num(PageNum page_num)
{
  this->node_->parent = page_num;
}
std::string to_string(const IndexNodeHandler &handler)
{
  std::stringstream ss;
羽飞's avatar
羽飞 已提交
98

羽飞's avatar
羽飞 已提交
99 100 101 102
  ss << "PageNum:" << handler.page_num()
     << ",is_leaf:" << handler.is_leaf() << ","
     << "key_num:" << handler.size() << ","
     << "parent:" << handler.parent_page_num() << ",";
羽飞's avatar
羽飞 已提交
103

羽飞's avatar
羽飞 已提交
104 105
  return ss.str();
}
羽飞's avatar
羽飞 已提交
106

羽飞's avatar
羽飞 已提交
107 108 109 110 111 112 113 114
bool IndexNodeHandler::validate() const
{
  if (parent_page_num() == BP_INVALID_PAGE_NUM) {
    // this is a root page
    if (size() < 1) {
      LOG_WARN("root page has no item");
      return false;
    }
羽飞's avatar
羽飞 已提交
115

羽飞's avatar
羽飞 已提交
116 117 118 119
    if (!is_leaf() && size() < 2) {
      LOG_WARN("root page internal node has less than 2 child. size=%d", size());
      return false;
    }
L
Longda 已提交
120
  }
羽飞's avatar
羽飞 已提交
121
  return true;
羽飞's avatar
羽飞 已提交
122 123
}

羽飞's avatar
羽飞 已提交
124 125 126 127 128 129
/////////////////////////////////////////////////////////////////////////////////
LeafIndexNodeHandler::LeafIndexNodeHandler(const IndexFileHeader &header, BPPageHandle &page_handle)
  : IndexNodeHandler(header, page_handle), leaf_node_((LeafIndexNode *)page_handle.data())
{}

void LeafIndexNodeHandler::init_empty()
L
Longda 已提交
130
{
羽飞's avatar
羽飞 已提交
131 132 133 134
  IndexNodeHandler::init_empty(true);
  leaf_node_->prev_brother = BP_INVALID_PAGE_NUM;
  leaf_node_->next_brother = BP_INVALID_PAGE_NUM;
}
羽飞's avatar
羽飞 已提交
135

羽飞's avatar
羽飞 已提交
136 137 138 139
void LeafIndexNodeHandler::set_next_page(PageNum page_num)
{
  leaf_node_->next_brother = page_num;
}
L
Longda 已提交
140

羽飞's avatar
羽飞 已提交
141 142 143 144 145 146 147 148 149 150 151 152
void LeafIndexNodeHandler::set_prev_page(PageNum page_num)
{
  leaf_node_->prev_brother = page_num;
}
PageNum LeafIndexNodeHandler::next_page() const
{
  return leaf_node_->next_brother;
}
PageNum LeafIndexNodeHandler::prev_page() const
{
  return leaf_node_->prev_brother;
}
L
Longda 已提交
153

羽飞's avatar
羽飞 已提交
154 155 156 157 158
char *LeafIndexNodeHandler::key_at(int index)
{
  assert(index >= 0 && index < size());
  return __key_at(index);
}
L
Longda 已提交
159

羽飞's avatar
羽飞 已提交
160 161 162 163 164
char *LeafIndexNodeHandler::value_at(int index)
{
  assert(index >= 0 && index < size());
  return __value_at(index);
}
羽飞's avatar
羽飞 已提交
165

羽飞's avatar
羽飞 已提交
166 167 168 169
int LeafIndexNodeHandler::max_size() const
{
  return header_.leaf_max_size;
}
L
Longda 已提交
170

羽飞's avatar
羽飞 已提交
171 172 173 174
int LeafIndexNodeHandler::min_size() const
{
  return header_.leaf_max_size - header_.leaf_max_size / 2;
}
L
Longda 已提交
175

羽飞's avatar
羽飞 已提交
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
int LeafIndexNodeHandler::lookup(const KeyComparator &comparator, const char *key, bool *found /* = nullptr */) const
{
  const int size = this->size();
  int i = 0;
  for ( ; i < size; i++) {
    int result = comparator(key, __key_at(i));
    if (0 == result) {
      if (found) {
	*found = true;
      }
      return i;
    }
    if (result < 0) {
      break;
    }
L
Longda 已提交
191
  }
羽飞's avatar
羽飞 已提交
192 193
  if (found) {
    *found = false;
L
Longda 已提交
194
  }
羽飞's avatar
羽飞 已提交
195 196
  return i;
}
L
Longda 已提交
197

羽飞's avatar
羽飞 已提交
198 199 200 201 202 203 204 205 206 207 208 209 210 211
void LeafIndexNodeHandler::insert(int index, const char *key, const char *value)
{
  if (index < size()) {
    memmove(__item_at(index + 1), __item_at(index), (size() - index) * item_size());
  }
  memcpy(__item_at(index), key, key_size());
  memcpy(__item_at(index) + key_size(), value, value_size());
  increase_size(1);
}
void LeafIndexNodeHandler::remove(int index)
{
  assert(index >= 0 && index < size());
  if (index < size() - 1) {
    memmove(__item_at(index), __item_at(index + 1), (size() - index - 1) * item_size());
羽飞's avatar
羽飞 已提交
212
  }
羽飞's avatar
羽飞 已提交
213 214
  increase_size(-1);
}
L
Longda 已提交
215

羽飞's avatar
羽飞 已提交
216 217 218 219 220 221 222 223 224
int LeafIndexNodeHandler::remove(const char *key, const KeyComparator &comparator)
{
  bool found = false;
  int index = lookup(comparator, key, &found);
  if (found) {
    this->remove(index);
    return 1;
  }
  return 0;
羽飞's avatar
羽飞 已提交
225 226
}

羽飞's avatar
羽飞 已提交
227
RC LeafIndexNodeHandler::move_half_to(LeafIndexNodeHandler &other, DiskBufferPool *bp, int file_id)
L
Longda 已提交
228
{
羽飞's avatar
羽飞 已提交
229 230
  const int size = this->size();
  const int move_index = size / 2;
L
Longda 已提交
231

羽飞's avatar
羽飞 已提交
232 233 234 235 236 237 238 239
  memcpy(other.__item_at(0), this->__item_at(move_index), item_size() * (size - move_index));
  other.increase_size(size - move_index);
  this->increase_size(- ( size - move_index));
  return RC::SUCCESS;
}
RC LeafIndexNodeHandler::move_first_to_end(LeafIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool, int file_id)
{
  other.append(__item_at(0));
L
Longda 已提交
240

羽飞's avatar
羽飞 已提交
241 242
  if (size() >= 1) {
    memmove(__item_at(0), __item_at(1), (size() - 1) * item_size() );
L
Longda 已提交
243
  }
羽飞's avatar
羽飞 已提交
244
  increase_size(-1);
羽飞's avatar
羽飞 已提交
245 246 247
  return RC::SUCCESS;
}

羽飞's avatar
羽飞 已提交
248
RC LeafIndexNodeHandler::move_last_to_front(LeafIndexNodeHandler &other, DiskBufferPool *bp, int file_id)
L
Longda 已提交
249
{
羽飞's avatar
羽飞 已提交
250
  other.preappend(__item_at(size() - 1));
L
Longda 已提交
251

羽飞's avatar
羽飞 已提交
252 253 254 255 256 257 258 259 260 261 262
  increase_size(-1);
  return RC::SUCCESS;
}
/**
 * move all items to left page
 */
RC LeafIndexNodeHandler::move_to(LeafIndexNodeHandler &other, DiskBufferPool *bp, int file_id)
{
  memcpy(other.__item_at(other.size()), this->__item_at(0), this->size() * item_size());
  other.increase_size(this->size());
  this->increase_size(- this->size());
L
Longda 已提交
263

羽飞's avatar
羽飞 已提交
264 265 266 267 268 269 270 271 272
  other.set_next_page(this->next_page());

  PageNum next_right_page_num = this->next_page();
  if (next_right_page_num != BP_INVALID_PAGE_NUM) {
    BPPageHandle next_right_page_handle;
    RC rc = bp->get_this_page(file_id, next_right_page_num, &next_right_page_handle);
    if (rc != RC::SUCCESS) {
      LOG_WARN("failed to fetch next right page. page number:%d. rc=%d:%s", next_right_page_num, rc, strrc(rc));
      return rc;
羽飞's avatar
羽飞 已提交
273
    }
L
Longda 已提交
274

羽飞's avatar
羽飞 已提交
275 276 277 278 279
    LeafIndexNodeHandler next_right_node(header_, next_right_page_handle);
    next_right_node.set_prev_page(other.page_num());
    next_right_page_handle.mark_dirty();
    bp->unpin_page(&next_right_page_handle);
  }
L
Longda 已提交
280
  return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
281
}
L
Longda 已提交
282

羽飞's avatar
羽飞 已提交
283
void LeafIndexNodeHandler::append(const char *item)
羽飞's avatar
羽飞 已提交
284
{
羽飞's avatar
羽飞 已提交
285 286 287
  memcpy(__item_at(size()), item, item_size());
  increase_size(1);
}
羽飞's avatar
羽飞 已提交
288

羽飞's avatar
羽飞 已提交
289 290 291 292
void LeafIndexNodeHandler::preappend(const char *item)
{
  if (size() > 0) {
    memmove(__item_at(1), __item_at(0), size() * item_size());
羽飞's avatar
羽飞 已提交
293
  }
羽飞's avatar
羽飞 已提交
294 295 296
  memcpy(__item_at(0), item, item_size());
  increase_size(1);
}
羽飞's avatar
羽飞 已提交
297

羽飞's avatar
羽飞 已提交
298 299 300 301 302 303 304 305 306 307 308 309
char *LeafIndexNodeHandler::__item_at(int index) const
{
  return leaf_node_->array + (index * item_size());
}
char *LeafIndexNodeHandler::__key_at(int index) const
{
  return __item_at(index);
}
char *LeafIndexNodeHandler::__value_at(int index) const
{
  return __item_at(index) + key_size();
}
L
Longda 已提交
310

羽飞's avatar
羽飞 已提交
311 312 313 314 315 316
std::string to_string(const LeafIndexNodeHandler &handler, const KeyPrinter &printer)
{
  std::stringstream ss;
  ss << to_string((const IndexNodeHandler &)handler)
     << ",prev page:" << handler.prev_page()
     << ",next page:" << handler.next_page();
羽飞's avatar
羽飞 已提交
317
  ss << ",values=[" << printer(handler.__key_at(0)) ;
羽飞's avatar
羽飞 已提交
318 319 320 321 322
  for (int i = 1; i < handler.size(); i++) {
    ss << "," << printer(handler.__key_at(i));
  }
  ss << "]";
  return ss.str();
L
Longda 已提交
323 324
}

羽飞's avatar
羽飞 已提交
325
bool LeafIndexNodeHandler::validate(const KeyComparator &comparator, DiskBufferPool *bp, int file_id) const
L
Longda 已提交
326
{
羽飞's avatar
羽飞 已提交
327 328 329 330
  bool result = IndexNodeHandler::validate();
  if (false == result) {
    return false;
  }
L
Longda 已提交
331

羽飞's avatar
羽飞 已提交
332 333 334 335 336 337
  const int node_size = size();
  for (int i = 1; i < node_size; i++) {
    if (comparator(__key_at(i - 1), __key_at(i)) >= 0) {
      LOG_WARN("page number = %d, invalid key order. id1=%d,id2=%d, this=%s",
	       page_num(), i-1, i, to_string(*this).c_str());
      return false;
羽飞's avatar
羽飞 已提交
338 339
    }
  }
L
Longda 已提交
340

羽飞's avatar
羽飞 已提交
341 342 343 344
  PageNum parent_page_num = this->parent_page_num();
  if (parent_page_num == BP_INVALID_PAGE_NUM) {
    return true;
  }
羽飞's avatar
羽飞 已提交
345

羽飞's avatar
羽飞 已提交
346 347 348 349 350 351 352 353 354 355 356 357 358 359
  BPPageHandle parent_page_handle;
  RC rc = bp->get_this_page(file_id, parent_page_num, &parent_page_handle);
  if (rc != RC::SUCCESS) {
    LOG_WARN("failed to fetch parent page. page num=%d, rc=%d:%s",
	     parent_page_num, rc, strrc(rc));
    return false;
  }

  InternalIndexNodeHandler parent_node(header_, parent_page_handle);
  int index_in_parent = parent_node.value_index(this->page_num());
  if (index_in_parent < 0) {
    LOG_WARN("invalid leaf node. cannot find index in parent. this page num=%d, parent page num=%d",
	     this->page_num(), parent_page_num);
    bp->unpin_page(&parent_page_handle);
L
Longda 已提交
360 361
    return false;
  }
羽飞's avatar
羽飞 已提交
362 363 364 365 366 367 368 369

  if (0 != index_in_parent) {
    int cmp_result = comparator(__key_at(0), parent_node.key_at(index_in_parent));
    if (cmp_result < 0) {
      LOG_WARN("invalid leaf node. first item should be greate than or equal to parent item. " \
	       "this page num=%d, parent page num=%d, index in parent=%d",
	       this->page_num(), parent_node.page_num(), index_in_parent);
      bp->unpin_page(&parent_page_handle);
L
Longda 已提交
370 371
      return false;
    }
羽飞's avatar
羽飞 已提交
372
  }
羽飞's avatar
羽飞 已提交
373

羽飞's avatar
羽飞 已提交
374 375 376 377 378 379 380 381
  if (index_in_parent < parent_node.size() - 1) {
    int cmp_result = comparator(__key_at(size() - 1), parent_node.key_at(index_in_parent + 1));
    if (cmp_result >= 0) {
      LOG_WARN("invalid leaf node. last item should be less than the item at the first after item in parent." \
	       "this page num=%d, parent page num=%d, parent item to compare=%d",
	       this->page_num(), parent_node.page_num(), index_in_parent + 1);
      bp->unpin_page(&parent_page_handle);
      return false;
L
Longda 已提交
382
    }
羽飞's avatar
羽飞 已提交
383
  }
羽飞's avatar
羽飞 已提交
384 385 386
  bp->unpin_page(&parent_page_handle);
  return true;
}
羽飞's avatar
羽飞 已提交
387

羽飞's avatar
羽飞 已提交
388 389 390 391
/////////////////////////////////////////////////////////////////////////////////
InternalIndexNodeHandler::InternalIndexNodeHandler(const IndexFileHeader &header, BPPageHandle &page_handle)
  : IndexNodeHandler(header, page_handle), internal_node_((InternalIndexNode *)page_handle.data())
{}
L
Longda 已提交
392

羽飞's avatar
羽飞 已提交
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
std::string to_string(const InternalIndexNodeHandler &node, const KeyPrinter &printer)
{
  std::stringstream ss;
  ss << to_string((const IndexNodeHandler &)node);
  ss << ",children:["
     << "{key:" << printer(node.__key_at(0)) << ","
     << "value:" << *(PageNum *)node.__value_at(0) << "}";

  for (int i = 1; i < node.size(); i++) {
    ss << ",{key:" << printer(node.__key_at(i))
       << ",value:"<< *(PageNum *)node.__value_at(i) << "}";
  }
  ss << "]";
  return ss.str();
}
L
Longda 已提交
408

羽飞's avatar
羽飞 已提交
409 410 411 412 413 414 415 416 417 418 419 420
void InternalIndexNodeHandler::init_empty()
{
  IndexNodeHandler::init_empty(false);
}
void InternalIndexNodeHandler::create_new_root(PageNum first_page_num, const char *key, PageNum page_num)
{
  memset(__key_at(0), 0, key_size());
  memcpy(__value_at(0), &first_page_num, value_size());
  memcpy(__item_at(1), key, key_size());
  memcpy(__value_at(1), &page_num, value_size());
  increase_size(2);
}
L
Longda 已提交
421

羽飞's avatar
羽飞 已提交
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
/**
 * insert one entry
 * the entry to be inserted will never at the first slot.
 * the right child page after split will always have bigger keys.
 */
void InternalIndexNodeHandler::insert(const char *key, PageNum page_num, const KeyComparator &comparator)
{
  int insert_position = -1;
  lookup(comparator, key, nullptr, &insert_position);
  if (insert_position < size()) {
    memmove(__item_at(insert_position + 1), __item_at(insert_position), (size() - insert_position) * item_size());
  }
  memcpy(__item_at(insert_position), key, key_size());
  memcpy(__value_at(insert_position), &page_num, value_size());
  increase_size(1);
}
羽飞's avatar
羽飞 已提交
438

羽飞's avatar
羽飞 已提交
439 440 441 442 443 444 445 446
RC InternalIndexNodeHandler::move_half_to(InternalIndexNodeHandler &other, DiskBufferPool *bp, int file_id)
{
  const int size = this->size();
  const int move_index = size / 2;
  RC rc = other.copy_from(this->__item_at(move_index), size - move_index, bp, file_id);
  if (rc != RC::SUCCESS) {
    LOG_WARN("failed to copy item to new node. rc=%d:%s", rc, strrc(rc));
    return rc;
羽飞's avatar
羽飞 已提交
447
  }
L
Longda 已提交
448

羽飞's avatar
羽飞 已提交
449 450 451
  increase_size(- (size - move_index));
  return rc;
}
L
Longda 已提交
452

羽飞's avatar
羽飞 已提交
453 454 455 456
int InternalIndexNodeHandler::max_size() const
{
  return header_.internal_max_size;
}
L
Longda 已提交
457

羽飞's avatar
羽飞 已提交
458 459 460 461
int InternalIndexNodeHandler::min_size() const
{
  return header_.internal_max_size - header_.internal_max_size / 2;
}
L
Longda 已提交
462

羽飞's avatar
羽飞 已提交
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
/**
 * lookup the first item which key <= item
 * @return unlike the leafNode, the return value is not the insert position,
 * but only the index of child to find. 
 */
int InternalIndexNodeHandler::lookup(const KeyComparator &comparator, const char *key,
				     bool *found /* = nullptr */, int *insert_position /*= nullptr */) const
{
  int i = 1;
  const int size = this->size();
  for ( ; i < size; i++) {
    int result = comparator(key, __key_at(i));
    if (result == 0) {
      if (found) {
	*found = true;
L
Longda 已提交
478
      }
羽飞's avatar
羽飞 已提交
479 480
      if (insert_position) {
	*insert_position = i;
L
Longda 已提交
481
      }
羽飞's avatar
羽飞 已提交
482
      return i;
L
Longda 已提交
483
    }
羽飞's avatar
羽飞 已提交
484 485 486
    if (result < 0) {
      if (found) {
	*found = false;
L
Longda 已提交
487
      }
羽飞's avatar
羽飞 已提交
488 489
      if (insert_position) {
	*insert_position = i;
L
Longda 已提交
490
      }
羽飞's avatar
羽飞 已提交
491 492

      return i - 1;
羽飞's avatar
羽飞 已提交
493 494
    }
  }
羽飞's avatar
羽飞 已提交
495 496 497 498 499 500 501 502
  if (found) {
    *found = false;
  }
  if (insert_position) {
    *insert_position = size;
  }
  return size - 1;
}
L
Longda 已提交
503

羽飞's avatar
羽飞 已提交
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550
char *InternalIndexNodeHandler::key_at(int index)
{
  assert(index >= 0 && index < size());
  return __key_at(index);
}

void InternalIndexNodeHandler::set_key_at(int index, const char *key)
{
  assert(index >= 0 && index < size());
  memcpy(__key_at(index), key, key_size());
}

PageNum InternalIndexNodeHandler::value_at(int index)
{
  assert(index >= 0 && index < size());
  return *(PageNum *)__value_at(index);
}

int InternalIndexNodeHandler::value_index(PageNum page_num)
{
  for (int i = 0; i < size(); i++) {
    if (page_num == *(PageNum*)__value_at(i)) {
      return i;
    }
  }
  return -1;
}

void InternalIndexNodeHandler::remove(int index)
{
  assert(index >= 0 && index < size());
  if (index < size() - 1) {
    memmove(__item_at(index), __item_at(index + 1), (size() - index - 1) * item_size());
  }
  increase_size(-1);
}

RC InternalIndexNodeHandler::move_to(InternalIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool, int file_id)
{
  RC rc = other.copy_from(__item_at(0), size(), disk_buffer_pool, file_id);
  if (rc != RC::SUCCESS) {
    LOG_WARN("failed to copy items to other node. rc=%d:%s", rc, strrc(rc));
    return rc;
  }

  increase_size(- this->size());
  return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
551 552
}

羽飞's avatar
羽飞 已提交
553
RC InternalIndexNodeHandler::move_first_to_end(InternalIndexNodeHandler &other, DiskBufferPool *disk_buffer_pool, int file_id)
L
Longda 已提交
554
{
羽飞's avatar
羽飞 已提交
555 556 557 558
  RC rc = other.append(__item_at(0), disk_buffer_pool, file_id);
  if (rc != RC::SUCCESS) {
    LOG_WARN("failed to append item to others.");
    return rc;
L
Longda 已提交
559 560
  }

羽飞's avatar
羽飞 已提交
561 562
  if (size() >= 1) {
    memmove(__item_at(0), __item_at(1), (size() - 1) * item_size() );
羽飞's avatar
羽飞 已提交
563
  }
羽飞's avatar
羽飞 已提交
564 565 566
  increase_size(-1);
  return rc;
}
羽飞's avatar
羽飞 已提交
567

羽飞's avatar
羽飞 已提交
568 569 570 571 572 573
RC InternalIndexNodeHandler::move_last_to_front(InternalIndexNodeHandler &other, DiskBufferPool *bp, int file_id)
{
  RC rc = other.preappend(__item_at(size() - 1), bp, file_id);
  if (rc != RC::SUCCESS) {
    LOG_WARN("failed to preappend to others");
    return rc;
羽飞's avatar
羽飞 已提交
574 575
  }

羽飞's avatar
羽飞 已提交
576 577 578 579 580 581 582 583 584
  increase_size(-1);
  return rc;
}
/**
 * copy items from other node to self's right
 */
RC InternalIndexNodeHandler::copy_from(const char *items, int num, DiskBufferPool *disk_buffer_pool, int file_id)
{
  memcpy(__item_at(this->size()), items, num * item_size());
羽飞's avatar
羽飞 已提交
585

羽飞's avatar
羽飞 已提交
586 587 588 589 590 591
  RC rc = RC::SUCCESS;
  PageNum this_page_num = this->page_num();
  BPPageHandle page_handle;
  for (int i = 0; i < num; i++) {
    const PageNum page_num = *(const PageNum *)((items + i * item_size()) + key_size());
    rc = disk_buffer_pool->get_this_page(file_id, page_num, &page_handle);
L
Longda 已提交
592
    if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
593 594 595
      LOG_WARN("failed to set child's page num. child page num:%d, this page num=%d, rc=%d:%s",
	       page_num, this_page_num, rc, strrc(rc));
      return rc;
L
Longda 已提交
596
    }
羽飞's avatar
羽飞 已提交
597 598 599 600
    IndexNodeHandler child_node(header_, page_handle);
    child_node.set_parent_page_num(this_page_num);
    page_handle.mark_dirty();
    disk_buffer_pool->unpin_page(&page_handle);
羽飞's avatar
羽飞 已提交
601
  }
羽飞's avatar
羽飞 已提交
602 603 604
  increase_size(num);
  return rc;
}
羽飞's avatar
羽飞 已提交
605

羽飞's avatar
羽飞 已提交
606 607 608 609
RC InternalIndexNodeHandler::append(const char *item, DiskBufferPool *bp, int file_id)
{
  return this->copy_from(item, 1, bp, file_id);
}
羽飞's avatar
羽飞 已提交
610

羽飞's avatar
羽飞 已提交
611 612 613 614 615 616 617 618
RC InternalIndexNodeHandler::preappend(const char *item, DiskBufferPool *bp, int file_id)
{
  PageNum child_page_num = *(PageNum *)(item + key_size());
  BPPageHandle page_handle;
  RC rc = bp->get_this_page(file_id, child_page_num, &page_handle);
  if (rc != RC::SUCCESS) {
    LOG_WARN("failed to fetch child page. rc=%d:%s", rc, strrc(rc));
    return rc;
羽飞's avatar
羽飞 已提交
619 620
  }

羽飞's avatar
羽飞 已提交
621 622
  IndexNodeHandler child_node(header_, page_handle);
  child_node.set_parent_page_num(this->page_num());
羽飞's avatar
羽飞 已提交
623

羽飞's avatar
羽飞 已提交
624 625
  page_handle.mark_dirty();
  bp->unpin_page(&page_handle);
羽飞's avatar
羽飞 已提交
626

羽飞's avatar
羽飞 已提交
627 628 629
  if (this->size() > 0) {
    memmove(__item_at(1), __item_at(0), this->size() * item_size());
  }
羽飞's avatar
羽飞 已提交
630

羽飞's avatar
羽飞 已提交
631 632 633 634
  memcpy(__item_at(0), item, item_size());
  increase_size(1);
  return RC::SUCCESS;
}
羽飞's avatar
羽飞 已提交
635

羽飞's avatar
羽飞 已提交
636 637 638 639
char *InternalIndexNodeHandler::__item_at(int index) const
{
  return internal_node_->array + (index * item_size());
}
羽飞's avatar
羽飞 已提交
640

羽飞's avatar
羽飞 已提交
641 642 643 644
char *InternalIndexNodeHandler::__key_at(int index) const
{
  return __item_at(index);
}
L
Longda 已提交
645

羽飞's avatar
羽飞 已提交
646 647 648 649
char *InternalIndexNodeHandler::__value_at(int index) const
{
  return __item_at(index) + key_size();
}
L
Longda 已提交
650

羽飞's avatar
羽飞 已提交
651 652 653 654
int InternalIndexNodeHandler::value_size() const
{
  return sizeof(PageNum);
}
L
Longda 已提交
655

羽飞's avatar
羽飞 已提交
656 657 658 659
int InternalIndexNodeHandler::item_size() const
{
  return key_size() + this->value_size();
}
羽飞's avatar
羽飞 已提交
660

羽飞's avatar
羽飞 已提交
661 662 663 664 665
bool InternalIndexNodeHandler::validate(const KeyComparator &comparator, DiskBufferPool *bp, int file_id) const
{
  bool result = IndexNodeHandler::validate();
  if (false == result) {
    return false;
羽飞's avatar
羽飞 已提交
666 667
  }

羽飞's avatar
羽飞 已提交
668 669 670 671 672 673 674
  const int node_size = size();
  for (int i = 2; i < node_size; i++) {
    if (comparator(__key_at(i - 1), __key_at(i)) >= 0) {
      LOG_WARN("page number = %d, invalid key order. id1=%d,id2=%d, this=%s",
	       page_num(), i-1, i, to_string(*this).c_str());
      return false;
    }
羽飞's avatar
羽飞 已提交
675 676
  }

羽飞's avatar
羽飞 已提交
677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696
  for (int i = 0; result && i < node_size; i++) {
    PageNum page_num = *(PageNum *)__value_at(i);
    if (page_num < 0) {
      LOG_WARN("this page num=%d, got invalid child page. page num=%d", this->page_num(), page_num);
    } else {
      BPPageHandle child_page_handle;
      RC rc = bp->get_this_page(file_id, page_num, &child_page_handle);
      if (rc != RC::SUCCESS) {
	LOG_WARN("failed to fetch child page while validate internal page. page num=%d, rc=%d:%s",
		 page_num, rc, strrc(rc));
      } else {
	IndexNodeHandler child_node(header_, child_page_handle);
	if (child_node.parent_page_num() != this->page_num()) {
	  LOG_WARN("child's parent page num is invalid. child page num=%d, parent page num=%d, this page num=%d",
		   child_node.page_num(), child_node.parent_page_num(), this->page_num());
	  result = false;
	}
	bp->unpin_page(&child_page_handle);
      }
    }
羽飞's avatar
羽飞 已提交
697
  }
L
Longda 已提交
698

羽飞's avatar
羽飞 已提交
699 700
  if (!result) {
    return result;
羽飞's avatar
羽飞 已提交
701 702
  }

羽飞's avatar
羽飞 已提交
703 704 705 706
  const PageNum parent_page_num = this->parent_page_num();
  if (parent_page_num == BP_INVALID_PAGE_NUM) {
    return result;
  }
L
Longda 已提交
707

羽飞's avatar
羽飞 已提交
708 709 710 711
  BPPageHandle parent_page_handle;
  RC rc = bp->get_this_page(file_id, parent_page_num, &parent_page_handle);
  if (rc != RC::SUCCESS) {
    LOG_WARN("failed to fetch parent page. page num=%d, rc=%d:%s", parent_page_num, rc, strrc(rc));
L
Longda 已提交
712
    return false;
羽飞's avatar
羽飞 已提交
713 714
  }

羽飞's avatar
羽飞 已提交
715 716 717 718 719 720 721 722
  InternalIndexNodeHandler parent_node(header_, parent_page_handle);
  int index_in_parent = parent_node.value_index(this->page_num());
  if (index_in_parent < 0) {
    LOG_WARN("invalid internal node. cannot find index in parent. this page num=%d, parent page num=%d",
	     this->page_num(), parent_page_num);
    bp->unpin_page(&parent_page_handle);
    return false;
  }
羽飞's avatar
羽飞 已提交
723

羽飞's avatar
羽飞 已提交
724 725 726 727 728 729 730 731
  if (0 != index_in_parent) {
    int cmp_result = comparator(__key_at(1), parent_node.key_at(index_in_parent));
    if (cmp_result < 0) {
      LOG_WARN("invalid internal node. the second item should be greate than or equal to parent item. " \
	       "this page num=%d, parent page num=%d, index in parent=%d",
	       this->page_num(), parent_node.page_num(), index_in_parent);
      bp->unpin_page(&parent_page_handle);
      return false;
L
Longda 已提交
732
    }
羽飞's avatar
羽飞 已提交
733
  }
L
Longda 已提交
734

羽飞's avatar
羽飞 已提交
735 736 737 738 739 740 741 742 743
  if (index_in_parent < parent_node.size() - 1) {
    int cmp_result = comparator(__key_at(size() - 1), parent_node.key_at(index_in_parent + 1));
    if (cmp_result >= 0) {
      LOG_WARN("invalid internal node. last item should be less than the item at the first after item in parent." \
	       "this page num=%d, parent page num=%d, parent item to compare=%d",
	       this->page_num(), parent_node.page_num(), index_in_parent + 1);
      bp->unpin_page(&parent_page_handle);
      return false;
    }
羽飞's avatar
羽飞 已提交
744
  }
羽飞's avatar
羽飞 已提交
745
  bp->unpin_page(&parent_page_handle);
羽飞's avatar
羽飞 已提交
746

羽飞's avatar
羽飞 已提交
747
  return result;
L
Longda 已提交
748
}
羽飞's avatar
羽飞 已提交
749

羽飞's avatar
羽飞 已提交
750
/////////////////////////////////////////////////////////////////////////////////
羽飞's avatar
羽飞 已提交
751

羽飞's avatar
羽飞 已提交
752 753 754
RC BplusTreeHandler::sync()
{
  return disk_buffer_pool_->purge_all_pages(file_id_);
L
Longda 已提交
755 756
}

羽飞's avatar
羽飞 已提交
757 758
RC BplusTreeHandler::create(const char *file_name, AttrType attr_type, int attr_length,
			    int internal_max_size /* = -1*/, int leaf_max_size /* = -1 */)
L
Longda 已提交
759
{
羽飞's avatar
羽飞 已提交
760 761
  DiskBufferPool *disk_buffer_pool = theGlobalDiskBufferPool();
  RC rc = disk_buffer_pool->create_file(file_name);
L
Longda 已提交
762
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
763
    LOG_WARN("Failed to create file. file name=%s, rc=%d:%s", file_name, rc, strrc(rc));
L
Longda 已提交
764
    return rc;
羽飞's avatar
羽飞 已提交
765
  }
羽飞's avatar
羽飞 已提交
766
  LOG_INFO("Successfully create index file:%s", file_name);
羽飞's avatar
羽飞 已提交
767

羽飞's avatar
羽飞 已提交
768 769
  int file_id;
  rc = disk_buffer_pool->open_file(file_name, &file_id);
L
Longda 已提交
770
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
771
    LOG_WARN("Failed to open file. file name=%s, rc=%d:%s", file_name, rc, strrc(rc));
L
Longda 已提交
772 773
    return rc;
  }
羽飞's avatar
羽飞 已提交
774 775 776 777
  LOG_INFO("Successfully open index file %s.", file_name);

  BPPageHandle header_page_handle;
  rc = disk_buffer_pool->allocate_page(file_id, &header_page_handle);
L
Longda 已提交
778
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
779 780
    LOG_WARN("failed to allocate header page for bplus tree. rc=%d:%s", rc, strrc(rc));
    disk_buffer_pool->close_file(file_id);
L
Longda 已提交
781 782
    return rc;
  }
羽飞's avatar
羽飞 已提交
783

羽飞's avatar
羽飞 已提交
784 785 786 787 788 789
  if (header_page_handle.page_num() != FIRST_INDEX_PAGE) {
    LOG_WARN("header page num should be %d but got %d. is it a new file : %s",
	     FIRST_INDEX_PAGE, header_page_handle.page_num(), file_name);
    disk_buffer_pool->close_file(file_id);
    return RC::INTERNAL;
  }
羽飞's avatar
羽飞 已提交
790

羽飞's avatar
羽飞 已提交
791 792
  if (internal_max_size < 0) {
    internal_max_size = calc_internal_page_capacity(attr_length);
羽飞's avatar
羽飞 已提交
793
  }
羽飞's avatar
羽飞 已提交
794 795 796 797 798 799 800 801 802 803 804
  if (leaf_max_size < 0) {
    leaf_max_size = calc_leaf_page_capacity(attr_length);
  }
  char *pdata = header_page_handle.data();
  IndexFileHeader *file_header = (IndexFileHeader *)pdata;
  file_header->attr_length = attr_length;
  file_header->key_length = attr_length + sizeof(RID);
  file_header->attr_type = attr_type;
  file_header->internal_max_size = internal_max_size;
  file_header->leaf_max_size = leaf_max_size;
  file_header->root_page = BP_INVALID_PAGE_NUM;
羽飞's avatar
羽飞 已提交
805

羽飞's avatar
羽飞 已提交
806 807
  header_page_handle.mark_dirty();
  disk_buffer_pool->unpin_page(&header_page_handle);
羽飞's avatar
羽飞 已提交
808

羽飞's avatar
羽飞 已提交
809 810
  disk_buffer_pool_ = disk_buffer_pool;
  file_id_ = file_id;
羽飞's avatar
羽飞 已提交
811

羽飞's avatar
羽飞 已提交
812 813
  memcpy(&file_header_, pdata, sizeof(file_header_));
  header_dirty_ = false;
L
Longda 已提交
814

羽飞's avatar
羽飞 已提交
815 816 817 818 819 820
  mem_pool_item_ = new common::MemPoolItem(file_name);
  if (mem_pool_item_->init(file_header->key_length) < 0) {
    LOG_WARN("Failed to init memory pool for index %s", file_name);
    close();
    return RC::NOMEM;
  }
L
Longda 已提交
821

羽飞's avatar
羽飞 已提交
822 823 824
  key_comparator_.init(file_header->attr_type, file_header->attr_length);
  key_printer_.init(file_header->attr_type, file_header->attr_length);
  LOG_INFO("Successfully create index %s", file_name);
L
Longda 已提交
825 826 827
  return RC::SUCCESS;
}

羽飞's avatar
羽飞 已提交
828
RC BplusTreeHandler::open(const char *file_name)
L
Longda 已提交
829
{
羽飞's avatar
羽飞 已提交
830 831 832 833
  if (file_id_ >= 0) {
    LOG_WARN("%s has been opened before index.open.", file_name);
    return RC::RECORD_OPENNED;
  }
L
Longda 已提交
834

羽飞's avatar
羽飞 已提交
835 836 837
  DiskBufferPool *disk_buffer_pool = theGlobalDiskBufferPool();
  int file_id = 0;
  RC rc = disk_buffer_pool->open_file(file_name, &file_id);
L
Longda 已提交
838
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
839
    LOG_WARN("Failed to open file name=%s, rc=%d:%s", file_name, rc, strrc(rc));
羽飞's avatar
羽飞 已提交
840 841
    return rc;
  }
L
Longda 已提交
842

羽飞's avatar
羽飞 已提交
843 844
  BPPageHandle page_handle;
  rc = disk_buffer_pool->get_this_page(file_id, FIRST_INDEX_PAGE, &page_handle);
L
Longda 已提交
845
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
846 847
    LOG_WARN("Failed to get first page file name=%s, rc=%d:%s", file_name, rc, strrc(rc));
    disk_buffer_pool_->close_file(file_id);
羽飞's avatar
羽飞 已提交
848 849
    return rc;
  }
L
Longda 已提交
850

羽飞's avatar
羽飞 已提交
851 852 853 854 855
  char *pdata = page_handle.data();
  memcpy(&file_header_, pdata, sizeof(IndexFileHeader));
  header_dirty_ = false;
  disk_buffer_pool_ = disk_buffer_pool;
  file_id_ = file_id;
羽飞's avatar
羽飞 已提交
856

羽飞's avatar
羽飞 已提交
857 858 859 860 861 862
  mem_pool_item_ = new common::MemPoolItem(file_name);
  if (mem_pool_item_->init(file_header_.key_length) < 0) {
    LOG_WARN("Failed to init memory pool for index %s", file_name);
    close();
    return RC::NOMEM;
  }
L
Longda 已提交
863

羽飞's avatar
羽飞 已提交
864 865
  // close old page_handle
  disk_buffer_pool->unpin_page(&page_handle);
L
Longda 已提交
866

羽飞's avatar
羽飞 已提交
867 868 869
  key_comparator_.init(file_header_.attr_type, file_header_.attr_length);
  LOG_INFO("Successfully open index %s", file_name);
  return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
870 871
}

羽飞's avatar
羽飞 已提交
872
RC BplusTreeHandler::close()
L
Longda 已提交
873
{
羽飞's avatar
羽飞 已提交
874
  if (file_id_ != -1) {
L
Longda 已提交
875

羽飞's avatar
羽飞 已提交
876 877
    disk_buffer_pool_->close_file(file_id_);
    file_id_ = -1;
L
Longda 已提交
878

羽飞's avatar
羽飞 已提交
879 880
    delete mem_pool_item_;
    mem_pool_item_ = nullptr;
羽飞's avatar
羽飞 已提交
881
  }
L
Longda 已提交
882

羽飞's avatar
羽飞 已提交
883 884
  disk_buffer_pool_ = nullptr;
  return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
885 886
}

羽飞's avatar
羽飞 已提交
887
RC BplusTreeHandler::print_leaf(BPPageHandle &page_handle)
L
Longda 已提交
888
{
羽飞's avatar
羽飞 已提交
889 890 891 892
  LeafIndexNodeHandler leaf_node(file_header_, page_handle);
  LOG_INFO("leaf node: %s", to_string(leaf_node, key_printer_).c_str());
  disk_buffer_pool_->unpin_page(&page_handle);
  return RC::SUCCESS;
L
Longda 已提交
893 894
}

羽飞's avatar
羽飞 已提交
895
RC BplusTreeHandler::print_internal_node_recursive(BPPageHandle &page_handle)
L
Longda 已提交
896
{
羽飞's avatar
羽飞 已提交
897 898 899 900 901 902 903 904 905 906 907 908 909 910 911
  RC rc = RC::SUCCESS;
  LOG_INFO("bplus tree. file header: %s", file_header_.to_string().c_str());
  InternalIndexNodeHandler internal_node(file_header_, page_handle);
  LOG_INFO("internal node: %s", to_string(internal_node, key_printer_).c_str());

  int node_size = internal_node.size();
  for (int i = 0; i < node_size; i++) {
    PageNum page_num = internal_node.value_at(i);
    BPPageHandle child_page_handle;
    rc = disk_buffer_pool_->get_this_page(file_id_, page_num, &child_page_handle);
    if (rc != RC::SUCCESS) {
      LOG_WARN("failed to fetch child page. page id=%d, rc=%d:%s", page_num, rc, strrc(rc));
      disk_buffer_pool_->unpin_page(&page_handle);
      return rc;
    }
羽飞's avatar
羽飞 已提交
912

羽飞's avatar
羽飞 已提交
913 914 915 916 917 918 919 920 921 922 923 924
    IndexNodeHandler node(file_header_, child_page_handle);
    if (node.is_leaf()) {
      rc = print_leaf(child_page_handle);
    } else {
      rc = print_internal_node_recursive(child_page_handle);
    }
    if (rc != RC::SUCCESS) {
      LOG_WARN("failed to print node. page id=%d, rc=%d:%s", child_page_handle.page_num(), rc, strrc(rc));
      disk_buffer_pool_->unpin_page(&page_handle);
      return rc;
    }
  }
羽飞's avatar
羽飞 已提交
925

羽飞's avatar
羽飞 已提交
926
  disk_buffer_pool_->unpin_page(&page_handle);
L
Longda 已提交
927 928 929
  return RC::SUCCESS;
}

羽飞's avatar
羽飞 已提交
930
RC BplusTreeHandler::print_tree()
L
Longda 已提交
931 932
{
  if (file_id_ < 0) {
羽飞's avatar
羽飞 已提交
933 934
    LOG_WARN("Index hasn't been created or opened, fail to print");
    return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
935
  }
羽飞's avatar
羽飞 已提交
936 937 938
  if (is_empty()) {
    LOG_INFO("tree is empty");
    return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
939 940
  }

羽飞's avatar
羽飞 已提交
941 942 943 944 945 946 947 948 949 950 951 952 953
  BPPageHandle page_handle;
  PageNum page_num = file_header_.root_page;
  RC rc = disk_buffer_pool_->get_this_page(file_id_, page_num, &page_handle);
  if (rc != RC::SUCCESS) {
    LOG_WARN("failed to fetch page. page id=%d, rc=%d:%s", page_num, rc, strrc(rc));
    return rc;
  }
  
  IndexNodeHandler node(file_header_, page_handle);
  if (node.is_leaf()) {
    rc = print_leaf(page_handle);
  } else {
    rc = print_internal_node_recursive(page_handle);
羽飞's avatar
羽飞 已提交
954
  }
羽飞's avatar
羽飞 已提交
955 956
  return rc;
}
L
Longda 已提交
957

羽飞's avatar
羽飞 已提交
958 959 960 961 962
RC BplusTreeHandler::print_leafs()
{
  if (is_empty()) {
    LOG_INFO("empty tree");
    return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
963 964
  }

L
Longda 已提交
965
  BPPageHandle page_handle;
羽飞's avatar
羽飞 已提交
966 967
  
  RC rc = left_most_page(page_handle);
L
Longda 已提交
968
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
969
    LOG_WARN("failed to get left most page. rc=%d:%s", rc, strrc(rc));
羽飞's avatar
羽飞 已提交
970 971
    return rc;
  }
L
Longda 已提交
972

羽飞's avatar
羽飞 已提交
973 974 975
  while (page_handle.page_num() != BP_INVALID_PAGE_NUM) {
    LeafIndexNodeHandler leaf_node(file_header_, page_handle);
    LOG_INFO("leaf info: %s", to_string(leaf_node, key_printer_).c_str());
L
Longda 已提交
976

羽飞's avatar
羽飞 已提交
977
    PageNum next_page_num = leaf_node.next_page();
L
Longda 已提交
978
    disk_buffer_pool_->unpin_page(&page_handle);
羽飞's avatar
羽飞 已提交
979

羽飞's avatar
羽飞 已提交
980 981 982
    if (next_page_num == BP_INVALID_PAGE_NUM) {
      break;
    }
L
Longda 已提交
983

羽飞's avatar
羽飞 已提交
984
    rc = disk_buffer_pool_->get_this_page(file_id_, next_page_num, &page_handle);
L
Longda 已提交
985
    if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
986
      LOG_WARN("failed to get next page. page id=%d, rc=%d:%s", next_page_num, rc, strrc(rc));
L
Longda 已提交
987 988
      return rc;
    }
羽飞's avatar
羽飞 已提交
989
  }
羽飞's avatar
羽飞 已提交
990
  return rc;
L
Longda 已提交
991 992
}

羽飞's avatar
羽飞 已提交
993
bool BplusTreeHandler::validate_node_recursive(BPPageHandle &page_handle)
L
Longda 已提交
994
{
羽飞's avatar
羽飞 已提交
995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009
  bool result = true;
  IndexNodeHandler node(file_header_, page_handle);
  if (node.is_leaf()) {
    LeafIndexNodeHandler leaf_node(file_header_, page_handle);
    result = leaf_node.validate(key_comparator_, disk_buffer_pool_, file_id_);
  } else {
    InternalIndexNodeHandler internal_node(file_header_, page_handle);
    result = internal_node.validate(key_comparator_, disk_buffer_pool_, file_id_);
    for (int i = 0; result && i < internal_node.size(); i++) {
      PageNum page_num = internal_node.value_at(i);
      BPPageHandle child_page_handle;
      RC rc = disk_buffer_pool_->get_this_page(file_id_, page_num, &child_page_handle);
      if (rc != RC::SUCCESS) {
        LOG_WARN("failed to fetch child page.page id=%d, rc=%d:%s", page_num, rc, strrc(rc));
        result = false;
L
Longda 已提交
1010 1011
        break;
      }
羽飞's avatar
羽飞 已提交
1012 1013

      result = validate_node_recursive(child_page_handle);
L
Longda 已提交
1014
    }
羽飞's avatar
羽飞 已提交
1015
  }
羽飞's avatar
羽飞 已提交
1016 1017 1018

  disk_buffer_pool_->unpin_page(&page_handle);
  return result;
羽飞's avatar
羽飞 已提交
1019 1020
}

羽飞's avatar
羽飞 已提交
1021
bool BplusTreeHandler::validate_leaf_link()
L
Longda 已提交
1022
{
羽飞's avatar
羽飞 已提交
1023 1024
  if (is_empty()) {
    return true;
羽飞's avatar
羽飞 已提交
1025
  }
L
Longda 已提交
1026

羽飞's avatar
羽飞 已提交
1027 1028 1029 1030 1031
  BPPageHandle page_handle;
  RC rc = left_most_page(page_handle);
  if (rc != RC::SUCCESS) {
    LOG_WARN("failed to fetch left most page. rc=%d:%s", rc, strrc(rc));
    return false;
羽飞's avatar
羽飞 已提交
1032 1033
  }

羽飞's avatar
羽飞 已提交
1034
  PageNum prev_page_num = BP_INVALID_PAGE_NUM;
羽飞's avatar
羽飞 已提交
1035

羽飞's avatar
羽飞 已提交
1036 1037 1038 1039 1040 1041 1042
  LeafIndexNodeHandler leaf_node(file_header_, page_handle);
  if (leaf_node.prev_page() != prev_page_num) {
    LOG_WARN("invalid page. current_page_num=%d, prev page num should be %d but got %d",
  	       page_handle.page_num(), prev_page_num, leaf_node.prev_page());
    return false;
  }
  PageNum next_page_num = leaf_node.next_page();
羽飞's avatar
羽飞 已提交
1043

羽飞's avatar
羽飞 已提交
1044 1045 1046 1047
  prev_page_num = page_handle.page_num();
  char *prev_key = (char *)mem_pool_item_->alloc();
  memcpy(prev_key, leaf_node.key_at(leaf_node.size() - 1), file_header_.key_length);
  disk_buffer_pool_->unpin_page(&page_handle);
L
Longda 已提交
1048

羽飞's avatar
羽飞 已提交
1049 1050 1051
  bool result = true;
  while (result && next_page_num != BP_INVALID_PAGE_NUM) {
    rc = disk_buffer_pool_->get_this_page(file_id_, next_page_num, &page_handle);
L
Longda 已提交
1052
    if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1053 1054
      LOG_WARN("failed to fetch next page. page num=%d, rc=%d:%s", next_page_num, rc, strrc(rc));
      return false;
羽飞's avatar
羽飞 已提交
1055
    }
L
Longda 已提交
1056

羽飞's avatar
羽飞 已提交
1057 1058 1059 1060 1061
    LeafIndexNodeHandler leaf_node(file_header_, page_handle);
    if (leaf_node.prev_page() != prev_page_num) {
      LOG_WARN("invalid page. current_page_num=%d, prev page num should be %d but got %d",
	       page_handle.page_num(), prev_page_num, leaf_node.prev_page());
      result = false;
L
Longda 已提交
1062
    }
羽飞's avatar
羽飞 已提交
1063 1064 1065
    if (key_comparator_(prev_key, leaf_node.key_at(0)) >= 0) {
      LOG_WARN("invalid page. current first key is not bigger than last");
      result = false;
羽飞's avatar
羽飞 已提交
1066 1067
    }

羽飞's avatar
羽飞 已提交
1068 1069 1070
    next_page_num = leaf_node.next_page();
    memcpy(prev_key, leaf_node.key_at(leaf_node.size() - 1), file_header_.key_length);
    prev_page_num = page_handle.page_num();
L
Longda 已提交
1071
    disk_buffer_pool_->unpin_page(&page_handle);
羽飞's avatar
羽飞 已提交
1072
  }
羽飞's avatar
羽飞 已提交
1073 1074 1075 1076

  free_key(prev_key);
  // can do more things
  return result;
羽飞's avatar
羽飞 已提交
1077 1078
}

羽飞's avatar
羽飞 已提交
1079
bool BplusTreeHandler::validate_tree()
L
Longda 已提交
1080
{
羽飞's avatar
羽飞 已提交
1081 1082
  if (is_empty()) {
    return true;
羽飞's avatar
羽飞 已提交
1083
  }
L
Longda 已提交
1084

羽飞's avatar
羽飞 已提交
1085 1086
  BPPageHandle page_handle;
  RC rc = disk_buffer_pool_->get_this_page(file_id_, file_header_.root_page, &page_handle);
L
Longda 已提交
1087
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1088
    LOG_WARN("failed to fetch root page. page id=%d, rc=%d:%s", file_header_.root_page, rc, strrc(rc));
羽飞's avatar
羽飞 已提交
1089 1090 1091
    return rc;
  }

羽飞's avatar
羽飞 已提交
1092 1093
  if (!validate_node_recursive(page_handle) || !validate_leaf_link()) {
    LOG_WARN("Current B+ Tree is invalid");
L
Longda 已提交
1094
    print_tree();
羽飞's avatar
羽飞 已提交
1095
    return false;
羽飞's avatar
羽飞 已提交
1096
  }
L
Longda 已提交
1097

羽飞's avatar
羽飞 已提交
1098 1099
  LOG_INFO("great! current tree is valid");
  return true;
L
Longda 已提交
1100 1101
}

羽飞's avatar
羽飞 已提交
1102
bool BplusTreeHandler::is_empty() const
L
Longda 已提交
1103
{
羽飞's avatar
羽飞 已提交
1104 1105
  return file_header_.root_page == BP_INVALID_PAGE_NUM;
}
L
Longda 已提交
1106

羽飞's avatar
羽飞 已提交
1107 1108 1109 1110 1111 1112 1113 1114
RC BplusTreeHandler::find_leaf(const char *key, BPPageHandle &page_handle)
{
  return find_leaf_internal(
			    [&](InternalIndexNodeHandler &internal_node) {
			      return internal_node.value_at(internal_node.lookup(key_comparator_, key));
			    },
			    page_handle);
}
L
Longda 已提交
1115

羽飞's avatar
羽飞 已提交
1116 1117 1118 1119 1120 1121 1122 1123
RC BplusTreeHandler::left_most_page(BPPageHandle &page_handle)
{
  return find_leaf_internal(
			    [&](InternalIndexNodeHandler &internal_node) {
			      return internal_node.value_at(0);
			    },
			    page_handle
			    );
羽飞's avatar
羽飞 已提交
1124
}
羽飞's avatar
羽飞 已提交
1125
RC BplusTreeHandler::right_most_page(BPPageHandle &page_handle)
L
Longda 已提交
1126
{
羽飞's avatar
羽飞 已提交
1127 1128 1129 1130 1131 1132 1133
  return find_leaf_internal(
			    [&](InternalIndexNodeHandler &internal_node) {
			      return internal_node.value_at(internal_node.size() - 1);
			    },
			    page_handle
			    );
}
羽飞's avatar
羽飞 已提交
1134

羽飞's avatar
羽飞 已提交
1135 1136 1137 1138 1139
RC BplusTreeHandler::find_leaf_internal(const std::function<PageNum(InternalIndexNodeHandler &)> &child_page_getter,
					BPPageHandle &page_handle)
{
  if (is_empty()) {
    return RC::EMPTY;
羽飞's avatar
羽飞 已提交
1140 1141
  }

羽飞's avatar
羽飞 已提交
1142 1143 1144 1145
  RC rc = disk_buffer_pool_->get_this_page(file_id_, file_header_.root_page, &page_handle);
  if (rc != RC::SUCCESS) {
    LOG_WARN("failed to fetch root page. page id=%d, rc=%d:%s", file_header_.root_page, rc, strrc(rc));
    return rc;
羽飞's avatar
羽飞 已提交
1146 1147
  }

羽飞's avatar
羽飞 已提交
1148 1149 1150 1151
  IndexNode *node = (IndexNode *)page_handle.data();
  while (false == node->is_leaf) {
    InternalIndexNodeHandler internal_node(file_header_, page_handle);
    PageNum page_num = child_page_getter(internal_node);
羽飞's avatar
羽飞 已提交
1152

羽飞's avatar
羽飞 已提交
1153
    disk_buffer_pool_->unpin_page(&page_handle);
L
Longda 已提交
1154

羽飞's avatar
羽飞 已提交
1155
    rc = disk_buffer_pool_->get_this_page(file_id_, page_num, &page_handle);
L
Longda 已提交
1156
    if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1157
      LOG_WARN("Failed to load page file_id:%d, page_num:%d", file_id_, page_num);
L
Longda 已提交
1158 1159
      return rc;
    }
羽飞's avatar
羽飞 已提交
1160
    node = (IndexNode *)page_handle.data();
L
Longda 已提交
1161 1162 1163 1164 1165
  }

  return RC::SUCCESS;
}

羽飞's avatar
羽飞 已提交
1166 1167 1168 1169 1170 1171 1172 1173
RC BplusTreeHandler::insert_entry_into_leaf_node(BPPageHandle &page_handle, const char *key, const RID *rid)
{
  LeafIndexNodeHandler leaf_node(file_header_, page_handle);
  bool exists = false;
  int insert_position = leaf_node.lookup(key_comparator_, key, &exists);
  if (exists) {
    LOG_TRACE("entry exists");
    return RC::RECORD_DUPLICATE_KEY;
羽飞's avatar
羽飞 已提交
1174
  }
L
Longda 已提交
1175

羽飞's avatar
羽飞 已提交
1176 1177 1178 1179
  if (leaf_node.size() < leaf_node.max_size()) {
    leaf_node.insert(insert_position, key, (const char *)rid);
    page_handle.mark_dirty();
    disk_buffer_pool_->unpin_page(&page_handle);
L
Longda 已提交
1180
    return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
1181 1182
  }

羽飞's avatar
羽飞 已提交
1183 1184 1185 1186 1187
  BPPageHandle new_page_handle;
  RC rc = split<LeafIndexNodeHandler>(page_handle, new_page_handle);
  if (rc != RC::SUCCESS) {
    LOG_WARN("failed to split leaf node. rc=%d:%s", rc, strrc(rc));
    return rc;
羽飞's avatar
羽飞 已提交
1188
  }
L
Longda 已提交
1189

羽飞's avatar
羽飞 已提交
1190 1191 1192 1193 1194
  LeafIndexNodeHandler new_index_node(file_header_, new_page_handle);
  new_index_node.set_prev_page(page_handle.page_num());
  new_index_node.set_next_page(leaf_node.next_page());
  new_index_node.set_parent_page_num(leaf_node.parent_page_num());
  leaf_node.set_next_page(new_page_handle.page_num());
羽飞's avatar
羽飞 已提交
1195

羽飞's avatar
羽飞 已提交
1196 1197 1198 1199
  PageNum next_page_num = new_index_node.next_page();
  if (next_page_num != BP_INVALID_PAGE_NUM) {
    BPPageHandle next_page_handle;
    rc = disk_buffer_pool_->get_this_page(file_id_, next_page_num, &next_page_handle);
L
Longda 已提交
1200
    if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1201
      LOG_WARN("failed to fetch next page. page num=%d, rc=%d:%s", next_page_num, rc, strrc(rc));
L
Longda 已提交
1202 1203 1204
      return rc;
    }

羽飞's avatar
羽飞 已提交
1205 1206 1207
    LeafIndexNodeHandler next_node(file_header_, next_page_handle);
    next_node.set_prev_page(new_page_handle.page_num());
    disk_buffer_pool_->unpin_page(&next_page_handle);
羽飞's avatar
羽飞 已提交
1208 1209
  }

羽飞's avatar
羽飞 已提交
1210 1211 1212 1213
  if (insert_position < leaf_node.size()) {
    leaf_node.insert(insert_position, key, (const char *)rid);
  } else {
    new_index_node.insert(insert_position - leaf_node.size(), key, (const char *)rid);
羽飞's avatar
羽飞 已提交
1214 1215
  }

羽飞's avatar
羽飞 已提交
1216
  return insert_entry_into_parent(page_handle, new_page_handle, new_index_node.key_at(0));
L
Longda 已提交
1217 1218
}

羽飞's avatar
羽飞 已提交
1219
RC BplusTreeHandler::insert_entry_into_parent(BPPageHandle &page_handle, BPPageHandle &new_page_handle, const char *key)
L
Longda 已提交
1220
{
羽飞's avatar
羽飞 已提交
1221
  RC rc = RC::SUCCESS;
L
Longda 已提交
1222

羽飞's avatar
羽飞 已提交
1223 1224 1225
  IndexNodeHandler node_handler(file_header_, page_handle);
  IndexNodeHandler new_node_handler(file_header_, new_page_handle);
  PageNum parent_page_num = node_handler.parent_page_num();
L
Longda 已提交
1226

羽飞's avatar
羽飞 已提交
1227 1228 1229 1230 1231
  if (parent_page_num == BP_INVALID_PAGE_NUM) {

    // create new root page
    BPPageHandle root_page;
    rc = disk_buffer_pool_->allocate_page(file_id_, &root_page);
L
Longda 已提交
1232
    if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1233 1234
      LOG_WARN("failed to allocate new root page. rc=%d:%s", rc, strrc(rc));
      return rc;
L
Longda 已提交
1235 1236
    }

羽飞's avatar
羽飞 已提交
1237 1238 1239 1240 1241
    InternalIndexNodeHandler root_node(file_header_, root_page);
    root_node.init_empty();
    root_node.create_new_root(page_handle.page_num(), key, new_page_handle.page_num());
    node_handler.set_parent_page_num(root_page.page_num());
    new_node_handler.set_parent_page_num(root_page.page_num());
L
Longda 已提交
1242

羽飞's avatar
羽飞 已提交
1243 1244 1245 1246
    page_handle.mark_dirty();
    new_page_handle.mark_dirty();
    disk_buffer_pool_->unpin_page(&page_handle);
    disk_buffer_pool_->unpin_page(&new_page_handle);
L
Longda 已提交
1247

羽飞's avatar
羽飞 已提交
1248 1249 1250 1251
    file_header_.root_page = root_page.page_num();
    update_root_page_num(); // TODO
    root_page.mark_dirty();
    disk_buffer_pool_->unpin_page(&root_page);
L
Longda 已提交
1252

羽飞's avatar
羽飞 已提交
1253
    return RC::SUCCESS;
L
Longda 已提交
1254 1255 1256

  } else {

羽飞's avatar
羽飞 已提交
1257 1258 1259 1260 1261 1262 1263 1264 1265
    BPPageHandle parent_page_handle;
    rc = disk_buffer_pool_->get_this_page(file_id_, parent_page_num, &parent_page_handle);
    if (rc != RC::SUCCESS) {
      LOG_WARN("failed to insert entry into leaf. rc=%d:%s", rc, strrc(rc));
      // should do more things to recover
      return rc;
    }

    InternalIndexNodeHandler node(file_header_, parent_page_handle);
L
Longda 已提交
1266

羽飞's avatar
羽飞 已提交
1267 1268 1269 1270
    /// current node is not in full mode, insert the entry and return
    if (node.size() < node.max_size()) {
      node.insert(key, new_page_handle.page_num(), key_comparator_);
      new_node_handler.set_parent_page_num(parent_page_num);
L
Longda 已提交
1271

羽飞's avatar
羽飞 已提交
1272 1273 1274 1275 1276 1277
      page_handle.mark_dirty();
      new_page_handle.mark_dirty();
      parent_page_handle.mark_dirty();
      disk_buffer_pool_->unpin_page(&page_handle);
      disk_buffer_pool_->unpin_page(&new_page_handle);
      disk_buffer_pool_->unpin_page(&parent_page_handle);
L
Longda 已提交
1278

羽飞's avatar
羽飞 已提交
1279
    } else {
L
Longda 已提交
1280

羽飞's avatar
羽飞 已提交
1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305
      // we should split the node and insert the entry and then insert new entry to current node's parent
      BPPageHandle new_parent_page_handle;
      rc = split<InternalIndexNodeHandler>(parent_page_handle, new_parent_page_handle);
      if (rc != RC::SUCCESS) {
	LOG_WARN("failed to split internal node. rc=%d:%s", rc, strrc(rc));
	disk_buffer_pool_->unpin_page(&page_handle);
	disk_buffer_pool_->unpin_page(&new_page_handle);
	disk_buffer_pool_->unpin_page(&parent_page_handle);
      } else {
	// insert into left or right ? decide by key compare result
	InternalIndexNodeHandler new_node(file_header_, new_parent_page_handle);
	if (key_comparator_(key, new_node.key_at(0)) > 0) {
	  new_node.insert(key, new_page_handle.page_num(), key_comparator_);
          new_node_handler.set_parent_page_num(new_node.page_num());
	} else {
	  node.insert(key, new_page_handle.page_num(), key_comparator_);
          new_node_handler.set_parent_page_num(node.page_num());
	}

	disk_buffer_pool_->unpin_page(&page_handle);
	disk_buffer_pool_->unpin_page(&new_page_handle);
	
	rc = insert_entry_into_parent(parent_page_handle, new_parent_page_handle, new_node.key_at(0));
      }
    }
L
Longda 已提交
1306
  }
羽飞's avatar
羽飞 已提交
1307
  return rc;
L
Longda 已提交
1308 1309 1310
}

/**
羽飞's avatar
羽飞 已提交
1311 1312 1313 1314
 * split one full node into two
 * @param page_handle[inout] the node to split
 * @param new_page_handle[out] the new node after split
 * @param intert_position the intert position of new key
L
Longda 已提交
1315
 */
羽飞's avatar
羽飞 已提交
1316 1317 1318 1319
template <typename IndexNodeHandlerType>
RC BplusTreeHandler::split(BPPageHandle &page_handle, BPPageHandle &new_page_handle)
{
  IndexNodeHandlerType old_node(file_header_, page_handle);
L
Longda 已提交
1320

羽飞's avatar
羽飞 已提交
1321 1322 1323 1324
  char *new_parent_key = (char *)mem_pool_item_->alloc();
  if (new_parent_key == nullptr) {
    LOG_WARN("Failed to alloc memory for new key. size=%d", file_header_.key_length);
    return RC::NOMEM;
L
Longda 已提交
1325 1326
  }

羽飞's avatar
羽飞 已提交
1327 1328 1329 1330 1331 1332
  // add a new node
  RC rc = disk_buffer_pool_->allocate_page(file_id_, &new_page_handle);
  if (rc != RC::SUCCESS) {
    LOG_WARN("Failed to split index page due to failed to allocate page, file_id:%d. rc=%d:%s", file_id_, rc, strrc(rc));
    return rc;
  }
L
Longda 已提交
1333

羽飞's avatar
羽飞 已提交
1334 1335 1336
  IndexNodeHandlerType new_node(file_header_, new_page_handle);
  new_node.init_empty();
  new_node.set_parent_page_num(old_node.parent_page_num());
L
Longda 已提交
1337

羽飞's avatar
羽飞 已提交
1338
  old_node.move_half_to(new_node, disk_buffer_pool_, file_id_);
L
Longda 已提交
1339

羽飞's avatar
羽飞 已提交
1340 1341 1342 1343
  page_handle.mark_dirty();
  new_page_handle.mark_dirty();
  return RC::SUCCESS;
}
L
Longda 已提交
1344

羽飞's avatar
羽飞 已提交
1345 1346 1347 1348 1349 1350 1351
RC BplusTreeHandler::update_root_page_num()
{
  BPPageHandle header_page_handle;
  RC rc = disk_buffer_pool_->get_this_page(file_id_, FIRST_INDEX_PAGE, &header_page_handle);
  if (rc != RC::SUCCESS) {
    LOG_WARN("failed to fetch header page. rc=%d:%s", rc, strrc(rc));
    return rc;
羽飞's avatar
羽飞 已提交
1352 1353
  }

羽飞's avatar
羽飞 已提交
1354 1355 1356 1357 1358
  IndexFileHeader *header = (IndexFileHeader *)header_page_handle.data();
  header->root_page = file_header_.root_page;
  header_page_handle.mark_dirty();
  disk_buffer_pool_->unpin_page(&header_page_handle);
  return rc;
L
Longda 已提交
1359
}
羽飞's avatar
羽飞 已提交
1360 1361


羽飞's avatar
羽飞 已提交
1362
RC BplusTreeHandler::create_new_tree(const char *key, const RID *rid)
L
Longda 已提交
1363
{
羽飞's avatar
羽飞 已提交
1364 1365 1366 1367 1368
  RC rc = RC::SUCCESS;
  if (file_header_.root_page != BP_INVALID_PAGE_NUM) {
    rc = RC::INTERNAL;
    LOG_WARN("cannot create new tree while root page is valid. root page id=%d", file_header_.root_page);
    return rc;
L
Longda 已提交
1369 1370
  }

羽飞's avatar
羽飞 已提交
1371 1372 1373 1374 1375
  BPPageHandle page_handle;
  rc = disk_buffer_pool_->allocate_page(file_id_, &page_handle);
  if (rc != RC::SUCCESS) {
    LOG_WARN("failed to allocate root page. rc=%d:%s", rc, strrc(rc));
    return rc;
羽飞's avatar
羽飞 已提交
1376 1377
  }

羽飞's avatar
羽飞 已提交
1378 1379 1380 1381 1382 1383
  LeafIndexNodeHandler leaf_node(file_header_, page_handle);
  leaf_node.init_empty();
  leaf_node.insert(0, key, (const char *)rid);
  file_header_.root_page = page_handle.page_num();
  page_handle.mark_dirty();
  disk_buffer_pool_->unpin_page(&page_handle);
L
Longda 已提交
1384

羽飞's avatar
羽飞 已提交
1385 1386 1387
  rc = update_root_page_num();
  // disk_buffer_pool_->check_all_pages_unpinned(file_id_);
  return rc;
羽飞's avatar
羽飞 已提交
1388 1389
}

羽飞's avatar
羽飞 已提交
1390
char *BplusTreeHandler::make_key(const char *user_key, const RID &rid)
羽飞's avatar
羽飞 已提交
1391
{
羽飞's avatar
羽飞 已提交
1392 1393 1394 1395 1396 1397 1398 1399 1400
  char *key = (char *)mem_pool_item_->alloc();
  if (key == nullptr) {
    LOG_WARN("Failed to alloc memory for key. file_id:%d", file_id_);
    return nullptr;
  }
  memcpy(key, user_key, file_header_.attr_length);
  memcpy(key + file_header_.attr_length, &rid, sizeof(rid));
  return key;
}
羽飞's avatar
羽飞 已提交
1401

羽飞's avatar
羽飞 已提交
1402 1403 1404 1405
void BplusTreeHandler::free_key(char *key)
{
  mem_pool_item_->free(key);
}
L
Longda 已提交
1406

羽飞's avatar
羽飞 已提交
1407 1408 1409 1410 1411
RC BplusTreeHandler::insert_entry(const char *user_key, const RID *rid)
{
  if (file_id_ < 0) {
    LOG_WARN("Index isn't ready!");
    return RC::RECORD_CLOSED;
L
Longda 已提交
1412
  }
羽飞's avatar
羽飞 已提交
1413

羽飞's avatar
羽飞 已提交
1414 1415 1416
  if (user_key == nullptr || rid == nullptr) {
    LOG_WARN("Invalid arguments, key is empty or rid is empty");
    return RC::INVALID_ARGUMENT;
羽飞's avatar
羽飞 已提交
1417 1418
  }

羽飞's avatar
羽飞 已提交
1419 1420 1421 1422 1423
  char *key = make_key(user_key, *rid);
  if (key == nullptr) {
    LOG_WARN("Failed to alloc memory for key. file_id:%d", file_id_);
    return RC::NOMEM;
  }
羽飞's avatar
羽飞 已提交
1424

羽飞's avatar
羽飞 已提交
1425 1426
  if (is_empty()) {
    return create_new_tree(key, rid);
羽飞's avatar
羽飞 已提交
1427 1428
  }

羽飞's avatar
羽飞 已提交
1429 1430
  BPPageHandle page_handle;
  RC rc = find_leaf(key, page_handle);
L
Longda 已提交
1431
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1432 1433
    LOG_WARN("Failed to find leaf file_id:%d, %s. rc=%d:%s", file_id_, rid->to_string().c_str(), rc, strrc(rc));
    mem_pool_item_->free(key);
羽飞's avatar
羽飞 已提交
1434 1435 1436
    return rc;
  }

羽飞's avatar
羽飞 已提交
1437
  rc = insert_entry_into_leaf_node(page_handle, key, rid);
L
Longda 已提交
1438
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1439 1440 1441 1442
    LOG_TRACE("Failed to insert into leaf of index %d, rid:%s", file_id_, rid->to_string().c_str());
    disk_buffer_pool_->unpin_page(&page_handle);
    mem_pool_item_->free(key);
    // disk_buffer_pool_->check_all_pages_unpinned(file_id_);
L
Longda 已提交
1443 1444
    return rc;
  }
羽飞's avatar
羽飞 已提交
1445

羽飞's avatar
羽飞 已提交
1446 1447 1448
  mem_pool_item_->free(key);
  LOG_TRACE("insert entry success");
  // disk_buffer_pool_->check_all_pages_unpinned(file_id_);
L
Longda 已提交
1449 1450 1451
  return RC::SUCCESS;
}

羽飞's avatar
羽飞 已提交
1452
RC BplusTreeHandler::get_entry(const char *user_key, std::list<RID> &rids)
L
Longda 已提交
1453
{
羽飞's avatar
羽飞 已提交
1454 1455 1456
  if (file_id_ < 0) {
    LOG_WARN("Index isn't ready!");
    return RC::RECORD_CLOSED;
羽飞's avatar
羽飞 已提交
1457 1458
  }

羽飞's avatar
羽飞 已提交
1459 1460 1461 1462 1463
  LOG_INFO("before get entry");
  disk_buffer_pool_->check_all_pages_unpinned(file_id_);

  BplusTreeScanner scanner(*this);
  RC rc = scanner.open(user_key, true/*left_inclusive*/, user_key, true/*right_inclusive*/);
L
Longda 已提交
1464
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1465
    LOG_WARN("failed to open scanner. rc=%d:%s", rc, strrc(rc));
羽飞's avatar
羽飞 已提交
1466 1467
    return rc;
  }
L
Longda 已提交
1468

羽飞's avatar
羽飞 已提交
1469 1470 1471
  RID rid;
  while ((rc = scanner.next_entry(&rid)) == RC::SUCCESS) {
    rids.push_back(rid);
羽飞's avatar
羽飞 已提交
1472 1473
  }

羽飞's avatar
羽飞 已提交
1474 1475 1476 1477 1478 1479 1480 1481 1482 1483
  scanner.close();
  if (rc != RC::RECORD_EOF) {
    LOG_WARN("scanner return error. rc=%d:%s", rc, strrc(rc));
  } else {
    rc = RC::SUCCESS;
  }
  LOG_INFO("after get entry");
  disk_buffer_pool_->check_all_pages_unpinned(file_id_);
  return rc;
}
羽飞's avatar
羽飞 已提交
1484

羽飞's avatar
羽飞 已提交
1485 1486 1487 1488 1489 1490
RC BplusTreeHandler::adjust_root(BPPageHandle &root_page_handle)
{
  IndexNodeHandler root_node(file_header_, root_page_handle);
  if (root_node.is_leaf() && root_node.size() > 0) {
    root_page_handle.mark_dirty();
    disk_buffer_pool_->unpin_page(&root_page_handle);
L
Longda 已提交
1491 1492
    return RC::SUCCESS;
  }
羽飞's avatar
羽飞 已提交
1493

羽飞's avatar
羽飞 已提交
1494 1495 1496 1497 1498 1499
  if (root_node.is_leaf()) {
    // this is a leaf and an empty node
    file_header_.root_page = BP_INVALID_PAGE_NUM;
  } else {
    // this is an internal node and has only one child node
    InternalIndexNodeHandler internal_node(file_header_, root_page_handle);
羽飞's avatar
羽飞 已提交
1500

羽飞's avatar
羽飞 已提交
1501 1502 1503 1504 1505 1506
    const PageNum child_page_num = internal_node.value_at(0);
    BPPageHandle child_page_handle;
    RC rc = disk_buffer_pool_->get_this_page(file_id_, child_page_num, &child_page_handle);
    if (rc != RC::SUCCESS) {
      LOG_WARN("failed to fetch child page. page num=%d, rc=%d:%s", child_page_num, rc, strrc(rc));
      return rc;
羽飞's avatar
羽飞 已提交
1507 1508
    }

羽飞's avatar
羽飞 已提交
1509 1510 1511 1512 1513
    IndexNodeHandler child_node(file_header_, child_page_handle);
    child_node.set_parent_page_num(BP_INVALID_PAGE_NUM);
    disk_buffer_pool_->unpin_page(&child_page_handle);
    
    file_header_.root_page = child_page_num;
羽飞's avatar
羽飞 已提交
1514 1515
  }

羽飞's avatar
羽飞 已提交
1516
  update_root_page_num();
羽飞's avatar
羽飞 已提交
1517

羽飞's avatar
羽飞 已提交
1518 1519 1520 1521 1522 1523 1524 1525 1526 1527
  PageNum old_root_page_num = root_page_handle.page_num();
  disk_buffer_pool_->unpin_page(&root_page_handle);
  disk_buffer_pool_->dispose_page(file_id_, old_root_page_num);
  return RC::SUCCESS;
}
template <typename IndexNodeHandlerType>
RC BplusTreeHandler::coalesce_or_redistribute(BPPageHandle &page_handle)
{
  IndexNodeHandlerType index_node(file_header_, page_handle);
  if (index_node.size() >= index_node.min_size()) {
L
Longda 已提交
1528
    disk_buffer_pool_->unpin_page(&page_handle);
羽飞's avatar
羽飞 已提交
1529
    return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
1530 1531
  }

羽飞's avatar
羽飞 已提交
1532 1533 1534 1535
  const PageNum parent_page_num = index_node.parent_page_num();
  if (BP_INVALID_PAGE_NUM == parent_page_num) {
    // this is the root page
    if (index_node.size() > 1) {
L
Longda 已提交
1536
      disk_buffer_pool_->unpin_page(&page_handle);
羽飞's avatar
羽飞 已提交
1537 1538 1539
    } else {
      // adjust the root node
      adjust_root(page_handle);
羽飞's avatar
羽飞 已提交
1540
    }
羽飞's avatar
羽飞 已提交
1541
    return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
1542 1543
  }

羽飞's avatar
羽飞 已提交
1544 1545
  BPPageHandle parent_page_handle;
  RC rc = disk_buffer_pool_->get_this_page(file_id_, parent_page_num, &parent_page_handle);
L
Longda 已提交
1546
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1547
    LOG_WARN("failed to fetch parent page. page id=%d, rc=%d:%s", parent_page_num, rc, strrc(rc));
L
Longda 已提交
1548
    disk_buffer_pool_->unpin_page(&page_handle);
羽飞's avatar
羽飞 已提交
1549
    return rc;
羽飞's avatar
羽飞 已提交
1550 1551
  }

羽飞's avatar
羽飞 已提交
1552 1553 1554 1555 1556
  InternalIndexNodeHandler parent_index_node(file_header_, parent_page_handle);
  int index = parent_index_node.lookup(key_comparator_, index_node.key_at(index_node.size() - 1));
  if (parent_index_node.value_at(index) != page_handle.page_num()) {
    LOG_ERROR("lookup return an invalid value. index=%d, this page num=%d, but got %d",
	      index, page_handle.page_num(), parent_index_node.value_at(index));
羽飞's avatar
羽飞 已提交
1557
  }
羽飞's avatar
羽飞 已提交
1558 1559 1560 1561 1562
  PageNum neighbor_page_num;
  if (index == 0) {
    neighbor_page_num = parent_index_node.value_at(1);
  } else {
    neighbor_page_num = parent_index_node.value_at(index - 1);
羽飞's avatar
羽飞 已提交
1563 1564
  }

羽飞's avatar
羽飞 已提交
1565 1566
  BPPageHandle neighbor_page_handle;
  rc = disk_buffer_pool_->get_this_page(file_id_, neighbor_page_num, &neighbor_page_handle);
L
Longda 已提交
1567
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1568 1569 1570 1571
    LOG_WARN("failed to fetch neighbor page. page id=%d, rc=%d:%s", neighbor_page_num, rc, strrc(rc));
    // TODO do more thing to release resource
    disk_buffer_pool_->unpin_page(&page_handle);
    disk_buffer_pool_->unpin_page(&parent_page_handle);
L
Longda 已提交
1572
    return rc;
羽飞's avatar
羽飞 已提交
1573
  }
羽飞's avatar
羽飞 已提交
1574 1575 1576 1577 1578 1579

  IndexNodeHandlerType neighbor_node(file_header_, neighbor_page_handle);
  if (index_node.size() + neighbor_node.size() > index_node.max_size()) {
    rc = redistribute<IndexNodeHandlerType>(neighbor_page_handle, page_handle, parent_page_handle, index);
  } else {
    rc = coalesce<IndexNodeHandlerType>(neighbor_page_handle, page_handle, parent_page_handle, index);
羽飞's avatar
羽飞 已提交
1580
  }
羽飞's avatar
羽飞 已提交
1581
  return rc;
羽飞's avatar
羽飞 已提交
1582 1583
}

羽飞's avatar
羽飞 已提交
1584 1585 1586
template <typename IndexNodeHandlerType>
RC BplusTreeHandler::coalesce(BPPageHandle &neighbor_page_handle, BPPageHandle &page_handle,
			      BPPageHandle &parent_page_handle, int index)
L
Longda 已提交
1587
{
羽飞's avatar
羽飞 已提交
1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603
  IndexNodeHandlerType neighbor_node(file_header_, neighbor_page_handle);
  IndexNodeHandlerType node(file_header_, page_handle);

  InternalIndexNodeHandler parent_node(file_header_, parent_page_handle);

  BPPageHandle *left_page_handle = nullptr;
  BPPageHandle *right_page_handle = nullptr;
  if (index == 0) {
    // neighbor node is at right
    left_page_handle = &page_handle;
    right_page_handle = &neighbor_page_handle;
    index++;
  } else {
    left_page_handle = &neighbor_page_handle;
    right_page_handle = &page_handle;
    // neighbor is at left
羽飞's avatar
羽飞 已提交
1604 1605
  }

羽飞's avatar
羽飞 已提交
1606 1607 1608 1609 1610 1611
  IndexNodeHandlerType left_node(file_header_, *left_page_handle);
  IndexNodeHandlerType right_node(file_header_, *right_page_handle);

  parent_node.remove(index);
  // parent_node.validate(key_comparator_, disk_buffer_pool_, file_id_);
  RC rc = right_node.move_to(left_node, disk_buffer_pool_, file_id_);
L
Longda 已提交
1612
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1613
    LOG_WARN("failed to move right node to left. rc=%d:%s", rc, strrc(rc));
羽飞's avatar
羽飞 已提交
1614 1615
    return rc;
  }
羽飞's avatar
羽飞 已提交
1616
  // left_node.validate(key_comparator_);
羽飞's avatar
羽飞 已提交
1617

羽飞's avatar
羽飞 已提交
1618 1619 1620 1621
  if (left_node.is_leaf()) {
    LeafIndexNodeHandler left_leaf_node(file_header_, *left_page_handle);
    LeafIndexNodeHandler right_leaf_node(file_header_, *right_page_handle);
    left_leaf_node.set_next_page(right_leaf_node.next_page());
羽飞's avatar
羽飞 已提交
1622

羽飞's avatar
羽飞 已提交
1623 1624 1625 1626 1627 1628 1629 1630 1631 1632
    PageNum next_right_page_num = right_leaf_node.next_page();
    if (next_right_page_num != BP_INVALID_PAGE_NUM) {
      BPPageHandle next_right_page_handle;
      rc = disk_buffer_pool_->get_this_page(file_id_, next_right_page_num, &next_right_page_handle);
      if (rc != RC::SUCCESS) {
        LOG_WARN("failed to fetch next right page. page number:%d. rc=%d:%s", next_right_page_num, rc, strrc(rc));
	disk_buffer_pool_->unpin_page(&page_handle);
	disk_buffer_pool_->unpin_page(&neighbor_page_handle);
	disk_buffer_pool_->unpin_page(&parent_page_handle);
        return rc;
羽飞's avatar
羽飞 已提交
1633
      }
羽飞's avatar
羽飞 已提交
1634 1635 1636 1637

      LeafIndexNodeHandler next_right_node(file_header_, next_right_page_handle);
      next_right_node.set_prev_page(left_node.page_num());
      disk_buffer_pool_->unpin_page(&next_right_page_handle);
羽飞's avatar
羽飞 已提交
1638
    }
羽飞's avatar
羽飞 已提交
1639
    
羽飞's avatar
羽飞 已提交
1640
  }
L
Longda 已提交
1641

羽飞's avatar
羽飞 已提交
1642 1643 1644 1645 1646
  PageNum right_page_num = right_page_handle->page_num();
  disk_buffer_pool_->unpin_page(left_page_handle);
  disk_buffer_pool_->unpin_page(right_page_handle);
  disk_buffer_pool_->dispose_page(file_id_, right_page_num);
  return coalesce_or_redistribute<InternalIndexNodeHandler>(parent_page_handle);
羽飞's avatar
羽飞 已提交
1647 1648
}

羽飞's avatar
羽飞 已提交
1649 1650 1651
template <typename IndexNodeHandlerType>
RC BplusTreeHandler::redistribute(BPPageHandle &neighbor_page_handle, BPPageHandle &page_handle,
				  BPPageHandle &parent_page_handle, int index)
L
Longda 已提交
1652
{
羽飞's avatar
羽飞 已提交
1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683
  InternalIndexNodeHandler parent_node(file_header_, parent_page_handle);
  IndexNodeHandlerType neighbor_node(file_header_, neighbor_page_handle);
  IndexNodeHandlerType node(file_header_, page_handle);
  if (neighbor_node.size() < node.size()) {
    LOG_ERROR("got invalid nodes. neighbor node size %d, this node size %d",
	      neighbor_node.size(), node.size());
  }
  if (index == 0) {
    // the neighbor is at right
    neighbor_node.move_first_to_end(node, disk_buffer_pool_, file_id_);
    // neighbor_node.validate(key_comparator_, disk_buffer_pool_, file_id_);
    // node.validate(key_comparator_, disk_buffer_pool_, file_id_);
    parent_node.set_key_at(index + 1, neighbor_node.key_at(0));
    // parent_node.validate(key_comparator_, disk_buffer_pool_, file_id_);
  } else {
    // the neighbor is at left
    neighbor_node.move_last_to_front(node, disk_buffer_pool_, file_id_);
    // neighbor_node.validate(key_comparator_, disk_buffer_pool_, file_id_);
    // node.validate(key_comparator_, disk_buffer_pool_, file_id_);
    parent_node.set_key_at(index, node.key_at(0));
    // parent_node.validate(key_comparator_, disk_buffer_pool_, file_id_);
  }

  neighbor_page_handle.mark_dirty();
  page_handle.mark_dirty();
  parent_page_handle.mark_dirty();
  disk_buffer_pool_->unpin_page(&parent_page_handle);
  disk_buffer_pool_->unpin_page(&neighbor_page_handle);
  disk_buffer_pool_->unpin_page(&page_handle);
  return RC::SUCCESS;
}
羽飞's avatar
羽飞 已提交
1684

羽飞's avatar
羽飞 已提交
1685 1686 1687
RC BplusTreeHandler::delete_entry_internal(BPPageHandle &leaf_page_handle, const char *key)
{
  LeafIndexNodeHandler leaf_index_node(file_header_, leaf_page_handle);
羽飞's avatar
羽飞 已提交
1688

羽飞's avatar
羽飞 已提交
1689 1690 1691 1692 1693
  const int remove_count = leaf_index_node.remove(key, key_comparator_);
  if (remove_count == 0) {
    LOG_TRACE("no data to remove");
    disk_buffer_pool_->unpin_page(&leaf_page_handle);
    return RC::RECORD_RECORD_NOT_EXIST;
羽飞's avatar
羽飞 已提交
1694
  }
羽飞's avatar
羽飞 已提交
1695
  // leaf_index_node.validate(key_comparator_, disk_buffer_pool_, file_id_);
L
Longda 已提交
1696

羽飞's avatar
羽飞 已提交
1697 1698 1699 1700 1701
  leaf_page_handle.mark_dirty();

  if (leaf_index_node.size() >= leaf_index_node.min_size()) {
    disk_buffer_pool_->unpin_page(&leaf_page_handle);
    return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
1702 1703
  }

羽飞's avatar
羽飞 已提交
1704
  return coalesce_or_redistribute<LeafIndexNodeHandler>(leaf_page_handle);
羽飞's avatar
羽飞 已提交
1705 1706
}

羽飞's avatar
羽飞 已提交
1707
RC BplusTreeHandler::delete_entry(const char *user_key, const RID *rid)
L
Longda 已提交
1708
{
羽飞's avatar
羽飞 已提交
1709 1710 1711
  if (file_id_ < 0) {
    LOG_WARN("Failed to delete index entry, due to index is't ready");
    return RC::RECORD_CLOSED;
羽飞's avatar
羽飞 已提交
1712 1713
  }

羽飞's avatar
羽飞 已提交
1714 1715 1716
  char *key = (char *)mem_pool_item_->alloc();
  if (nullptr == key) {
    LOG_WARN("Failed to alloc memory for key. size=%d", file_header_.key_length);
羽飞's avatar
羽飞 已提交
1717 1718
    return RC::NOMEM;
  }
羽飞's avatar
羽飞 已提交
1719 1720 1721 1722 1723 1724 1725
  memcpy(key, user_key, file_header_.attr_length);
  memcpy(key + file_header_.attr_length, rid, sizeof(*rid));

  LOG_INFO("before delete");
  disk_buffer_pool_->check_all_pages_unpinned(file_id_);
  BPPageHandle leaf_page_handle;
  RC rc = find_leaf(key, leaf_page_handle);
L
Longda 已提交
1726
  if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1727 1728 1729 1730 1731 1732 1733 1734 1735
    LOG_WARN("failed to find leaf page. rc =%d:%s", rc, strrc(rc));
    mem_pool_item_->free(key);
    return rc;
  }
  rc = delete_entry_internal(leaf_page_handle, key);
  if (rc != RC::SUCCESS) {
    LOG_WARN("Failed to delete index %d", file_id_);
    mem_pool_item_->free(key);
    return rc;
羽飞's avatar
羽飞 已提交
1736
  }
羽飞's avatar
羽飞 已提交
1737 1738 1739
  mem_pool_item_->free(key);
  LOG_INFO("after delete");
  disk_buffer_pool_->check_all_pages_unpinned(file_id_);
L
Longda 已提交
1740
  return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
1741 1742
}

羽飞's avatar
羽飞 已提交
1743 1744 1745 1746
BplusTreeScanner::BplusTreeScanner(BplusTreeHandler &tree_handler) : tree_handler_(tree_handler)
{}

BplusTreeScanner::~BplusTreeScanner()
L
Longda 已提交
1747
{
羽飞's avatar
羽飞 已提交
1748
  close();
羽飞's avatar
羽飞 已提交
1749 1750
}

羽飞's avatar
羽飞 已提交
1751 1752
RC BplusTreeScanner::open(const char *left_user_key, bool left_inclusive,
                          const char *right_user_key, bool right_inclusive)
L
Longda 已提交
1753
{
羽飞's avatar
羽飞 已提交
1754 1755 1756 1757
  RC rc = RC::SUCCESS;
  if (inited_) {
    LOG_WARN("tree scanner has been inited");
    return RC::INTERNAL;
羽飞's avatar
羽飞 已提交
1758
  }
羽飞's avatar
羽飞 已提交
1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774

  inited_ = true;
  
  // 校验输入的键值是否是合法范围
  if (left_user_key && right_user_key) {
    const auto &attr_comparator = tree_handler_.key_comparator_.attr_comparator();
    const int result = attr_comparator(left_user_key, right_user_key);
    if (result > 0 || // left < right
         // left == right but is (left,right)/[left,right) or (left,right]
	(result == 0 && (left_inclusive == false || right_inclusive == false))) { 
      return RC::INVALID_ARGUMENT;
    }
  }

  if (nullptr == left_user_key) {
    rc = tree_handler_.left_most_page(left_page_handle_);
L
Longda 已提交
1775
    if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1776
      LOG_WARN("failed to find left most page. rc=%d:%s", rc, strrc(rc));
羽飞's avatar
羽飞 已提交
1777 1778
      return rc;
    }
羽飞's avatar
羽飞 已提交
1779 1780

    iter_index_ = 0;
L
Longda 已提交
1781
  } else {
羽飞's avatar
羽飞 已提交
1782 1783 1784 1785 1786 1787 1788 1789
    char *left_key = nullptr;
    if (left_inclusive) { 
      left_key = tree_handler_.make_key(left_user_key, *RID::min());
    } else {
      left_key = tree_handler_.make_key(left_user_key, *RID::max());
    }
    rc = tree_handler_.find_leaf(left_key, left_page_handle_);

L
Longda 已提交
1790
    if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1791 1792
      LOG_WARN("failed to find left page. rc=%d:%s", rc, strrc(rc));
      tree_handler_.free_key(left_key);
羽飞's avatar
羽飞 已提交
1793 1794
      return rc;
    }
羽飞's avatar
羽飞 已提交
1795 1796 1797 1798 1799 1800 1801 1802 1803
    LeafIndexNodeHandler left_node(tree_handler_.file_header_, left_page_handle_);
    int left_index = left_node.lookup(tree_handler_.key_comparator_, left_key);
    tree_handler_.free_key(left_key);
    // lookup 返回的是适合插入的位置,还需要判断一下是否在合适的边界范围内
    if (left_index >= left_node.size()) { // 超出了当前页,就需要向后移动一个位置
      const PageNum next_page_num = left_node.next_page();
      if (next_page_num == BP_INVALID_PAGE_NUM) { // 这里已经是最后一页,说明当前扫描,没有数据
	return RC::SUCCESS;
      }
羽飞's avatar
羽飞 已提交
1804

羽飞's avatar
羽飞 已提交
1805 1806
      tree_handler_.disk_buffer_pool_->unpin_page(&left_page_handle_);
      rc = tree_handler_.disk_buffer_pool_->get_this_page(tree_handler_.file_id_, next_page_num, &left_page_handle_);
L
Longda 已提交
1807
      if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1808 1809
	LOG_WARN("failed to fetch next page. page num=%d, rc=%d:%s", next_page_num, rc, strrc(rc));
	return rc;
羽飞's avatar
羽飞 已提交
1810
      }
羽飞's avatar
羽飞 已提交
1811 1812

      left_index = 0;
羽飞's avatar
羽飞 已提交
1813
    }
羽飞's avatar
羽飞 已提交
1814
    iter_index_ = left_index;
羽飞's avatar
羽飞 已提交
1815 1816
  }

羽飞's avatar
羽飞 已提交
1817 1818 1819
  // 没有指定右边界范围,那么就返回右边界最大值
  if (nullptr == right_user_key) {
    rc = tree_handler_.right_most_page(right_page_handle_);
L
Longda 已提交
1820
    if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1821
      LOG_WARN("failed to fetch right most page. rc=%d:%s", rc, strrc(rc));
羽飞's avatar
羽飞 已提交
1822 1823
      return rc;
    }
羽飞's avatar
羽飞 已提交
1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836

    LeafIndexNodeHandler node(tree_handler_.file_header_, right_page_handle_);
    end_index_ = node.size() - 1;
  } else {

    char *right_key = nullptr;
    if (right_inclusive) {
      right_key = tree_handler_.make_key(right_user_key, *RID::max());
    } else {
      right_key = tree_handler_.make_key(right_user_key, *RID::min());
    }

    rc = tree_handler_.find_leaf(right_key, right_page_handle_);
L
Longda 已提交
1837
    if (rc != RC::SUCCESS) {
羽飞's avatar
羽飞 已提交
1838 1839
      LOG_WARN("failed to find left page. rc=%d:%s", rc, strrc(rc));
      tree_handler_.free_key(right_key);
羽飞's avatar
羽飞 已提交
1840 1841 1842
      return rc;
    }

羽飞's avatar
羽飞 已提交
1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883
    LeafIndexNodeHandler right_node(tree_handler_.file_header_, right_page_handle_);
    int right_index = right_node.lookup(tree_handler_.key_comparator_, right_key);
    tree_handler_.free_key(right_key);
    // lookup 返回的是适合插入的位置,需要根据实际情况做调整
    // 通常情况下需要找到上一个位置
    if (right_index > 0) {
      right_index--;
    } else {
      // 实际上,只有最左边的叶子节点查找时,lookup 才可能返回0
      // 其它的叶子节点都不可能返回0,所以这段逻辑其实是可以简化的
      const PageNum prev_page_num = right_node.prev_page();
      if (prev_page_num == BP_INVALID_PAGE_NUM) {
	end_index_ = -1;
	return RC::SUCCESS;
      }

      tree_handler_.disk_buffer_pool_->unpin_page(&right_page_handle_);
      rc = tree_handler_.disk_buffer_pool_->get_this_page(tree_handler_.file_id_, prev_page_num, &right_page_handle_);
      if (rc != RC::SUCCESS) {
	LOG_WARN("failed to fetch prev page num. page num=%d, rc=%d:%s", prev_page_num, rc, strrc(rc));
	return rc;
      }

      LeafIndexNodeHandler tmp_node(tree_handler_.file_header_, right_page_handle_);
      right_index = tmp_node.size() - 1;
    }
    end_index_ = right_index;
  }

  // 判断是否左边界比右边界要靠后
  // 两个边界最多会多一页
  // 查找不存在的元素,或者不存在的范围数据时,可能会存在这个问题
  if (left_page_handle_.page_num() == right_page_handle_.page_num() &&
      iter_index_ > end_index_) {
    end_index_ = -1;
  } else {
    LeafIndexNodeHandler left_node(tree_handler_.file_header_, left_page_handle_);
    LeafIndexNodeHandler right_node(tree_handler_.file_header_, right_page_handle_);
    if (left_node.prev_page() == right_node.page_num()) {
      end_index_ = -1;
    }
羽飞's avatar
羽飞 已提交
1884
  }
羽飞's avatar
羽飞 已提交
1885
  return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
1886 1887
}

羽飞's avatar
羽飞 已提交
1888
RC BplusTreeScanner::next_entry(RID *rid)
L
Longda 已提交
1889
{
羽飞's avatar
羽飞 已提交
1890 1891
  if (-1 == end_index_) {
    return RC::RECORD_EOF;
羽飞's avatar
羽飞 已提交
1892 1893
  }

羽飞's avatar
羽飞 已提交
1894 1895 1896 1897 1898 1899 1900
  LeafIndexNodeHandler node(tree_handler_.file_header_, left_page_handle_);
  memcpy(rid, node.value_at(iter_index_), sizeof(*rid));

  if (left_page_handle_.page_num() == right_page_handle_.page_num() &&
      iter_index_ == end_index_) {
    end_index_ = -1;
    return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
1901 1902
  }

羽飞's avatar
羽飞 已提交
1903 1904 1905 1906
  if (iter_index_ < node.size() - 1) {
    ++iter_index_;
    return RC::SUCCESS;
  }
羽飞's avatar
羽飞 已提交
1907

羽飞's avatar
羽飞 已提交
1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919
  RC rc = RC::SUCCESS;
  if (left_page_handle_.page_num() != right_page_handle_.page_num()) {
    PageNum page_num = node.next_page();
    tree_handler_.disk_buffer_pool_->unpin_page(&left_page_handle_);
    if (page_num == BP_INVALID_PAGE_NUM) {
      LOG_WARN("got invalid next page. page num=%d", page_num);
      rc = RC::INTERNAL;
    } else {
      rc = tree_handler_.disk_buffer_pool_->get_this_page(tree_handler_.file_id_, page_num, &left_page_handle_);
      if (rc != RC::SUCCESS) {
        LOG_WARN("failed to fetch next page. page num=%d, rc=%d:%s", page_num, rc, strrc(rc));
        return rc;
羽飞's avatar
羽飞 已提交
1920 1921
      }

羽飞's avatar
羽飞 已提交
1922 1923 1924 1925 1926 1927
      iter_index_ = 0;
    }
  } else if (end_index_ != -1) {
    LOG_WARN("should have more pages but not. left page=%d, right page=%d",
	     left_page_handle_.page_num(), right_page_handle_.page_num());
    rc = RC::INTERNAL;
羽飞's avatar
羽飞 已提交
1928
  }
羽飞's avatar
羽飞 已提交
1929
  return rc;
羽飞's avatar
羽飞 已提交
1930 1931
}

羽飞's avatar
羽飞 已提交
1932 1933 1934 1935
RC BplusTreeScanner::close()
{
  if (left_page_handle_.open) {
    tree_handler_.disk_buffer_pool_->unpin_page(&left_page_handle_);
羽飞's avatar
羽飞 已提交
1936
  }
羽飞's avatar
羽飞 已提交
1937 1938
  if (right_page_handle_.open) {
    tree_handler_.disk_buffer_pool_->unpin_page(&right_page_handle_);
羽飞's avatar
羽飞 已提交
1939
  }
羽飞's avatar
羽飞 已提交
1940 1941 1942 1943
  end_index_ = -1;
  inited_ = false;
  LOG_INFO("bplus tree scanner closed");
  return RC::SUCCESS;
羽飞's avatar
羽飞 已提交
1944
}