Skip to content

Commit a281708

Browse files
authored
Update doc (#60)
1 parent 60d5d32 commit a281708

File tree

18 files changed

+183
-85
lines changed

18 files changed

+183
-85
lines changed

Cargo.toml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "skl"
3-
version = "0.22.17"
3+
version = "0.22.18"
44
edition = "2021"
55
rust-version = "1.81.0"
66
repository = "https://github.com/al8n/skl"
@@ -20,6 +20,14 @@ harness = false
2020
name = "heap"
2121
path = "examples/heap.rs"
2222

23+
[[example]]
24+
name = "generic"
25+
path = "examples/generic.rs"
26+
27+
[[example]]
28+
name = "multiple-version"
29+
path = "examples/multiple_version.rs"
30+
2331
[[example]]
2432
name = "mmap"
2533
path = "examples/mmap.rs"

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
## Features
4242

4343
- **MVCC and 3D access**: Builtin MVCC (multiple versioning concurrency control) and key-value-version access support.
44+
- **Customable Statefull Comparator**: Not limited by `Borrow` and the stateless comparator like `HashMap` or `BTreeMap`, `SkipMap` supports statefull custom comparators.
45+
- **Multiple Maps**: Users can create multiple `SkipMap`s on the same ARENA.
4446
- **Lock-free and Concurrent-Safe:** `SkipMap` provide lock-free operations, ensuring efficient concurrent access without the need for explicit locking mechanisms.
4547
- **Extensible for Key-Value Database Developers:** Designed as a low-level crate, `SkipMap` offer a flexible foundation for key-value database developers. You can easily build your own memtable or durable storage using these structures.
4648
- **Memory Efficiency:** These data structures are optimized for minimal memory overhead. They operate around references, avoiding unnecessary allocations and deep copies, which can be crucial for efficient memory usage.

examples/generic.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use skl::generic::{
2+
unique::{sync::SkipMap, Map},
3+
Builder,
4+
};
5+
6+
pub fn key(i: usize) -> String {
7+
format!("{:05}", i)
8+
}
9+
10+
pub fn new_value(i: usize) -> String {
11+
format!("{:05}", i)
12+
}
13+
14+
fn main() {
15+
const N: usize = 1000;
16+
17+
let l = Builder::new()
18+
.with_capacity(1 << 20)
19+
.alloc::<SkipMap<str, str>>()
20+
.unwrap();
21+
22+
for i in 0..N {
23+
let l = l.clone();
24+
std::thread::spawn(move || {
25+
l.insert(key(i).as_str(), new_value(i).as_str()).unwrap();
26+
});
27+
}
28+
29+
while l.refs() > 1 {}
30+
31+
for i in 0..N {
32+
let l = l.clone();
33+
std::thread::spawn(move || {
34+
let k = key(i);
35+
assert_eq!(
36+
l.get(k.as_str()).unwrap().value(),
37+
new_value(i).as_str(),
38+
"broken: {i}"
39+
);
40+
});
41+
}
42+
}

examples/heap.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
use skl::{
2-
generic::{
3-
unique::{sync::SkipMap, Map},
4-
Builder,
5-
},
6-
Arena,
1+
use skl::dynamic::{
2+
unique::{sync::SkipMap, Map},
3+
Builder,
74
};
85

96
pub fn key(i: usize) -> Vec<u8> {
@@ -19,7 +16,7 @@ fn main() {
1916

2017
let l = Builder::new()
2118
.with_capacity(1 << 20)
22-
.alloc::<SkipMap<[u8], [u8]>>()
19+
.alloc::<SkipMap>()
2320
.unwrap();
2421

2522
for i in 0..N {

examples/mmap.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
use skl::{
2-
generic::{
3-
unique::{sync::SkipMap, Map},
4-
Builder,
5-
},
6-
Arena,
1+
use skl::dynamic::{
2+
unique::{sync::SkipMap, Map},
3+
Builder,
74
};
85

96
pub fn key(i: usize) -> Vec<u8> {
@@ -23,7 +20,7 @@ fn main() {
2320
.with_read(true)
2421
.with_write(true)
2522
.with_create_new(true)
26-
.map_mut::<SkipMap<[u8], [u8]>, _>("test.wal")
23+
.map_mut::<SkipMap, _>("test.wal")
2724
.unwrap()
2825
};
2926

examples/mmap_anon.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
use skl::{
2-
generic::{
3-
unique::{sync::SkipMap, Map},
4-
Builder,
5-
},
6-
Arena,
1+
use skl::dynamic::{
2+
unique::{sync::SkipMap, Map},
3+
Builder,
74
};
85

96
pub fn key(i: usize) -> Vec<u8> {
@@ -19,7 +16,7 @@ fn main() {
1916

2017
let l = Builder::new()
2118
.with_capacity(1 << 20)
22-
.map_anon::<SkipMap<[u8], [u8]>>()
19+
.map_anon::<SkipMap>()
2320
.unwrap();
2421

2522
for i in 0..N {

examples/multiple_maps.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use skl::{
2-
generic::{
2+
dynamic::{
33
unique::{sync::SkipMap, Map},
44
Ascend, Builder,
55
},
@@ -23,10 +23,9 @@ fn main() {
2323
.with_read(true)
2424
.with_write(true)
2525
.with_capacity(1024 * 1024)
26-
.map_mut::<SkipMap<[u8], [u8]>, _>("multiple_maps.wal")
26+
.map_mut::<SkipMap, _>("multiple_maps.wal")
2727
.unwrap();
28-
let l2 =
29-
SkipMap::<[u8], [u8]>::create_from_allocator(l.allocator().clone(), Ascend::new()).unwrap();
28+
let l2 = SkipMap::create_from_allocator(l.allocator().clone(), Ascend::new()).unwrap();
3029
let h2 = l2.header().copied().unwrap();
3130

3231
let t1 = std::thread::spawn(move || {
@@ -55,11 +54,9 @@ fn main() {
5554
.with_read(true)
5655
.with_write(true)
5756
.with_capacity((1024 * 1024 * 2) as u32)
58-
.map_mut::<SkipMap<[u8], [u8]>, _>("multiple_maps.wal")
57+
.map_mut::<SkipMap, _>("multiple_maps.wal")
5958
.unwrap();
60-
let l2 =
61-
SkipMap::<[u8], [u8]>::open_from_allocator(header, l.allocator().clone(), Ascend::new())
62-
.unwrap();
59+
let l2 = SkipMap::open_from_allocator(header, l.allocator().clone(), Ascend::new()).unwrap();
6360
assert_eq!(500, l.len());
6461
assert_eq!(500, l2.len());
6562

examples/multiple_version.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use skl::generic::{
2+
multiple_version::{sync::SkipMap, Map},
3+
Builder,
4+
};
5+
6+
pub fn key(i: usize) -> String {
7+
format!("{:05}", i)
8+
}
9+
10+
pub fn new_value(i: usize) -> String {
11+
format!("{:05}", i)
12+
}
13+
14+
fn main() {
15+
const N: usize = 1000;
16+
17+
let l = Builder::new()
18+
.with_capacity(1 << 20)
19+
.alloc::<SkipMap<str, str>>()
20+
.unwrap();
21+
22+
for i in 0..(N / 2) {
23+
let l = l.clone();
24+
std::thread::spawn(move || {
25+
l.insert(0, key(i).as_str(), new_value(i).as_str()).unwrap();
26+
});
27+
}
28+
29+
for i in (N / 2)..N {
30+
let l = l.clone();
31+
std::thread::spawn(move || {
32+
l.insert(1, key(i).as_str(), new_value(i).as_str()).unwrap();
33+
});
34+
}
35+
36+
while l.refs() > 1 {}
37+
38+
for i in 0..N {
39+
let l = l.clone();
40+
std::thread::spawn(move || {
41+
let k = key(i);
42+
assert_eq!(
43+
l.get(2, k.as_str()).unwrap().value(),
44+
new_value(i).as_str(),
45+
"broken: {i}"
46+
);
47+
});
48+
}
49+
}

integration/src/bin/test-mmap-anon.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
use integration::{big_value, key, new_value};
2-
use skl::{
3-
generic::{
4-
unique::{sync::SkipMap, Map},
5-
Builder,
6-
},
7-
Arena,
2+
use skl::generic::{
3+
unique::{sync::SkipMap, Map},
4+
Builder,
85
};
96

107
fn main() {

integration/src/bin/test-mmap.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
use integration::{key, new_value};
2-
use skl::{
3-
generic::{
4-
unique::{sync::SkipMap, Map},
5-
Builder,
6-
},
7-
Arena,
2+
use skl::generic::{
3+
unique::{sync::SkipMap, Map},
4+
Builder,
85
};
96

107
fn main() {

0 commit comments

Comments
 (0)