An error occurred while loading the file. Please try again.
-
liamy authoredf0190dcd
/* Copyright (c) 2023 Renmin University of China
RMDB 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. */
#include "rm_scan.h"
#include "defs.h"
#include "record/rm_defs.h"
#include "rm_file_handle.h"
/**
* @brief 初始化file_handle和rid
* @param file_handle
*/
RmScan::RmScan(const RmFileHandle *file_handle) : file_handle_(file_handle) {
// by liamY
// 初始化file_handle和rid(指向第一个存放了记录的位置)
// // 检查filehdr,是否有数据记录
// if (file_handle_->file_hdr_.num_pages <= 1) {
// // 说明没有数据记录
// rid_ = Rid{0, 0};
// } else {
// //
// 从page里面找到第一页有record记录的,这部分由辅助函数fetch_page_handle完成
// // int page_no = 1;
// // bool find = false;
// // RmPageHandle page_handle = file_handle_->fetch_page_handle(page_no);
// // for (; page_no < file_handle_->file_hdr_.num_pages; page_no++) {
// // if (page_handle.page_hdr->num_records > 0) {
// // find = true;
// // break;
// // }
// // page_handle = file_handle_->fetch_page_handle(page_no);
// // }
// // if (find) {
// // rid_ =
// // Rid{page_no,
// // Bitmap::first_bit(true, page_handle.bitmap,
// // file_handle_->file_hdr_.num_records_per_page)};
// // } else {
// // rid_ = Rid{0, 0};
// // }
// fix by liamY
rid_ = Rid{1, -1};
if (file_handle_->file_hdr_.num_pages == 1) {
rid_ = Rid{0, 0};
} else {
next();
}
// }
}
/**
* @brief 找到文件中下一个存放了记录的位置
*/
void RmScan::next() {
// Todo:
// 找到文件中下一个存放了记录的非空闲位置,用rid_来指向这个位置
// 根据file_handle_以及rid_获取当前位置
// 获取page_handle
RmPageHandle page_handle = file_handle_->fetch_page_handle(rid_.page_no);
// 查找下一个slot_no(当前页面的查找需要单独拿出来,因为cur不同)
int next_slot_no = Bitmap::next_bit(
true, page_handle.bitmap, file_handle_->file_hdr_.num_records_per_page,
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
rid_.slot_no);
// 没有查找到下一条记录并且没有到达文件末尾都需要继续查找
while (next_slot_no == file_handle_->file_hdr_.num_records_per_page &&
!is_end()) {
// 说明下一条记录不在当前页面,寻找下一个页面
rid_.page_no++;
// fix by noah:页面增加之后已经越界,需要直接退出循环
if (is_end()) {
break;
}
page_handle = file_handle_->fetch_page_handle(rid_.page_no);
next_slot_no =
Bitmap::next_bit(true, page_handle.bitmap,
file_handle_->file_hdr_.num_records_per_page, -1);
}
// 如果还没有到达文件末尾则表示找到了下一条记录
if (!is_end()) {
// 更新rid_.slot_no,rid_.page_no已经在循环中被更新了
rid_.slot_no = next_slot_no;
}
}
/**
* @brief 判断是否到达文件末尾
*/
bool RmScan::is_end() const {
// by liamY: 修改返回值
// RmPageHandle page_handle = file_handle_->fetch_page_handle(rid_.page_no);
// int next_bit =Bitmap::next_bit(true, page_handle.bitmap,
// file_handle_->file_hdr_.num_records_per_page,
// rid_.slot_no);
// fix by noah:这里只需要判断page_no >=
// .num_pages。因为文件头页算在num_pages中,但是不算在page_no中。如果这个条件为真就表示页号越界了。
// 原来的处理方式会导致page_no越界,而如果判断的是page_no >= num_pages-1
// 又会导致当前scan中的rid还是有效的,但是被判定为已经到文件末尾
// 所以这里就只能通过next函数的配合来解决这个问题。最后一次next的时候需要将ridd的page_no额外增加一次
// add fix by liamY: rid_.page_no == 0 means there is no page
if ( rid_.page_no == 0 || rid_.page_no >= file_handle_->file_hdr_.num_pages) {
return true;
}
return false;
}
/**
* @brief RmScan内部存放的rid
*/
Rid RmScan::rid() const { return rid_; }