未验证 提交 9446aba8 编写于 作者: 羽飞's avatar 羽飞 提交者: GitHub

Merge pull request #48 from hnwyllmm/main

fix var len char
......@@ -14,6 +14,7 @@ See the Mulan PSL v2 for more details. */
#pragma once
#include <string.h>
#include "storage/common/field.h"
#include "sql/expr/tuple_cell.h"
......@@ -79,7 +80,11 @@ class ValueExpr : public Expression
public:
ValueExpr() = default;
ValueExpr(const Value &value) : tuple_cell_(value.type, (char *)value.data)
{}
{
if (value.type == CHARS) {
tuple_cell_.set_length(strlen((const char *)value.data));
}
}
virtual ~ValueExpr() = default;
......
......@@ -115,6 +115,7 @@ public:
const FieldMeta *field_meta = field_expr->field().meta();
cell.set_type(field_meta->type());
cell.set_data(this->record_->data() + field_meta->offset());
cell.set_length(field_meta->len());
return RC::SUCCESS;
}
......
......@@ -27,7 +27,7 @@ void TupleCell::to_string(std::ostream &os) const
os << *(float *)data_;
} break;
case CHARS: {
for (int i = 0; i < 4; i++) { // the max length of CHARS is 4
for (int i = 0; i < length_; i++) {
if (data_[i] == '\0') {
break;
}
......@@ -46,7 +46,7 @@ int TupleCell::compare(const TupleCell &other) const
switch (this->attr_type_) {
case INTS: return compare_int(this->data_, other.data_);
case FLOATS: return compare_float(this->data_, other.data_);
case CHARS: return compare_string(this->data_, other.data_, 4);
case CHARS: return compare_string(this->data_, this->length_, other.data_, other.length_);
default: {
LOG_WARN("unsupported type: %d", this->attr_type_);
}
......
......@@ -31,6 +31,7 @@ public:
{}
void set_type(AttrType type) { this->attr_type_ = type; }
void set_length(int length) { this->length_ = length; }
void set_data(char *data) { this->data_ = data; }
void set_data(const char *data) { this->set_data(const_cast<char *>(data)); }
......@@ -43,11 +44,15 @@ public:
return data_;
}
int length() const { return length_; }
AttrType attr_type() const
{
return attr_type_;
}
private:
AttrType attr_type_ = UNDEFINED;
int length_ = -1;
char *data_ = nullptr; // real data. no need to move to field_meta.offset
};
......@@ -36,8 +36,8 @@ RC IndexScanOperator::open()
}
IndexScanner *index_scanner = index_->create_scanner(left_cell_.data(), left_inclusive_,
right_cell_.data(), right_inclusive_);
IndexScanner *index_scanner = index_->create_scanner(left_cell_.data(), left_cell_.length(), left_inclusive_,
right_cell_.data(), right_cell_.length(), right_inclusive_);
if (nullptr == index_scanner) {
LOG_WARN("failed to create index scanner");
return RC::INTERNAL;
......
......@@ -66,6 +66,8 @@ public:
return comp_op_;
}
AttrType attr_type() const { return attr_type_; }
private:
ConDesc left_;
ConDesc right_;
......
......@@ -326,7 +326,14 @@ RC Table::make_record(int value_num, const Value *values, char *&record_out)
for (int i = 0; i < value_num; i++) {
const FieldMeta *field = table_meta_.field(i + normal_field_start_index);
const Value &value = values[i];
memcpy(record + field->offset(), value.data, field->len());
size_t copy_len = field->len();
if (field->type() == CHARS) {
const size_t data_len = strlen((const char *)value.data);
if (copy_len > data_len) {
copy_len = data_len + 1;
}
}
memcpy(record + field->offset(), value.data, copy_len);
}
record_out = record;
......@@ -775,6 +782,8 @@ IndexScanner *Table::find_index_for_scan(const DefaultConditionFilter &filter)
const char *left_key = nullptr;
const char *right_key = nullptr;
int left_len = 4;
int right_len = 4;
bool left_inclusive = false;
bool right_inclusive = false;
switch (filter.comp_op()) {
......@@ -809,7 +818,12 @@ IndexScanner *Table::find_index_for_scan(const DefaultConditionFilter &filter)
return nullptr;
}
}
return index->create_scanner(left_key, left_inclusive, right_key, right_inclusive);
if (filter.attr_type() == CHARS) {
left_len = left_key != nullptr ? strlen(left_key) : 0;
right_len = right_key != nullptr ? strlen(right_key) : 0;
}
return index->create_scanner(left_key, left_len, left_inclusive, right_key, right_len, right_inclusive);
}
IndexScanner *Table::find_index_for_scan(const ConditionFilter *filter)
......
......@@ -29,6 +29,7 @@ class IndexScanner;
class RecordDeleter;
class Trx;
// TODO remove the routines with condition
class Table {
public:
Table() = default;
......
......@@ -295,6 +295,8 @@ RC DiskBufferPool::allocate_page(Frame **frame)
RC DiskBufferPool::unpin_page(Frame *frame)
{
assert(frame->pin_count_ >= 1);
if (--frame->pin_count_ == 0) {
PageNum page_num = frame->page_num();
auto pages_it = disposed_pages.find(page_num);
......
......@@ -1443,10 +1443,10 @@ RC BplusTreeHandler::insert_entry(const char *user_key, const RID *rid)
return RC::SUCCESS;
}
RC BplusTreeHandler::get_entry(const char *user_key, std::list<RID> &rids)
RC BplusTreeHandler::get_entry(const char *user_key, int key_len, std::list<RID> &rids)
{
BplusTreeScanner scanner(*this);
RC rc = scanner.open(user_key, true/*left_inclusive*/, user_key, true/*right_inclusive*/);
RC rc = scanner.open(user_key, key_len, true/*left_inclusive*/, user_key, key_len, true/*right_inclusive*/);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to open scanner. rc=%d:%s", rc, strrc(rc));
return rc;
......@@ -1721,8 +1721,8 @@ BplusTreeScanner::~BplusTreeScanner()
close();
}
RC BplusTreeScanner::open(const char *left_user_key, bool left_inclusive,
const char *right_user_key, bool right_inclusive)
RC BplusTreeScanner::open(const char *left_user_key, int left_len, bool left_inclusive,
const char *right_user_key, int right_len, bool right_inclusive)
{
RC rc = RC::SUCCESS;
if (inited_) {
......@@ -1753,10 +1753,30 @@ RC BplusTreeScanner::open(const char *left_user_key, bool left_inclusive,
iter_index_ = 0;
} else {
char *left_key = nullptr;
if (left_inclusive) {
left_key = tree_handler_.make_key(left_user_key, *RID::min());
char *fixed_left_key = const_cast<char *>(left_user_key);
if (tree_handler_.file_header_.attr_type == CHARS) {
bool should_inclusive_after_fix = false;
rc = fix_user_key(left_user_key, left_len, true/*greater*/, &fixed_left_key, &should_inclusive_after_fix);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to fix left user key. rc=%s", strrc(rc));
return rc;
}
if (should_inclusive_after_fix) {
left_inclusive = true;
}
}
if (left_inclusive) {
left_key = tree_handler_.make_key(fixed_left_key, *RID::min());
} else {
left_key = tree_handler_.make_key(left_user_key, *RID::max());
left_key = tree_handler_.make_key(fixed_left_key, *RID::max());
}
if (fixed_left_key != left_user_key) {
delete[] fixed_left_key;
fixed_left_key = nullptr;
}
rc = tree_handler_.find_leaf(left_key, left_frame_);
......@@ -1800,10 +1820,28 @@ RC BplusTreeScanner::open(const char *left_user_key, bool left_inclusive,
} else {
char *right_key = nullptr;
char *fixed_right_key = const_cast<char *>(right_user_key);
bool should_include_after_fix = false;
if (tree_handler_.file_header_.attr_type == CHARS) {
rc = fix_user_key(right_user_key, right_len, false/*want_greater*/, &fixed_right_key, &should_include_after_fix);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to fix right user key. rc=%s", strrc(rc));
return rc;
}
if (should_include_after_fix) {
right_inclusive = true;
}
}
if (right_inclusive) {
right_key = tree_handler_.make_key(right_user_key, *RID::max());
right_key = tree_handler_.make_key(fixed_right_key, *RID::max());
} else {
right_key = tree_handler_.make_key(right_user_key, *RID::min());
right_key = tree_handler_.make_key(fixed_right_key, *RID::min());
}
if (fixed_right_key != right_user_key) {
delete[] fixed_right_key;
fixed_right_key = nullptr;
}
rc = tree_handler_.find_leaf(right_key, right_frame_);
......@@ -1883,11 +1921,13 @@ RC BplusTreeScanner::next_entry(RID *rid)
PageNum page_num = node.next_page();
tree_handler_.disk_buffer_pool_->unpin_page(left_frame_);
if (page_num == BP_INVALID_PAGE_NUM) {
left_frame_ = nullptr;
LOG_WARN("got invalid next page. page num=%d", page_num);
rc = RC::INTERNAL;
} else {
rc = tree_handler_.disk_buffer_pool_->get_this_page(page_num, &left_frame_);
if (rc != RC::SUCCESS) {
left_frame_ = nullptr;
LOG_WARN("failed to fetch next page. page num=%d, rc=%d:%s", page_num, rc, strrc(rc));
return rc;
}
......@@ -1906,12 +1946,64 @@ RC BplusTreeScanner::close()
{
if (left_frame_ != nullptr) {
tree_handler_.disk_buffer_pool_->unpin_page(left_frame_);
left_frame_ = nullptr;
}
if (right_frame_ != nullptr) {
tree_handler_.disk_buffer_pool_->unpin_page(right_frame_);
right_frame_ = nullptr;
}
end_index_ = -1;
inited_ = false;
LOG_INFO("bplus tree scanner closed");
return RC::SUCCESS;
}
RC BplusTreeScanner::fix_user_key(const char *user_key, int key_len, bool want_greater,
char **fixed_key, bool *should_inclusive)
{
if (nullptr == fixed_key || nullptr == should_inclusive) {
return RC::INVALID_ARGUMENT;
}
// 这里很粗暴,变长字段才需要做调整,其它默认都不需要做调整
assert(tree_handler_.file_header_.attr_type == CHARS);
assert(strlen(user_key) >= static_cast<size_t>(key_len));
*should_inclusive = false;
int32_t attr_length = tree_handler_.file_header_.attr_length;
char *key_buf = new (std::nothrow)char [attr_length];
if (nullptr == key_buf) {
return RC::NOMEM;
}
if (key_len <= attr_length) {
memcpy(key_buf, user_key, key_len);
memset(key_buf + key_len, 0, attr_length - key_len);
*fixed_key = key_buf;
return RC::SUCCESS;
}
// key_len > attr_length
memcpy(key_buf, user_key, attr_length);
char c = user_key[attr_length];
if (c == 0) {
*fixed_key = key_buf;
return RC::SUCCESS;
}
// 扫描 >=/> user_key 的数据
// 示例:>=/> ABCD1 的数据,attr_length=4,
// 等价于扫描 >= ABCE 的数据
// 如果是扫描 <=/< user_key的数据
// 示例:<=/< ABCD1 <==> <= ABCD (attr_length=4)
*should_inclusive = true;
if (want_greater) {
key_buf[attr_length - 1]++;
}
*fixed_key = key_buf;
return RC::SUCCESS;
}
......@@ -118,7 +118,14 @@ public:
return std::to_string(*(float*)v);
}
case CHARS: {
return std::string(v, attr_length_);
std::string str;
for (int i = 0; i < attr_length_; i++) {
if (v[i] == 0) {
break;
}
str.push_back(v[i]);
}
return str;
}
default:{
LOG_ERROR("unknown attr type. %d", attr_type_);
......@@ -400,12 +407,14 @@ public:
* 此函数向IndexHandle对应的索引中插入一个索引项。
* 参数user_key指向要插入的属性值,参数rid标识该索引项对应的元组,
* 即向索引中插入一个值为(user_key,rid)的键值对
* @note 这里假设user_key的内存大小与attr_length 一致
*/
RC insert_entry(const char *user_key, const RID *rid);
/**
* 从IndexHandle句柄对应的索引中删除一个值为(*pData,rid)的索引项
* @return RECORD_INVALID_KEY 指定值不存在
* @note 这里假设user_key的内存大小与attr_length 一致
*/
RC delete_entry(const char *user_key, const RID *rid);
......@@ -413,9 +422,10 @@ public:
/**
* 获取指定值的record
* @param key_len user_key的长度
* @param rid 返回值,记录记录所在的页面号和slot
*/
RC get_entry(const char *user_key, std::list<RID> &rids);
RC get_entry(const char *user_key, int key_len, std::list<RID> &rids);
RC sync();
......@@ -493,18 +503,26 @@ public:
/**
* 扫描指定范围的数据
* @param left_key 扫描范围的左边界,如果是null,则没有左边界
* @param left_user_key 扫描范围的左边界,如果是null,则没有左边界
* @param left_len left_user_key 的内存大小(只有在变长字段中才会关注)
* @param left_inclusive 左边界的值是否包含在内
* @param right_key 扫描范围的右边界。如果是null,则没有右边界
* @param right_user_key 扫描范围的右边界。如果是null,则没有右边界
* @param right_len right_user_key 的内存大小(只有在变长字段中才会关注)
* @param right_inclusive 右边界的值是否包含在内
*/
RC open(const char *left_user_key, bool left_inclusive,
const char *right_user_key, bool right_inclusive);
RC open(const char *left_user_key, int left_len, bool left_inclusive,
const char *right_user_key, int right_len, bool right_inclusive);
RC next_entry(RID *rid);
RC close();
private:
/**
* 如果key的类型是CHARS, 扩展或缩减user_key的大小刚好是schema中定义的大小
*/
RC fix_user_key(const char *user_key, int key_len, bool want_greater,
char **fixed_key, bool *should_inclusive);
private:
bool inited_ = false;
BplusTreeHandler &tree_handler_;
......
......@@ -98,11 +98,11 @@ RC BplusTreeIndex::delete_entry(const char *record, const RID *rid)
return index_handler_.delete_entry(record + field_meta_.offset(), rid);
}
IndexScanner *BplusTreeIndex::create_scanner(const char *left_key, bool left_inclusive,
const char *right_key, bool right_inclusive)
IndexScanner *BplusTreeIndex::create_scanner(const char *left_key, int left_len, bool left_inclusive,
const char *right_key, int right_len, bool right_inclusive)
{
BplusTreeIndexScanner *index_scanner = new BplusTreeIndexScanner(index_handler_);
RC rc = index_scanner->open(left_key, left_inclusive, right_key, right_inclusive);
RC rc = index_scanner->open(left_key, left_len, left_inclusive, right_key, right_len, right_inclusive);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to open index scanner. rc=%d:%s", rc, strrc(rc));
delete index_scanner;
......@@ -125,9 +125,10 @@ BplusTreeIndexScanner::~BplusTreeIndexScanner() noexcept
tree_scanner_.close();
}
RC BplusTreeIndexScanner::open(const char *left_key, bool left_inclusive, const char *right_key, bool right_inclusive)
RC BplusTreeIndexScanner::open(const char *left_key, int left_len, bool left_inclusive,
const char *right_key, int right_len, bool right_inclusive)
{
return tree_scanner_.open(left_key, left_inclusive, right_key, right_inclusive);
return tree_scanner_.open(left_key, left_len, left_inclusive, right_key, right_len, right_inclusive);
}
RC BplusTreeIndexScanner::next_entry(RID *rid)
......
......@@ -33,8 +33,8 @@ public:
/**
* 扫描指定范围的数据
*/
IndexScanner *create_scanner(const char *left_key, bool left_inclusive,
const char *right_key, bool right_inclusive) override;
IndexScanner *create_scanner(const char *left_key, int left_len, bool left_inclusive,
const char *right_key, int right_len, bool right_inclusive) override;
RC sync() override;
......@@ -51,7 +51,8 @@ public:
RC next_entry(RID *rid) override;
RC destroy() override;
RC open(const char *left_key, bool left_inclusive, const char *right_key, bool right_inclusive);
RC open(const char *left_key, int left_len, bool left_inclusive,
const char *right_key, int right_len, bool right_inclusive);
private:
BplusTreeScanner tree_scanner_;
};
......
......@@ -46,8 +46,8 @@ public:
virtual RC insert_entry(const char *record, const RID *rid) = 0;
virtual RC delete_entry(const char *record, const RID *rid) = 0;
virtual IndexScanner *create_scanner(const char *left_key, bool left_inclusive,
const char *right_key, bool right_inclusive) = 0;
virtual IndexScanner *create_scanner(const char *left_key, int left_len, bool left_inclusive,
const char *right_key, int right_len, bool right_inclusive) = 0;
virtual RC sync() = 0;
......
......@@ -13,6 +13,7 @@ See the Mulan PSL v2 for more details. */
//
#include <string.h>
#include <algorithm>
const double epsilon = 1E-6;
......@@ -37,9 +38,22 @@ int compare_float(void *arg1, void *arg2)
return 0;
}
int compare_string(void *arg1, void *arg2, int maxlen)
int compare_string(void *arg1, int arg1_max_length, void *arg2, int arg2_max_length)
{
const char *s1 = (const char *)arg1;
const char *s2 = (const char *)arg2;
return strncmp(s1, s2, maxlen);
int maxlen = std::min(arg1_max_length, arg2_max_length);
int result = strncmp(s1, s2, maxlen);
if (0 != result) {
return result;
}
if (arg1_max_length > maxlen) {
return s1[maxlen] - 0;
}
if (arg2_max_length > maxlen) {
return 0 - s2[maxlen];
}
return 0;
}
......@@ -16,4 +16,4 @@ See the Mulan PSL v2 for more details. */
int compare_int(void *arg1, void *arg2);
int compare_float(void *arg1, void *arg2);
int compare_string(void *arg1, void *arg2, int max_length);
int compare_string(void *arg1, int arg1_max_length, void *arg2, int arg2_max_length);
......@@ -31,6 +31,7 @@ using namespace common;
#define INSERT_NUM (TIMES * ORDER * ORDER * ORDER * ORDER)
#define POOL_NUM 2
BufferPoolManager bpm;
BplusTreeHandler *handler = nullptr;
const char *index_name = "test.btree";
int insert_num = INSERT_NUM;
......@@ -38,6 +39,12 @@ const int page_size = 1024;
RID rid, check_rid;
int k = 0;
void init_bpm()
{
if (&BufferPoolManager::instance() == nullptr) {
BufferPoolManager::set_instance(&bpm);
}
}
void test_insert()
{
RC rc = RC::SUCCESS;
......@@ -148,7 +155,7 @@ void test_get()
}
rids.clear();
RC rc = handler->get_entry((const char *)&i, rids);
RC rc = handler->get_entry((const char *)&i, 4, rids);
ASSERT_EQ(RC::SUCCESS, rc);
ASSERT_EQ(1, rids.size());
......@@ -221,7 +228,7 @@ void test_delete()
LOG_INFO("Begin to get entry of index, i=%d, rid: %s", i, rid.to_string().c_str());
}
rids.clear();
rc = handler->get_entry((const char *)&i, rids);
rc = handler->get_entry((const char *)&i, 4, rids);
ASSERT_EQ(RC::SUCCESS, rc);
int t = i % TIMES;
if (t == 0 || t == 1) {
......@@ -458,6 +465,50 @@ TEST(test_bplus_tree, test_internal_index_node_handle)
ASSERT_EQ(i, index);
}
}
TEST(test_bplus_tree, test_chars)
{
LoggerFactory::init_default("test_chars.log");
const char *index_name = "chars.btree";
::remove(index_name);
handler = new BplusTreeHandler();
handler->create(index_name, CHARS, 8, ORDER, ORDER);
char keys[][9] = {
"abcdefg",
"12345678",
"12345678",
"abcdefg",
"abcdefga"
};
RID rid;
RC rc = RC::SUCCESS;
for (size_t i = 0; i < sizeof(keys)/sizeof(keys[0]); i++) {
rid.page_num = 0;
rid.slot_num = i;
rc = handler->insert_entry(keys[i], &rid);
ASSERT_EQ(RC::SUCCESS, rc);
}
LOG_INFO("begin to print bplus tree of chars");
handler->print_tree();
LOG_INFO("end to print bplus tree of chars");
BplusTreeScanner scanner(*handler);
const char *key = "abcdefg";
rc = scanner.open(key, strlen(key), true, key, strlen(key), true);
ASSERT_EQ(rc, RC::SUCCESS);
int count = 0;
while (RC::SUCCESS == (rc = scanner.next_entry(&rid))) {
count++;
}
scanner.close();
ASSERT_EQ(2, count);
}
TEST(test_bplus_tree, test_scanner)
{
LoggerFactory::init_default("test.log");
......@@ -484,7 +535,7 @@ TEST(test_bplus_tree, test_scanner)
int begin = -100;
int end = -20;
rc = scanner.open((const char *)&begin, false, (const char *)&end, false);
rc = scanner.open((const char *)&begin, 4, false, (const char *)&end, 4, false);
ASSERT_EQ(RC::SUCCESS, rc);
rc = scanner.next_entry(&rid);
......@@ -494,7 +545,7 @@ TEST(test_bplus_tree, test_scanner)
begin = -100;
end = 1;
rc = scanner.open((const char *)&begin, false, (const char *)&end, false);
rc = scanner.open((const char *)&begin, 4, false, (const char *)&end, 4, false);
ASSERT_EQ(RC::SUCCESS, rc);
rc = scanner.next_entry(&rid);
ASSERT_EQ(RC::RECORD_EOF, rc);
......@@ -503,7 +554,7 @@ TEST(test_bplus_tree, test_scanner)
begin = -100;
end = 1;
rc = scanner.open((const char *)&begin, false, (const char *)&end, true/*inclusive*/);
rc = scanner.open((const char *)&begin, 4, false, (const char *)&end, 4, true/*inclusive*/);
ASSERT_EQ(RC::SUCCESS, rc);
rc = scanner.next_entry(&rid);
ASSERT_EQ(RC::SUCCESS, rc);
......@@ -514,7 +565,7 @@ TEST(test_bplus_tree, test_scanner)
begin = 1;
end = 3;
rc = scanner.open((const char *)&begin, false, (const char *)&end, false/*inclusive*/);
rc = scanner.open((const char *)&begin, 4, false, (const char *)&end, 4, false/*inclusive*/);
ASSERT_EQ(RC::SUCCESS, rc);
rc = scanner.next_entry(&rid);
ASSERT_EQ(RC::RECORD_EOF, rc);
......@@ -523,7 +574,7 @@ TEST(test_bplus_tree, test_scanner)
begin = 1;
end = 3;
rc = scanner.open((const char *)&begin, true, (const char *)&end, true/*inclusive*/);
rc = scanner.open((const char *)&begin, 4, true, (const char *)&end, 4, true/*inclusive*/);
ASSERT_EQ(RC::SUCCESS, rc);
while ((rc = scanner.next_entry(&rid)) == RC::SUCCESS) {
count++;
......@@ -535,7 +586,7 @@ TEST(test_bplus_tree, test_scanner)
begin = 0;
end = 3;
rc = scanner.open((const char *)&begin, true, (const char *)&end, true/*inclusive*/);
rc = scanner.open((const char *)&begin, 4, true, (const char *)&end, 4, true/*inclusive*/);
ASSERT_EQ(RC::SUCCESS, rc);
count = 0;
while ((rc = scanner.next_entry(&rid)) == RC::SUCCESS) {
......@@ -548,7 +599,7 @@ TEST(test_bplus_tree, test_scanner)
begin = 11;
end = 21;
rc = scanner.open((const char *)&begin, true, (const char *)&end, true/*inclusive*/);
rc = scanner.open((const char *)&begin, 4, true, (const char *)&end, 4, true/*inclusive*/);
ASSERT_EQ(RC::SUCCESS, rc);
count = 0;
while ((rc = scanner.next_entry(&rid)) == RC::SUCCESS) {
......@@ -561,7 +612,7 @@ TEST(test_bplus_tree, test_scanner)
begin = 11;
end = 91;
rc = scanner.open((const char *)&begin, true, (const char *)&end, true/*inclusive*/);
rc = scanner.open((const char *)&begin, 4, true, (const char *)&end, 4, true/*inclusive*/);
ASSERT_EQ(RC::SUCCESS, rc);
count = 0;
while ((rc = scanner.next_entry(&rid)) == RC::SUCCESS) {
......@@ -574,7 +625,7 @@ TEST(test_bplus_tree, test_scanner)
begin = 191;
end = 199;
rc = scanner.open((const char *)&begin, true, (const char *)&end, true/*inclusive*/);
rc = scanner.open((const char *)&begin, 4, true, (const char *)&end, 4, true/*inclusive*/);
ASSERT_EQ(RC::SUCCESS, rc);
count = 0;
while ((rc = scanner.next_entry(&rid)) == RC::SUCCESS) {
......@@ -587,7 +638,7 @@ TEST(test_bplus_tree, test_scanner)
begin = 191;
end = 201;
rc = scanner.open((const char *)&begin, true, (const char *)&end, true/*inclusive*/);
rc = scanner.open((const char *)&begin, 4, true, (const char *)&end, 4, true/*inclusive*/);
ASSERT_EQ(RC::SUCCESS, rc);
count = 0;
while ((rc = scanner.next_entry(&rid)) == RC::SUCCESS) {
......@@ -600,7 +651,7 @@ TEST(test_bplus_tree, test_scanner)
begin = 200;
end = 301;
rc = scanner.open((const char *)&begin, true, (const char *)&end, true/*inclusive*/);
rc = scanner.open((const char *)&begin, 4, true, (const char *)&end, 4, true/*inclusive*/);
ASSERT_EQ(RC::SUCCESS, rc);
rc = scanner.next_entry(&rid);
ASSERT_EQ(RC::RECORD_EOF, rc);
......@@ -609,14 +660,14 @@ TEST(test_bplus_tree, test_scanner)
begin = 300;
end = 201;
rc = scanner.open((const char *)&begin, true, (const char *)&end, true/*inclusive*/);
rc = scanner.open((const char *)&begin, 4, true, (const char *)&end, 4, true/*inclusive*/);
ASSERT_EQ(RC::INVALID_ARGUMENT, rc);
scanner.close();
begin = 300;
end = 201;
rc = scanner.open(nullptr, true, (const char *)&end, true/*inclusive*/);
rc = scanner.open(nullptr, 4, true, (const char *)&end, 4, true/*inclusive*/);
ASSERT_EQ(RC::SUCCESS, rc);
count = 0;
while ((rc = scanner.next_entry(&rid)) == RC::SUCCESS) {
......@@ -629,7 +680,7 @@ TEST(test_bplus_tree, test_scanner)
begin = 300;
end = 10;
rc = scanner.open(nullptr, true, (const char *)&end, true/*inclusive*/);
rc = scanner.open(nullptr, 4, true, (const char *)&end, 4, true/*inclusive*/);
ASSERT_EQ(RC::SUCCESS, rc);
count = 0;
while ((rc = scanner.next_entry(&rid)) == RC::SUCCESS) {
......@@ -642,7 +693,7 @@ TEST(test_bplus_tree, test_scanner)
begin = 190;
end = 10;
rc = scanner.open((const char *)&begin, true, nullptr, true/*inclusive*/);
rc = scanner.open((const char *)&begin, 4, true, nullptr, 4, true/*inclusive*/);
ASSERT_EQ(RC::SUCCESS, rc);
count = 0;
while ((rc = scanner.next_entry(&rid)) == RC::SUCCESS) {
......@@ -655,7 +706,7 @@ TEST(test_bplus_tree, test_scanner)
begin = 190;
end = 10;
rc = scanner.open(nullptr, true, nullptr, true/*inclusive*/);
rc = scanner.open(nullptr, 0, true, nullptr, 0, true/*inclusive*/);
ASSERT_EQ(RC::SUCCESS, rc);
count = 0;
while ((rc = scanner.next_entry(&rid)) == RC::SUCCESS) {
......@@ -695,6 +746,7 @@ int main(int argc, char **argv)
// 调用RUN_ALL_TESTS()运行所有测试用例
// main函数返回RUN_ALL_TESTS()的运行结果
init_bpm();
int rc = RUN_ALL_TESTS();
return rc;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册