Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
oceanbase
miniob
提交
9446aba8
M
miniob
项目概览
oceanbase
/
miniob
1 年多 前同步成功
通知
74
Star
1521
Fork
537
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
分析
仓库
DevOps
项目成员
Pages
M
miniob
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Pages
分析
分析
仓库分析
DevOps
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
提交
未验证
提交
9446aba8
编写于
8月 16, 2022
作者:
羽飞
提交者:
GitHub
8月 16, 2022
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #48 from hnwyllmm/main
fix var len char
上级
6dedcfbf
98e4146a
变更
17
隐藏空白更改
内联
并排
Showing
17 changed file
with
261 addition
and
53 deletion
+261
-53
src/observer/sql/expr/expression.h
src/observer/sql/expr/expression.h
+6
-1
src/observer/sql/expr/tuple.h
src/observer/sql/expr/tuple.h
+1
-0
src/observer/sql/expr/tuple_cell.cpp
src/observer/sql/expr/tuple_cell.cpp
+2
-2
src/observer/sql/expr/tuple_cell.h
src/observer/sql/expr/tuple_cell.h
+5
-0
src/observer/sql/operator/index_scan_operator.cpp
src/observer/sql/operator/index_scan_operator.cpp
+2
-2
src/observer/storage/common/condition_filter.h
src/observer/storage/common/condition_filter.h
+2
-0
src/observer/storage/common/table.cpp
src/observer/storage/common/table.cpp
+16
-2
src/observer/storage/common/table.h
src/observer/storage/common/table.h
+1
-0
src/observer/storage/default/disk_buffer_pool.cpp
src/observer/storage/default/disk_buffer_pool.cpp
+2
-0
src/observer/storage/index/bplus_tree.cpp
src/observer/storage/index/bplus_tree.cpp
+101
-9
src/observer/storage/index/bplus_tree.h
src/observer/storage/index/bplus_tree.h
+24
-6
src/observer/storage/index/bplus_tree_index.cpp
src/observer/storage/index/bplus_tree_index.cpp
+6
-5
src/observer/storage/index/bplus_tree_index.h
src/observer/storage/index/bplus_tree_index.h
+4
-3
src/observer/storage/index/index.h
src/observer/storage/index/index.h
+2
-2
src/observer/util/comparator.cpp
src/observer/util/comparator.cpp
+16
-2
src/observer/util/comparator.h
src/observer/util/comparator.h
+1
-1
unitest/bplus_tree_test.cpp
unitest/bplus_tree_test.cpp
+70
-18
未找到文件。
src/observer/sql/expr/expression.h
浏览文件 @
9446aba8
...
...
@@ -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
;
...
...
src/observer/sql/expr/tuple.h
浏览文件 @
9446aba8
...
...
@@ -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
;
}
...
...
src/observer/sql/expr/tuple_cell.cpp
浏览文件 @
9446aba8
...
...
@@ -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_
);
}
...
...
src/observer/sql/expr/tuple_cell.h
浏览文件 @
9446aba8
...
...
@@ -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
};
src/observer/sql/operator/index_scan_operator.cpp
浏览文件 @
9446aba8
...
...
@@ -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
;
...
...
src/observer/storage/common/condition_filter.h
浏览文件 @
9446aba8
...
...
@@ -66,6 +66,8 @@ public:
return
comp_op_
;
}
AttrType
attr_type
()
const
{
return
attr_type_
;
}
private:
ConDesc
left_
;
ConDesc
right_
;
...
...
src/observer/storage/common/table.cpp
浏览文件 @
9446aba8
...
...
@@ -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
)
...
...
src/observer/storage/common/table.h
浏览文件 @
9446aba8
...
...
@@ -29,6 +29,7 @@ class IndexScanner;
class
RecordDeleter
;
class
Trx
;
// TODO remove the routines with condition
class
Table
{
public:
Table
()
=
default
;
...
...
src/observer/storage/default/disk_buffer_pool.cpp
浏览文件 @
9446aba8
...
...
@@ -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
);
...
...
src/observer/storage/index/bplus_tree.cpp
浏览文件 @
9446aba8
...
...
@@ -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
;
}
src/observer/storage/index/bplus_tree.h
浏览文件 @
9446aba8
...
...
@@ -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_
;
...
...
src/observer/storage/index/bplus_tree_index.cpp
浏览文件 @
9446aba8
...
...
@@ -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
)
...
...
src/observer/storage/index/bplus_tree_index.h
浏览文件 @
9446aba8
...
...
@@ -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_
;
};
...
...
src/observer/storage/index/index.h
浏览文件 @
9446aba8
...
...
@@ -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
;
...
...
src/observer/util/comparator.cpp
浏览文件 @
9446aba8
...
...
@@ -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
;
}
src/observer/util/comparator.h
浏览文件 @
9446aba8
...
...
@@ -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
);
unitest/bplus_tree_test.cpp
浏览文件 @
9446aba8
...
...
@@ -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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录