Skip to content

Commit 8927bf5

Browse files
authored
Merge pull request #168 from vbogdanb/add-exmaple-one-page
Add C++ and rust examples readme
2 parents f0b65e2 + b45a14b commit 8927bf5

1 file changed

Lines changed: 202 additions & 0 deletions

File tree

examples/README.md

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
2+
# Getting Started with Key-Value-Storage (persistency)
3+
4+
This guide will help you get started with the C++ and Rust implementations of the Key-Value-Storage (KVS) library, including how to use it and link it with Bazel.
5+
6+
## 1. Integrating with Bazel
7+
8+
### 1.1 Add this to your MODULE.bazel:
9+
<details>
10+
<summary>MODULE.bazel</summary>
11+
12+
module(name = "your_project_name")
13+
14+
# Add the persistency dependency (replace version as needed)
15+
bazel_dep(name = "persistency", version = "0.2.0")
16+
17+
# Add required toolchains and dependencies for C++ and Rust
18+
bazel_dep(name = "score_toolchains_gcc", version = "0.4", dev_dependency=True)
19+
gcc = use_extension("@score_toolchains_gcc//extentions:gcc.bzl", "gcc", dev_dependency=True)
20+
gcc.toolchain(
21+
url = "https://github.com/eclipse-score/toolchains_gcc_packages/releases/download/0.0.1/x86_64-unknown-linux-gnu_gcc12.tar.gz",
22+
sha256 = "457f5f20f57528033cb840d708b507050d711ae93e009388847e113b11bf3600",
23+
strip_prefix = "x86_64-unknown-linux-gnu",
24+
)
25+
use_repo(gcc, "gcc_toolchain", "gcc_toolchain_gcc")
26+
27+
bazel_dep(name = "rules_rust", version = "0.61.0")
28+
crate = use_extension("@rules_rust//crate_universe:extensions.bzl", "crate")
29+
crate.from_specs(name = "crate_index")
30+
use_repo(crate, "crate_index")
31+
32+
# Add any other dependencies required by persistency (see persistency's own MODULE.bazel for details)
33+
34+
</details>
35+
36+
### 1.2 Insert this into your .bazelrc:
37+
<details>
38+
<summary>.bazelrc</summary>
39+
40+
```
41+
build --@score_baselibs//score/json:base_library=nlohmann
42+
build --@score_baselibs//score/mw/log/flags:KRemote_Logging=False
43+
44+
```
45+
</details>
46+
47+
### 1.3 Run Bazel
48+
If you start with a plain project add an empty file called `BUILD` into your project folder.
49+
50+
Now you can build the project with the command:
51+
```sh
52+
bazel build //...
53+
```
54+
(So far nothing happens, because no targets were defined.)
55+
56+
You can now continue in this guide to create a simple consumer-producer program or start on your own.
57+
58+
59+
60+
## 2. Using the C++ Implementation
61+
62+
### 2.1 Basic Usage
63+
64+
The C++ API is centered around `KvsBuilder` and `Kvs` classes. Here is a minimal example based on the test scenarios:
65+
66+
```cpp
67+
#include "kvsbuilder.hpp"
68+
#include <iostream>
69+
70+
int main() {
71+
// Use fully qualified names instead of 'using namespace'
72+
auto open_res = score::mw::per::kvs::KvsBuilder(score::mw::per::kvs::InstanceId(0))
73+
.need_defaults_flag(true)
74+
.need_kvs_flag(false)
75+
.dir(".")
76+
.build();
77+
if (!open_res) {
78+
std::cerr << "Failed to open KVS: " << static_cast<int>(open_res.error()) << std::endl;
79+
return 1;
80+
}
81+
score::mw::per::kvs::Kvs kvs = std::move(open_res.value());
82+
83+
// Set a key-value pair
84+
kvs.set_value("username", score::mw::per::kvs::KvsValue("alice"));
85+
86+
// Read a value (will fall back to default if not set)
87+
score::mw::per::kvs::Result<score::mw::per::kvs::KvsValue> get_res = kvs.get_value("username");
88+
if (get_res) {
89+
std::cout << "username: " << get_res.value().as_string() << std::endl;
90+
}
91+
92+
// Read a default value (not set, but present in defaults)
93+
auto get_default = kvs.get_value("language");
94+
if (get_default) {
95+
std::cout << "language (default): " << get_default.value().as_string() << std::endl;
96+
}
97+
98+
// Check if a key exists (only if written)
99+
if (kvs.key_exists("username").value_or(false)) {
100+
std::cout << "username exists!" << std::endl;
101+
}
102+
103+
// Remove a key
104+
kvs.remove_key("username");
105+
106+
// List all keys (only written keys, not defaults)
107+
auto keys_res = kvs.get_all_keys();
108+
if (keys_res) {
109+
std::cout << "All keys in KVS:" << std::endl;
110+
for (const auto& key : keys_res.value()) {
111+
std::cout << " " << key << std::endl;
112+
}
113+
}
114+
115+
// Flush changes to disk
116+
kvs.flush();
117+
118+
return 0;
119+
}
120+
```
121+
122+
## 3. Using the Rust Implementation
123+
124+
### 3.1 Basic Usage
125+
126+
From `examples/basic.rs`:
127+
```rust
128+
use rust_kvs::prelude::*;
129+
use std::collections::HashMap;
130+
use tempfile::tempdir;
131+
132+
fn main() -> Result<(), ErrorCode> {
133+
let dir = tempdir()?;
134+
let dir_string = dir.path().to_string_lossy().to_string();
135+
let instance_id = InstanceId(0);
136+
137+
// Build KVS instance
138+
let builder = KvsBuilder::new(instance_id)
139+
.dir(dir_string.clone())
140+
.kvs_load(KvsLoad::Optional);
141+
let kvs = builder.build()?;
142+
143+
// Set values
144+
kvs.set_value("number", 123.0)?;
145+
kvs.set_value("bool", true)?;
146+
kvs.set_value("string", "First")?;
147+
148+
// Get value
149+
let value = kvs.get_value("number")?;
150+
println!("number = {:?}", value);
151+
152+
Ok(())
153+
}
154+
```
155+
156+
### 3.2 Snapshots Example
157+
158+
From `examples/snapshots.rs`:
159+
```rust
160+
let max_count = kvs.snapshot_max_count() as u32;
161+
for index in 0..max_count {
162+
kvs.set_value("counter", index)?;
163+
kvs.flush()?;
164+
println!("Snapshot count: {:?}", kvs.snapshot_count());
165+
}
166+
167+
// Restore a snapshot
168+
kvs.snapshot_restore(SnapshotId(2))?;
169+
```
170+
171+
### 3.3 Defaults Example
172+
173+
From `examples/defaults.rs`:
174+
```rust
175+
// Create defaults file and build KVS instance with defaults
176+
create_defaults_file(dir.path().to_path_buf(), instance_id)?;
177+
let builder = KvsBuilder::new(instance_id)
178+
.dir(dir_string)
179+
.defaults(KvsDefaults::Required);
180+
let kvs = builder.build()?;
181+
182+
// Get default value
183+
let k1_value = kvs.get_default_value("k1")?;
184+
println!("k1 = {:?}", k1_value);
185+
```
186+
## 4. Default value file example
187+
This file should be placed in the working directory:
188+
```json
189+
{
190+
"language": "en",
191+
"theme": "dark",
192+
"timeout": 30
193+
}
194+
```
195+
196+
**Important:**
197+
- If you open the KVS with `.need_defaults_flag(true)`, the file must exist.
198+
- The KVS will use these defaults for any key not explicitly set.
199+
- You must also provide a CRC file (e.g., `defaults.json.crc`) alongside the defaults file. This CRC file is generated using the Adler-32 checksum algorithm, as implemented in the codebase. The CRC ensures the integrity of the defaults file at runtime.
200+
## 5. More Examples
201+
- See `src/cpp/tests/` for C++ test scenarios and usage patterns.
202+
- See `src/rust/rust_kvs/examples/` for Rust usage patterns.

0 commit comments

Comments
 (0)