From e7244823138074359db7bc0e083e1d031fee7598 Mon Sep 17 00:00:00 2001 From: Kould <2435992353@qq.com> Date: Tue, 1 Aug 2023 00:12:18 +0800 Subject: [PATCH] Docs/examples (#40) * example: a new example 'simple_crud' has been added to briefly introduce basic operations * feat(examples): add `mvcc` and `scan_read` to demonstrate scan and transaction functions respectively * docs: version up * style: code format * style: `partial_cmp` code format --- Cargo.toml | 2 +- README.md | 4 +-- examples/mvcc.rs | 42 ++++++++++++++++++++++ examples/scan_read.rs | 36 +++++++++++++++++++ examples/simple_crud.rs | 48 +++++++++++++++++++++++++ src/bin/cli.rs | 1 + src/kernel/lsm/iterator/merging_iter.rs | 5 +-- src/kernel/lsm/mem_table.rs | 5 +-- src/kernel/lsm/storage.rs | 5 ++- src/kernel/lsm/version/edit.rs | 2 +- src/kernel/utils/lru_cache.rs | 4 +-- 11 files changed, 137 insertions(+), 17 deletions(-) create mode 100644 examples/mvcc.rs create mode 100644 examples/scan_read.rs create mode 100644 examples/simple_crud.rs diff --git a/Cargo.toml b/Cargo.toml index 00d0657..6bced33 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kip_db" -version = "0.1.1-alpha.0" +version = "0.1.2-alpha.0" edition = "2021" authors = ["Kould "] description = "轻量级、异步 基于LSM Leveled Compaction K-V数据库" diff --git a/README.md b/README.md index a9421b9..b00eb95 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ ## 快速上手 🤞 #### 组件引入 ``` toml -kip_db = "0.1.1-alpha.0" +kip_db = "0.1.2-alpha.0" ``` ### 代码编译 #### 基本编译 @@ -255,7 +255,7 @@ PS D:\Workspace\kould\KipDB\target\release> ./cli batch-get kould kipdb 参考自:https://chinggg.github.io/post/docker-perf/ -### 如果你想参与我们的工作、提供更好的意见或抱着一起学习的心态,欢迎联系我以加入群聊 +### 如果你想参与KipDB或[KipSQL](https://github.com/KipData/KipSQL),欢迎通过下方微信二维码与我交流 ![微信联系方式](./static/images/wechat.png) ### Thanks For diff --git a/examples/mvcc.rs b/examples/mvcc.rs new file mode 100644 index 0000000..20d9e40 --- /dev/null +++ b/examples/mvcc.rs @@ -0,0 +1,42 @@ +use bytes::Bytes; +use kip_db::kernel::lsm::storage::{Config, KipStorage}; +use kip_db::kernel::Storage; +use kip_db::KernelError; +use tempfile::TempDir; + +#[tokio::main] +async fn main() -> Result<(), KernelError> { + let temp_dir = TempDir::new().expect("unable to create temporary working directory"); + let config = Config::new(temp_dir.into_path()).enable_level_0_memorization(); + let kip_storage = KipStorage::open_with_config(config).await?; + + println!("New Transaction"); + let mut tx = kip_storage.new_transaction().await; + + println!("Set KeyValue after the transaction -> (key_1, value_1)"); + kip_storage + .set(b"key_1", Bytes::copy_from_slice(b"value_1")) + .await?; + + println!("Read key_1 on the transaction: {:?}", tx.get(b"key_1")?); + + println!("Set KeyValue on the transaction -> (key_2, value_2)"); + tx.set(b"key_2", Bytes::copy_from_slice(b"value_2")); + + println!("Read key_2 on the transaction: {:?}", tx.get(b"key_2")?); + + println!( + "Read key_2 on the storage: {:?}", + kip_storage.get(b"key_2").await? + ); + + println!("Commit this transaction"); + tx.commit().await?; + + println!( + "Read key_2 on the storage again!: {:?}", + kip_storage.get(b"key_2").await? + ); + + Ok(()) +} diff --git a/examples/scan_read.rs b/examples/scan_read.rs new file mode 100644 index 0000000..14e1379 --- /dev/null +++ b/examples/scan_read.rs @@ -0,0 +1,36 @@ +use bytes::Bytes; +use kip_db::kernel::lsm::storage::{Config, KipStorage}; +use kip_db::kernel::Storage; +use kip_db::KernelError; +use std::collections::Bound; +use tempfile::TempDir; + +#[tokio::main] +async fn main() -> Result<(), KernelError> { + let temp_dir = TempDir::new().expect("unable to create temporary working directory"); + let config = Config::new(temp_dir.into_path()).enable_level_0_memorization(); + let kip_storage = KipStorage::open_with_config(config).await?; + + println!("Set KeyValue -> (key_1, value_1)"); + kip_storage + .set(b"key_1", Bytes::copy_from_slice(b"value_1")) + .await?; + println!("Set KeyValue -> (key_2, value_2)"); + kip_storage + .set(b"key_2", Bytes::copy_from_slice(b"value_2")) + .await?; + println!("Set KeyValue -> (key_3, value_3)"); + kip_storage + .set(b"key_3", Bytes::copy_from_slice(b"value_3")) + .await?; + + println!("New Transaction"); + let tx = kip_storage.new_transaction().await; + + println!( + "RangeScan without key_3 By Transaction: {:?}", + tx.range_scan(Bound::Unbounded, Bound::Excluded(b"key_3"))? + ); + + Ok(()) +} diff --git a/examples/simple_crud.rs b/examples/simple_crud.rs new file mode 100644 index 0000000..ba224f6 --- /dev/null +++ b/examples/simple_crud.rs @@ -0,0 +1,48 @@ +use bytes::Bytes; +use kip_db::kernel::lsm::storage::{Config, KipStorage}; +use kip_db::kernel::{CommandData, Storage}; +use kip_db::KernelError; +use tempfile::TempDir; + +#[tokio::main] +async fn main() -> Result<(), KernelError> { + let temp_dir = TempDir::new().expect("unable to create temporary working directory"); + let config = Config::new(temp_dir.into_path()).enable_level_0_memorization(); + let kip_storage = KipStorage::open_with_config(config).await?; + + println!("Set KeyValue -> (apple, banana)"); + kip_storage + .set(b"apple", Bytes::copy_from_slice(b"banana")) + .await?; + + println!( + "Get Key: apple -> Value: {:?}", + kip_storage.get(b"apple").await? + ); + println!("SizeOfDisk: {}", kip_storage.size_of_disk().await?); + println!("Len: {}", kip_storage.len().await?); + println!("IsEmpty: {}", kip_storage.is_empty().await); + + kip_storage.flush().await?; + + let join_cmd_1 = vec![ + CommandData::set(b"moon".to_vec(), b"star".to_vec()), + // CommandData::remove(b"apple".to_vec()), + ]; + println!( + "Join 1: {:?} -> {:?}", + join_cmd_1.clone(), + kip_storage.join(join_cmd_1).await? + ); + let join_cmd_2 = vec![ + CommandData::get(b"moon".to_vec()), + CommandData::get(b"apple".to_vec()), + ]; + println!( + "Join 2: {:?} -> {:?}", + join_cmd_2.clone(), + kip_storage.join(join_cmd_2).await? + ); + + Ok(()) +} diff --git a/src/bin/cli.rs b/src/bin/cli.rs index df5a8e7..5b500d1 100644 --- a/src/bin/cli.rs +++ b/src/bin/cli.rs @@ -85,6 +85,7 @@ async fn main() -> Result<()> { Ok(()) } +#[allow(clippy::needless_pass_by_ref_mut)] async fn batch_set(client: &mut Client, batch: Vec) -> Result { if batch.len() % 2 != 0 { error!( diff --git a/src/kernel/lsm/iterator/merging_iter.rs b/src/kernel/lsm/iterator/merging_iter.rs index 41f9eeb..8f360da 100644 --- a/src/kernel/lsm/iterator/merging_iter.rs +++ b/src/kernel/lsm/iterator/merging_iter.rs @@ -16,10 +16,7 @@ struct IterKey { impl PartialOrd for IterKey { fn partial_cmp(&self, other: &Self) -> Option { - self.key.partial_cmp(&other.key).and_then(|ord| match ord { - Ordering::Equal => self.num.partial_cmp(&other.num), - ordering => Some(ordering), - }) + Some(self.cmp(other)) } } diff --git a/src/kernel/lsm/mem_table.rs b/src/kernel/lsm/mem_table.rs index 0c12f01..810a653 100644 --- a/src/kernel/lsm/mem_table.rs +++ b/src/kernel/lsm/mem_table.rs @@ -41,10 +41,7 @@ pub(crate) struct InternalKey { impl PartialOrd for InternalKey { fn partial_cmp(&self, other: &Self) -> Option { - self.key.partial_cmp(&other.key).and_then(|ord| match ord { - Ordering::Equal => self.seq_id.partial_cmp(&other.seq_id), - ordering => Some(ordering), - }) + Some(self.cmp(other)) } } diff --git a/src/kernel/lsm/storage.rs b/src/kernel/lsm/storage.rs index a237e10..22394d1 100644 --- a/src/kernel/lsm/storage.rs +++ b/src/kernel/lsm/storage.rs @@ -39,8 +39,7 @@ pub(crate) const BANNER: &str = " ▒▒▒▒▒ ▒▒▒▒ ▒▒▒▒▒ ▒███▒▒▒ ▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒ ▒███ █████ - ▒▒▒▒▒ -Version: 0.1.1-alpha.0"; + ▒▒▒▒▒"; pub(crate) const DEFAULT_MINOR_THRESHOLD_WITH_SIZE_WITH_MEM: usize = 2 * 1024 * 1024; @@ -203,7 +202,7 @@ impl KipStorage { where Self: Sized, { - info!("{}", BANNER); + info!("{} \nVersion: {}", BANNER, env!("CARGO_PKG_VERSION")); Gen::init(); // 若lockfile的文件夹路径不存在则创建 fs::create_dir_all(&config.dir_path)?; diff --git a/src/kernel/lsm/version/edit.rs b/src/kernel/lsm/version/edit.rs index 8743c0c..626ae8c 100644 --- a/src/kernel/lsm/version/edit.rs +++ b/src/kernel/lsm/version/edit.rs @@ -38,6 +38,6 @@ impl Ord for EditType { impl PartialOrd for EditType { fn partial_cmp(&self, other: &Self) -> Option { - self.ord_num().partial_cmp(&other.ord_num()) + Some(self.cmp(other)) } } diff --git a/src/kernel/utils/lru_cache.rs b/src/kernel/utils/lru_cache.rs index 69a534a..9b30b8f 100644 --- a/src/kernel/utils/lru_cache.rs +++ b/src/kernel/utils/lru_cache.rs @@ -22,7 +22,7 @@ unsafe impl Sync for NodeReadPtr {} impl Clone for NodeReadPtr { fn clone(&self) -> Self { - NodeReadPtr(self.0) + *self } } @@ -81,7 +81,7 @@ impl PartialEq for KeyRef { impl PartialOrd for KeyRef { fn partial_cmp(&self, other: &Self) -> Option { - unsafe { self.0.as_ref().key.partial_cmp(&other.0.as_ref().key) } + Some(self.cmp(other)) } }