做完rust全链路

This commit is contained in:
LIm1tZz7 committed 2026-09-24 21:28:49 +08:00
1 parent e428265357
commit 2a4b446252
34 files changed
+1756 -1031

No files matched your search

+26 -21
View File
@@ -1,10 +1,10 @@
use chusql_storage::btree::DiskBTree;
use chusql_storage::config::{DEFAULT_BTREE_ORDER, DEFAULT_PAGE_SIZE};
use chusql_storage::page::DEFAULT_POOL_SIZE;
// B+ 树测试:空树查询、插入后查找、重开文件数据仍在、覆盖同一个键、升序遍历、
// 倒序插入 500 个键、页大小 / order 可以配置、配置和文件头对不上时报错。
// B+ 树测试:插查、重开、分裂、页大小与 order 校验。
/// 空树的 get 返回 None,遍历返回空。
/// 空树查不到,遍历为空
#[test]
fn empty_tree_get() {
let dir = tempfile::tempdir().unwrap();
@@ -12,13 +12,14 @@ fn empty_tree_get() {
dir.path().join("t.idx"),
DEFAULT_PAGE_SIZE,
DEFAULT_BTREE_ORDER,
DEFAULT_POOL_SIZE,
)
.unwrap();
assert_eq!(t.get(1).unwrap(), None);
assert_eq!(t.iter_all().unwrap(), vec![]);
}
/// 插 100 个键,每个都能按 key 查回来。
/// 插 100 个键都能查回
#[test]
fn insert_then_get() {
let dir = tempfile::tempdir().unwrap();
@@ -26,6 +27,7 @@ fn insert_then_get() {
dir.path().join("t.idx"),
DEFAULT_PAGE_SIZE,
DEFAULT_BTREE_ORDER,
DEFAULT_POOL_SIZE,
)
.unwrap();
for i in 0..100 {
@@ -36,24 +38,24 @@ fn insert_then_get() {
}
}
/// 关掉再打开同一个索引文件,数据还在。
/// 重开文件数据还在
#[test]
fn reopen_persists() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("t.idx");
{
let mut t = DiskBTree::open(&path, DEFAULT_PAGE_SIZE, DEFAULT_BTREE_ORDER).unwrap();
let mut t = DiskBTree::open(&path, DEFAULT_PAGE_SIZE, DEFAULT_BTREE_ORDER, DEFAULT_POOL_SIZE).unwrap();
for i in 0..50 {
t.insert(i, i as u64).unwrap();
}
}
let mut t = DiskBTree::open(&path, DEFAULT_PAGE_SIZE, DEFAULT_BTREE_ORDER).unwrap();
let mut t = DiskBTree::open(&path, DEFAULT_PAGE_SIZE, DEFAULT_BTREE_ORDER, DEFAULT_POOL_SIZE).unwrap();
for i in 0..50 {
assert_eq!(t.get(i).unwrap(), Some(i as u64));
}
}
/// 同一个键插两次,后写的值生效。
/// 同一个键后写的值生效
#[test]
fn update_existing() {
let dir = tempfile::tempdir().unwrap();
@@ -61,6 +63,7 @@ fn update_existing() {
dir.path().join("t.idx"),
DEFAULT_PAGE_SIZE,
DEFAULT_BTREE_ORDER,
DEFAULT_POOL_SIZE,
)
.unwrap();
t.insert(5, 100).unwrap();
@@ -68,7 +71,7 @@ fn update_existing() {
assert_eq!(t.get(5).unwrap(), Some(200));
}
/// 倒序插入后遍历,结果仍按 key 升序。
/// 倒序插入后遍历仍升序
#[test]
fn iter_all_sorted() {
let dir = tempfile::tempdir().unwrap();
@@ -76,6 +79,7 @@ fn iter_all_sorted() {
dir.path().join("t.idx"),
DEFAULT_PAGE_SIZE,
DEFAULT_BTREE_ORDER,
DEFAULT_POOL_SIZE,
)
.unwrap();
for i in (0..50).rev() {
@@ -88,7 +92,7 @@ fn iter_all_sorted() {
}
}
/// 倒序插入 500 个键(必然多次分裂),每个键都能查到。
/// 倒序插 500 个键都能查到
#[test]
fn reverse_order_insert() {
let dir = tempfile::tempdir().unwrap();
@@ -96,6 +100,7 @@ fn reverse_order_insert() {
dir.path().join("t.idx"),
DEFAULT_PAGE_SIZE,
DEFAULT_BTREE_ORDER,
DEFAULT_POOL_SIZE,
)
.unwrap();
for i in (0..500).rev() {
@@ -106,11 +111,11 @@ fn reverse_order_insert() {
}
}
/// 页大小和 order 都可以配置:512 字节的页 + 8 个孩子照样能插能查。
/// 512 字节页 + 8 个孩子可用
#[test]
fn custom_page_size_and_order() {
let dir = tempfile::tempdir().unwrap();
let mut t = DiskBTree::open(dir.path().join("t.idx"), 512, 8).unwrap();
let mut t = DiskBTree::open(dir.path().join("t.idx"), 512, 8, DEFAULT_POOL_SIZE).unwrap();
for i in 0..200 {
t.insert(i, i as u64 + 1).unwrap();
}
@@ -119,32 +124,32 @@ fn custom_page_size_and_order() {
}
}
/// 文件头里记着页大小和 order:换配置再打开要报错,而不是读出乱七八糟的东西。
/// 页大小或 order 不符要报错
#[test]
fn config_mismatch_errors() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("t.idx");
{
let mut t = DiskBTree::open(&path, DEFAULT_PAGE_SIZE, DEFAULT_BTREE_ORDER).unwrap();
let mut t = DiskBTree::open(&path, DEFAULT_PAGE_SIZE, DEFAULT_BTREE_ORDER, DEFAULT_POOL_SIZE).unwrap();
t.insert(1, 1).unwrap();
}
assert!(DiskBTree::open(&path, DEFAULT_PAGE_SIZE, 8).is_err());
assert!(DiskBTree::open(&path, 8192, DEFAULT_BTREE_ORDER).is_err());
assert!(DiskBTree::open(&path, DEFAULT_PAGE_SIZE, DEFAULT_BTREE_ORDER).is_ok());
assert!(DiskBTree::open(&path, DEFAULT_PAGE_SIZE, 8, DEFAULT_POOL_SIZE).is_err());
assert!(DiskBTree::open(&path, 8192, DEFAULT_BTREE_ORDER, DEFAULT_POOL_SIZE).is_err());
assert!(DiskBTree::open(&path, DEFAULT_PAGE_SIZE, DEFAULT_BTREE_ORDER, DEFAULT_POOL_SIZE).is_ok());
}
/// 不是本项目的索引文件(比如随便一个空文件)要报错。
/// 不是索引文件要报错
#[test]
fn not_an_index_file_errors() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("junk.idx");
std::fs::write(&path, vec![7u8; DEFAULT_PAGE_SIZE]).unwrap();
assert!(DiskBTree::open(&path, DEFAULT_PAGE_SIZE, DEFAULT_BTREE_ORDER).is_err());
assert!(DiskBTree::open(&path, DEFAULT_PAGE_SIZE, DEFAULT_BTREE_ORDER, DEFAULT_POOL_SIZE).is_err());
}
/// order 放不进一页时直接拒绝。
/// order 放不进一页要报错
#[test]
fn order_too_large_for_page_errors() {
let dir = tempfile::tempdir().unwrap();
assert!(DiskBTree::open(dir.path().join("t.idx"), 512, 300).is_err());
assert!(DiskBTree::open(dir.path().join("t.idx"), 512, 300, DEFAULT_POOL_SIZE).is_err());
}