diff --git a/README.md b/README.md index c0eb1c4..1638278 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ English | [简体中文][zh-cn-url] - Lock-free and concurrent safe read transaction: the read transaction is totally concurrent safe and can be shared in multiple threads, there is no lock in read transaction. - `BTreeMap` like user friendly API and all iterators implement `Iterator` trait, which means users use Rust powerful conbinators when iterating over the database. - Async version is runtime agnostic, `tokio`, `async-std`, `smol`, `wasm-bindgen-futures` and any other async runtime. -- 100% safe, skipdb sets `[forbid(unsafe_code)]`. +- 100% safe, sets `[forbid(unsafe_code)]`. ## Installation diff --git a/async-skipdb/Cargo.toml b/async-skipdb/Cargo.toml index 1f6e279..b0f080d 100644 --- a/async-skipdb/Cargo.toml +++ b/async-skipdb/Cargo.toml @@ -1,13 +1,15 @@ [package] name = "async-skipdb" -version.workspace = true +version = "0.1.3" rust-version.workspace = true edition.workspace = true repository.workspace = true homepage.workspace = true documentation = "https://docs.rs/async-skipdb" -description = "A blazing fast ACID, MVCC and SSI in memory database based on lock-free skiplist." +description = "An embedded, in-memory, ACID, MVCC, almost lock-free and serializable snapshot isolation database engine." license.workspace = true +keywords = ["database", "key-value-store", "memdb", "embedded-database", "memodb"] +categories = ["database-implementations", "concurrency", "data-structures", "asynchronous"] [features] default = [] diff --git a/async-skipdb/README-zh_CN.md b/async-skipdb/README-zh_CN.md index d920637..51b5a8b 100644 --- a/async-skipdb/README-zh_CN.md +++ b/async-skipdb/README-zh_CN.md @@ -1,5 +1,5 @@
-

SkipDB

+

Async SkipDB

diff --git a/async-skipdb/README.md b/async-skipdb/README.md index d920637..f0da192 100644 --- a/async-skipdb/README.md +++ b/async-skipdb/README.md @@ -1,5 +1,5 @@
-

SkipDB

+

Async SkipDB

@@ -40,7 +40,7 @@ For sync version, please see [`skipdb`](https://crates.io/crates/skipdb). - Lock-free and concurrent safe read transaction: the read transaction is totally concurrent safe and can be shared in multiple threads, there is no lock in read transaction. - `BTreeMap` like user friendly API and all iterators implement `Iterator` trait, which means users use Rust powerful conbinators when iterating over the database. - Runtime agnostic, `tokio`, `async-std`, `smol`, `wasm-bindgen-futures` and any other async runtime. -- 100% safe, skipdb sets `[forbid(unsafe_code)]`. +- 100% safe, sets `[forbid(unsafe_code)]`. ## Installation diff --git a/skipdb/Cargo.toml b/skipdb/Cargo.toml index 7a2b77c..1c5a92d 100644 --- a/skipdb/Cargo.toml +++ b/skipdb/Cargo.toml @@ -1,13 +1,15 @@ [package] name = "skipdb" -version.workspace = true +version = "0.1.3" rust-version.workspace = true edition.workspace = true repository.workspace = true homepage.workspace = true documentation = "https://docs.rs/skipdb" -description = "A blazing fast ACID, MVCC and SSI in memory database based on lock-free skiplist." +description = "An embedded, in-memory, ACID, MVCC, almost lock-free and serializable snapshot isolation database engine." license.workspace = true +keywords = ["database", "key-value-store", "memdb", "embedded-database", "memodb"] +categories = ["database-implementations", "concurrency", "data-structures"] [features] default = [] diff --git a/skipdb/README-zh_CN.md b/skipdb/README-zh_CN.md index ab12bb5..e51044c 100644 --- a/skipdb/README-zh_CN.md +++ b/skipdb/README-zh_CN.md @@ -1,5 +1,5 @@
-

SkiplistDB

+

SkipDB

@@ -18,7 +18,7 @@ Blazing fast ACID and MVCC in memory database based on lock-free skiplist. [crates.io][crates-url] -[English][en-us-url] | 简体中文 +English | [简体中文][zh-cn-url]
@@ -28,13 +28,122 @@ Blazing fast ACID and MVCC in memory database based on lock-free skiplist. `skipdb` uses the same SSI (Serializable Snapshot Isolation) transaction model used in [`badger`](https://github.com/dgraph-io/badger). +For async usage, please see [`async-skipdb`](https://crates.io/crates/async-skipdb). + +## Features + +- ACID, MVCC, serializable snapshot isolation, concurrent safe and almost lock-free. +- No extra allocation and copy, there is no `Arc` wrapper for both key and value stored in the database, which means that users provide `K` and `V`, and database store `K` and `V` directly. +- Zero-copy and in-place compaction, which means there is no copy, no extra allocation when compacting. +- Concurrent execution of transactions, providing serializable snapshot isolation, avoiding write skews. +- Both read transaction and write transaction are `Send + Sync + 'static`, which means you do not need to handle annoying lifetime problem anymore. +- Lock-free and concurrent safe read transaction: the read transaction is totally concurrent safe and can be shared in multiple threads, there is no lock in read transaction. +- `BTreeMap` like user friendly API and all iterators implement `Iterator` trait, which means users use Rust powerful conbinators when iterating over the database. +- 100% safe, sets `[forbid(unsafe_code)]`. + ## Installation ```toml [dependencies] -skipdb = "0.0.0" +skipdb = "0.1" ``` +## Example + +- If your `K` implement `Hash`. + + ```rust + use skipdb::equivalent::EquivalentDb; + + #[derive(Debug)] + struct Person { + hobby: String, + age: u8, + } + + fn main() { + let db: EquivalentDb = EquivalentDb::new(); + + { + let alice = Person { hobby: "swim".to_string(), age: 20 }; + let bob = Person { hobby: "run".to_string(), age: 30 }; + + let mut txn = db.write(); + txn.insert("Alice".to_string(), alice).unwrap(); + txn.insert("Bob".to_string(), bob).unwrap(); + + { + let alice = txn.get("Alice").unwrap().unwrap(); + assert_eq!(alice.value().age, 20); + assert_eq!(alice.value().hobby, "swim"); + } + + txn.commit().unwrap(); + } + + { + let txn = db.read(); + let alice = txn.get("Alice").unwrap(); + assert_eq!(alice.value().age, 20); + assert_eq!(alice.value().hobby, "swim"); + + let bob = txn.get("Bob").unwrap(); + assert_eq!(bob.value().age, 30); + assert_eq!(bob.value().hobby, "run"); + } + } + ``` + +- If your key cannot implement `Hash` for some reasons. + + Then you can use `ComparableDb`, but this will require `K: CheapClone + Ord`, you can see [`cheap_clone`](https://crates.io/crates/cheap-clone) trait for more details. + + ```rust + use skipdb::comparable::ComparableDb; + + #[derive(Debug)] + struct Person { + name: String, + hobby: String, + age: u8, + } + + fn main() { + let db: ComparableDb = ComparableDb::new(); + + { + let alice = Person { name: "Alice".to_string(), hobby: "swim".to_string(), age: 20 }; + let bob = Person { name: "Bob".to_string(), hobby: "run".to_string(), age: 30 }; + + let mut txn = db.write(); + txn.insert(1, alice).unwrap(); + txn.insert(2, bob).unwrap(); + + { + let alice = txn.get(&1).unwrap().unwrap(); + assert_eq!(alice.value().name, "Alice"); + assert_eq!(alice.value().age, 20); + assert_eq!(alice.value().hobby, "swim"); + } + + txn.commit().unwrap(); + } + + { + let txn = db.read(); + let alice = txn.get(&1).unwrap(); + assert_eq!(alice.value().name, "Alice"); + assert_eq!(alice.value().age, 20); + assert_eq!(alice.value().hobby, "swim"); + + let bob = txn.get(&2).unwrap(); + assert_eq!(bob.value().name, "Bob"); + assert_eq!(bob.value().age, 30); + assert_eq!(bob.value().hobby, "run"); + } + } + ``` + #### License `skipdb` is under the terms of both the MIT license and the @@ -49,4 +158,4 @@ Copyright (c) 2024 Al Liu. [doc-url]: https://docs.rs/skipdb [crates-url]: https://crates.io/crates/skipdb [codecov-url]: https://app.codecov.io/gh/al8n/skipdb/ -[en-us-url]: https://github.com/al8n/skipdb/tree/main/README.md +[zh-cn-url]: https://github.com/al8n/skipdb/tree/main/README-zh_CN.md diff --git a/skipdb/README.md b/skipdb/README.md index bccb85e..e51044c 100644 --- a/skipdb/README.md +++ b/skipdb/README.md @@ -39,7 +39,7 @@ For async usage, please see [`async-skipdb`](https://crates.io/crates/async-skip - Both read transaction and write transaction are `Send + Sync + 'static`, which means you do not need to handle annoying lifetime problem anymore. - Lock-free and concurrent safe read transaction: the read transaction is totally concurrent safe and can be shared in multiple threads, there is no lock in read transaction. - `BTreeMap` like user friendly API and all iterators implement `Iterator` trait, which means users use Rust powerful conbinators when iterating over the database. -- 100% safe, skipdb sets `[forbid(unsafe_code)]`. +- 100% safe, sets `[forbid(unsafe_code)]`. ## Installation