pub struct DB {
pub path: PathBuf,
/* private fields */
}Expand description
This is the main struct which represents the database.
This struct holds the connection to the sled database and provides
safe, high-level access to the various data trees. It manages a background
thread for handling TTL (Time-To-Live) expirations automatically.
When this struct is dropped, it will signal the background thread to shut down and wait for it to finish gracefully.
This struct also holds 2 Arcsled::Tree directly instead of a single sled::Db, since almost all of the functions uses the tree directly which requires the sled::Db to constantly open each trees. Passing trees from the struct deletes the constant need to open the trees
Fields§
§path: PathBufPath to the database
Implementations§
Source§impl DB
impl DB
Sourcepub fn transaction<F>(&self, f: F) -> Result<(), TransientError>
pub fn transaction<F>(&self, f: F) -> Result<(), TransientError>
Examples found in repository?
8fn main() -> Result<(), Box<dyn Error>> {
9 // 1. Setup a temporary database for the example.
10 let temp_dir = tempdir()?;
11 let db = DB::new(temp_dir.path())?;
12
13 println!("Database created successfully.");
14
15 // 2. Set the initial state for two user accounts.
16 db.set("user:alice", "100", None)?;
17 db.set("user:bob", "50", None)?;
18
19 println!("Initial state:");
20 println!(" - Alice's balance: {}", db.get("user:alice")?.unwrap());
21 println!(" - Bob's balance: {}", db.get("user:bob")?.unwrap());
22 println!("\nAttempting to transfer 20 from Alice to Bob...");
23
24 // 3. Run the atomic transfer inside a transaction.
25 let transaction_result = db.transaction(|tx| {
26 // Get the current balances.
27 let alice_balance_str = tx.get("user:alice")?.unwrap();
28 let bob_balance_str = tx.get("user:bob")?.unwrap();
29
30 let mut alice_balance: u64 = alice_balance_str.parse()?;
31 let mut bob_balance: u64 = bob_balance_str.parse()?;
32
33 let transfer_amount = 20;
34
35 // Check if the transfer is possible.
36 if alice_balance < transfer_amount {
37 // By returning an error, we abort the entire transaction.
38 // No changes will be saved.
39 return Err(Box::from("Alice has insufficient funds!"));
40 }
41
42 // Perform the transfer.
43 alice_balance -= transfer_amount;
44 bob_balance += transfer_amount;
45
46 // Save the new balances.
47 tx.set("user:alice", &alice_balance.to_string(), None)?;
48 tx.set("user:bob", &bob_balance.to_string(), None)?;
49
50 // Return Ok to commit the transaction.
51 Ok(())
52 });
53
54 // 4. Check if the transaction succeeded.
55 if let Err(e) = transaction_result {
56 println!("\nTransaction failed: {}", e);
57 } else {
58 println!("\nTransaction successful!");
59 }
60
61 // 5. Verify the final state of the database.
62 // The balances should be updated because the transaction succeeded.
63 println!("\nFinal state:");
64 println!(" - Alice's balance: {}", db.get("user:alice")?.unwrap());
65 println!(" - Bob's balance: {}", db.get("user:bob")?.unwrap());
66
67 assert_eq!(db.get("user:alice")?.unwrap(), "80");
68 assert_eq!(db.get("user:bob")?.unwrap(), "70");
69
70 Ok(())
71}Source§impl DB
impl DB
Sourcepub fn new(path: &Path) -> Result<DB, TransientError>
pub fn new(path: &Path) -> Result<DB, TransientError>
Creates a new DB instance or opens an existing one at the specified
path.
This function initializes the underlying sled database, opens the
required data trees (data_tree, meta_tree, ttl_tree), and
spawns a background thread to handle TTL expirations.
§Errors
Returns a sled::Error if the database cannot be opened at the given
path.
Examples found in repository?
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let db = DB::new(Path::new("./my_database"))?;
7
8 db.set("user:2", "Bob", None)?;
9
10 // Increment the frequency counter
11 db.increment_frequency("user:2")?;
12
13 // Get the metadata for the key
14 if let Some(meta) = db.get_metadata("user:2")? {
15 println!("'user:2' has been accessed {} time(s)", meta.freq);
16 // "'user:2' has been accessed 1 time(s)"
17 }
18
19 Ok(())
20}More examples
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 // 1. Open the database. It will be created if it doesn't exist.
8 let db = DB::new(Path::new("./my_database"))?;
9
10 // 2. Set a value with a 10-second TTL.
11 db.set("user:1", "Alice", Some(Duration::from_secs(10)))?;
12
13 // 3. Get the value back.
14 if let Some(value) = db.get("user:1")? {
15 println!("Found value: {}", value); // "Found value: Alice"
16 }
17
18 // 4. Remove the data.
19 db.remove("user:1")?;
20
21 Ok(())
22}41fn main() -> Result<(), Box<dyn std::error::Error>> {
42 thread::spawn(server_main);
43
44 // Let the thread build the app first
45 // and Let prometheus scrape once
46 sleep(Duration::new(15, 0));
47
48 let db = DB::new(Path::new("./databasetest")).unwrap();
49
50 db.set("H", "haha", None).unwrap();
51 db.set("HAHAHHAH", "Skib", None).unwrap();
52 db.set("HI", "h", None).unwrap();
53 db.set("Chronos", "Temporal", None).unwrap();
54 db.set("pop", "HAHAHAHH", Some(Duration::new(0, 100000)))
55 .unwrap();
56 for i in 0..1000 {
57 db.get("HI").unwrap();
58 db.set(&format!("{i}"), "h", None).unwrap();
59 }
60 db.backup_to(Path::new("./backup/")).unwrap();
61
62 Ok(())
63}6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 let db = Arc::new(DB::new("./my_database".as_ref())?);
8 db.set("concurrent_key", "initial_value", None)?;
9
10 let mut handles = vec![];
11 for _ in 0..10 {
12 let db_clone = Arc::clone(&db);
13 let handle = thread::spawn(move || {
14 for _ in 0..100 {
15 db_clone.increment_frequency("concurrent_key").unwrap();
16 }
17 });
18 handles.push(handle);
19 }
20
21 for handle in handles {
22 handle.join().unwrap();
23 }
24
25 let final_meta = db.get_metadata("concurrent_key")?.unwrap();
26 println!("Final frequency: {}", final_meta.freq); // "Final frequency: 1000"
27
28 Ok(())
29}7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 let db = DB::new(Path::new("./my_database"))?;
9
10 // Set a key with a 2-second TTL
11 db.set("session:123", "user_token", Some(Duration::from_secs(2)))?;
12 println!("'session:123' is set.");
13
14 // The key exists initially
15 assert!(db.get("session:123")?.is_some());
16
17 // Wait for the TTL to expire
18 sleep(Duration::from_secs(3));
19
20 // The key should now be gone
21 assert!(db.get("session:123")?.is_none());
22 println!("'session:123' has expired.");
23
24 // You can also update a key to make it permanent
25 db.set(
26 "user:permanent",
27 "This will last forever",
28 Some(Duration::from_secs(1))
29 )?;
30 db.set("user:permanent", "This will last forever", None)?; // Remove the TTL
31
32 sleep(Duration::from_secs(2));
33 assert!(db.get("user:permanent")?.is_some());
34 println!("'user:permanent' is still here.");
35
36 Ok(())
37}8fn main() -> Result<(), Box<dyn Error>> {
9 // 1. Setup a temporary database for the example.
10 let temp_dir = tempdir()?;
11 let db = DB::new(temp_dir.path())?;
12
13 println!("Database created successfully.");
14
15 // 2. Set the initial state for two user accounts.
16 db.set("user:alice", "100", None)?;
17 db.set("user:bob", "50", None)?;
18
19 println!("Initial state:");
20 println!(" - Alice's balance: {}", db.get("user:alice")?.unwrap());
21 println!(" - Bob's balance: {}", db.get("user:bob")?.unwrap());
22 println!("\nAttempting to transfer 20 from Alice to Bob...");
23
24 // 3. Run the atomic transfer inside a transaction.
25 let transaction_result = db.transaction(|tx| {
26 // Get the current balances.
27 let alice_balance_str = tx.get("user:alice")?.unwrap();
28 let bob_balance_str = tx.get("user:bob")?.unwrap();
29
30 let mut alice_balance: u64 = alice_balance_str.parse()?;
31 let mut bob_balance: u64 = bob_balance_str.parse()?;
32
33 let transfer_amount = 20;
34
35 // Check if the transfer is possible.
36 if alice_balance < transfer_amount {
37 // By returning an error, we abort the entire transaction.
38 // No changes will be saved.
39 return Err(Box::from("Alice has insufficient funds!"));
40 }
41
42 // Perform the transfer.
43 alice_balance -= transfer_amount;
44 bob_balance += transfer_amount;
45
46 // Save the new balances.
47 tx.set("user:alice", &alice_balance.to_string(), None)?;
48 tx.set("user:bob", &bob_balance.to_string(), None)?;
49
50 // Return Ok to commit the transaction.
51 Ok(())
52 });
53
54 // 4. Check if the transaction succeeded.
55 if let Err(e) = transaction_result {
56 println!("\nTransaction failed: {}", e);
57 } else {
58 println!("\nTransaction successful!");
59 }
60
61 // 5. Verify the final state of the database.
62 // The balances should be updated because the transaction succeeded.
63 println!("\nFinal state:");
64 println!(" - Alice's balance: {}", db.get("user:alice")?.unwrap());
65 println!(" - Bob's balance: {}", db.get("user:bob")?.unwrap());
66
67 assert_eq!(db.get("user:alice")?.unwrap(), "80");
68 assert_eq!(db.get("user:bob")?.unwrap(), "70");
69
70 Ok(())
71}Sourcepub fn set(
&self,
key: &str,
val: &str,
ttl: Option<Duration>,
) -> Result<(), TransientError>
pub fn set( &self, key: &str, val: &str, ttl: Option<Duration>, ) -> Result<(), TransientError>
Sets a key-value pair with an optional Time-To-Live (TTL).
If the key already exists, its value and TTL will be updated.
If ttl is None, the key will be persistent.
§Errors
This function can return an error if there’s an issue with the underlying
Examples found in repository?
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let db = DB::new(Path::new("./my_database"))?;
7
8 db.set("user:2", "Bob", None)?;
9
10 // Increment the frequency counter
11 db.increment_frequency("user:2")?;
12
13 // Get the metadata for the key
14 if let Some(meta) = db.get_metadata("user:2")? {
15 println!("'user:2' has been accessed {} time(s)", meta.freq);
16 // "'user:2' has been accessed 1 time(s)"
17 }
18
19 Ok(())
20}More examples
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 // 1. Open the database. It will be created if it doesn't exist.
8 let db = DB::new(Path::new("./my_database"))?;
9
10 // 2. Set a value with a 10-second TTL.
11 db.set("user:1", "Alice", Some(Duration::from_secs(10)))?;
12
13 // 3. Get the value back.
14 if let Some(value) = db.get("user:1")? {
15 println!("Found value: {}", value); // "Found value: Alice"
16 }
17
18 // 4. Remove the data.
19 db.remove("user:1")?;
20
21 Ok(())
22}41fn main() -> Result<(), Box<dyn std::error::Error>> {
42 thread::spawn(server_main);
43
44 // Let the thread build the app first
45 // and Let prometheus scrape once
46 sleep(Duration::new(15, 0));
47
48 let db = DB::new(Path::new("./databasetest")).unwrap();
49
50 db.set("H", "haha", None).unwrap();
51 db.set("HAHAHHAH", "Skib", None).unwrap();
52 db.set("HI", "h", None).unwrap();
53 db.set("Chronos", "Temporal", None).unwrap();
54 db.set("pop", "HAHAHAHH", Some(Duration::new(0, 100000)))
55 .unwrap();
56 for i in 0..1000 {
57 db.get("HI").unwrap();
58 db.set(&format!("{i}"), "h", None).unwrap();
59 }
60 db.backup_to(Path::new("./backup/")).unwrap();
61
62 Ok(())
63}6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 let db = Arc::new(DB::new("./my_database".as_ref())?);
8 db.set("concurrent_key", "initial_value", None)?;
9
10 let mut handles = vec![];
11 for _ in 0..10 {
12 let db_clone = Arc::clone(&db);
13 let handle = thread::spawn(move || {
14 for _ in 0..100 {
15 db_clone.increment_frequency("concurrent_key").unwrap();
16 }
17 });
18 handles.push(handle);
19 }
20
21 for handle in handles {
22 handle.join().unwrap();
23 }
24
25 let final_meta = db.get_metadata("concurrent_key")?.unwrap();
26 println!("Final frequency: {}", final_meta.freq); // "Final frequency: 1000"
27
28 Ok(())
29}7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 let db = DB::new(Path::new("./my_database"))?;
9
10 // Set a key with a 2-second TTL
11 db.set("session:123", "user_token", Some(Duration::from_secs(2)))?;
12 println!("'session:123' is set.");
13
14 // The key exists initially
15 assert!(db.get("session:123")?.is_some());
16
17 // Wait for the TTL to expire
18 sleep(Duration::from_secs(3));
19
20 // The key should now be gone
21 assert!(db.get("session:123")?.is_none());
22 println!("'session:123' has expired.");
23
24 // You can also update a key to make it permanent
25 db.set(
26 "user:permanent",
27 "This will last forever",
28 Some(Duration::from_secs(1))
29 )?;
30 db.set("user:permanent", "This will last forever", None)?; // Remove the TTL
31
32 sleep(Duration::from_secs(2));
33 assert!(db.get("user:permanent")?.is_some());
34 println!("'user:permanent' is still here.");
35
36 Ok(())
37}8fn main() -> Result<(), Box<dyn Error>> {
9 // 1. Setup a temporary database for the example.
10 let temp_dir = tempdir()?;
11 let db = DB::new(temp_dir.path())?;
12
13 println!("Database created successfully.");
14
15 // 2. Set the initial state for two user accounts.
16 db.set("user:alice", "100", None)?;
17 db.set("user:bob", "50", None)?;
18
19 println!("Initial state:");
20 println!(" - Alice's balance: {}", db.get("user:alice")?.unwrap());
21 println!(" - Bob's balance: {}", db.get("user:bob")?.unwrap());
22 println!("\nAttempting to transfer 20 from Alice to Bob...");
23
24 // 3. Run the atomic transfer inside a transaction.
25 let transaction_result = db.transaction(|tx| {
26 // Get the current balances.
27 let alice_balance_str = tx.get("user:alice")?.unwrap();
28 let bob_balance_str = tx.get("user:bob")?.unwrap();
29
30 let mut alice_balance: u64 = alice_balance_str.parse()?;
31 let mut bob_balance: u64 = bob_balance_str.parse()?;
32
33 let transfer_amount = 20;
34
35 // Check if the transfer is possible.
36 if alice_balance < transfer_amount {
37 // By returning an error, we abort the entire transaction.
38 // No changes will be saved.
39 return Err(Box::from("Alice has insufficient funds!"));
40 }
41
42 // Perform the transfer.
43 alice_balance -= transfer_amount;
44 bob_balance += transfer_amount;
45
46 // Save the new balances.
47 tx.set("user:alice", &alice_balance.to_string(), None)?;
48 tx.set("user:bob", &bob_balance.to_string(), None)?;
49
50 // Return Ok to commit the transaction.
51 Ok(())
52 });
53
54 // 4. Check if the transaction succeeded.
55 if let Err(e) = transaction_result {
56 println!("\nTransaction failed: {}", e);
57 } else {
58 println!("\nTransaction successful!");
59 }
60
61 // 5. Verify the final state of the database.
62 // The balances should be updated because the transaction succeeded.
63 println!("\nFinal state:");
64 println!(" - Alice's balance: {}", db.get("user:alice")?.unwrap());
65 println!(" - Bob's balance: {}", db.get("user:bob")?.unwrap());
66
67 assert_eq!(db.get("user:alice")?.unwrap(), "80");
68 assert_eq!(db.get("user:bob")?.unwrap(), "70");
69
70 Ok(())
71}Sourcepub fn get(&self, key: &str) -> Result<Option<String>, TransientError>
pub fn get(&self, key: &str) -> Result<Option<String>, TransientError>
Retrieves the value for a given key.
§Errors
Returns an error if the value cannot be retrieved from the database or if the value is not valid UTF-8.
Examples found in repository?
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 // 1. Open the database. It will be created if it doesn't exist.
8 let db = DB::new(Path::new("./my_database"))?;
9
10 // 2. Set a value with a 10-second TTL.
11 db.set("user:1", "Alice", Some(Duration::from_secs(10)))?;
12
13 // 3. Get the value back.
14 if let Some(value) = db.get("user:1")? {
15 println!("Found value: {}", value); // "Found value: Alice"
16 }
17
18 // 4. Remove the data.
19 db.remove("user:1")?;
20
21 Ok(())
22}More examples
41fn main() -> Result<(), Box<dyn std::error::Error>> {
42 thread::spawn(server_main);
43
44 // Let the thread build the app first
45 // and Let prometheus scrape once
46 sleep(Duration::new(15, 0));
47
48 let db = DB::new(Path::new("./databasetest")).unwrap();
49
50 db.set("H", "haha", None).unwrap();
51 db.set("HAHAHHAH", "Skib", None).unwrap();
52 db.set("HI", "h", None).unwrap();
53 db.set("Chronos", "Temporal", None).unwrap();
54 db.set("pop", "HAHAHAHH", Some(Duration::new(0, 100000)))
55 .unwrap();
56 for i in 0..1000 {
57 db.get("HI").unwrap();
58 db.set(&format!("{i}"), "h", None).unwrap();
59 }
60 db.backup_to(Path::new("./backup/")).unwrap();
61
62 Ok(())
63}7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 let db = DB::new(Path::new("./my_database"))?;
9
10 // Set a key with a 2-second TTL
11 db.set("session:123", "user_token", Some(Duration::from_secs(2)))?;
12 println!("'session:123' is set.");
13
14 // The key exists initially
15 assert!(db.get("session:123")?.is_some());
16
17 // Wait for the TTL to expire
18 sleep(Duration::from_secs(3));
19
20 // The key should now be gone
21 assert!(db.get("session:123")?.is_none());
22 println!("'session:123' has expired.");
23
24 // You can also update a key to make it permanent
25 db.set(
26 "user:permanent",
27 "This will last forever",
28 Some(Duration::from_secs(1))
29 )?;
30 db.set("user:permanent", "This will last forever", None)?; // Remove the TTL
31
32 sleep(Duration::from_secs(2));
33 assert!(db.get("user:permanent")?.is_some());
34 println!("'user:permanent' is still here.");
35
36 Ok(())
37}8fn main() -> Result<(), Box<dyn Error>> {
9 // 1. Setup a temporary database for the example.
10 let temp_dir = tempdir()?;
11 let db = DB::new(temp_dir.path())?;
12
13 println!("Database created successfully.");
14
15 // 2. Set the initial state for two user accounts.
16 db.set("user:alice", "100", None)?;
17 db.set("user:bob", "50", None)?;
18
19 println!("Initial state:");
20 println!(" - Alice's balance: {}", db.get("user:alice")?.unwrap());
21 println!(" - Bob's balance: {}", db.get("user:bob")?.unwrap());
22 println!("\nAttempting to transfer 20 from Alice to Bob...");
23
24 // 3. Run the atomic transfer inside a transaction.
25 let transaction_result = db.transaction(|tx| {
26 // Get the current balances.
27 let alice_balance_str = tx.get("user:alice")?.unwrap();
28 let bob_balance_str = tx.get("user:bob")?.unwrap();
29
30 let mut alice_balance: u64 = alice_balance_str.parse()?;
31 let mut bob_balance: u64 = bob_balance_str.parse()?;
32
33 let transfer_amount = 20;
34
35 // Check if the transfer is possible.
36 if alice_balance < transfer_amount {
37 // By returning an error, we abort the entire transaction.
38 // No changes will be saved.
39 return Err(Box::from("Alice has insufficient funds!"));
40 }
41
42 // Perform the transfer.
43 alice_balance -= transfer_amount;
44 bob_balance += transfer_amount;
45
46 // Save the new balances.
47 tx.set("user:alice", &alice_balance.to_string(), None)?;
48 tx.set("user:bob", &bob_balance.to_string(), None)?;
49
50 // Return Ok to commit the transaction.
51 Ok(())
52 });
53
54 // 4. Check if the transaction succeeded.
55 if let Err(e) = transaction_result {
56 println!("\nTransaction failed: {}", e);
57 } else {
58 println!("\nTransaction successful!");
59 }
60
61 // 5. Verify the final state of the database.
62 // The balances should be updated because the transaction succeeded.
63 println!("\nFinal state:");
64 println!(" - Alice's balance: {}", db.get("user:alice")?.unwrap());
65 println!(" - Bob's balance: {}", db.get("user:bob")?.unwrap());
66
67 assert_eq!(db.get("user:alice")?.unwrap(), "80");
68 assert_eq!(db.get("user:bob")?.unwrap(), "70");
69
70 Ok(())
71}Sourcepub fn increment_frequency(&self, key: &str) -> Result<(), TransientError>
pub fn increment_frequency(&self, key: &str) -> Result<(), TransientError>
Atomically increments the frequency counter for a given key.
§Errors
This function can return an error if the key does not exist or if there is an issue with the compare-and-swap operation.
Examples found in repository?
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let db = DB::new(Path::new("./my_database"))?;
7
8 db.set("user:2", "Bob", None)?;
9
10 // Increment the frequency counter
11 db.increment_frequency("user:2")?;
12
13 // Get the metadata for the key
14 if let Some(meta) = db.get_metadata("user:2")? {
15 println!("'user:2' has been accessed {} time(s)", meta.freq);
16 // "'user:2' has been accessed 1 time(s)"
17 }
18
19 Ok(())
20}More examples
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 let db = Arc::new(DB::new("./my_database".as_ref())?);
8 db.set("concurrent_key", "initial_value", None)?;
9
10 let mut handles = vec![];
11 for _ in 0..10 {
12 let db_clone = Arc::clone(&db);
13 let handle = thread::spawn(move || {
14 for _ in 0..100 {
15 db_clone.increment_frequency("concurrent_key").unwrap();
16 }
17 });
18 handles.push(handle);
19 }
20
21 for handle in handles {
22 handle.join().unwrap();
23 }
24
25 let final_meta = db.get_metadata("concurrent_key")?.unwrap();
26 println!("Final frequency: {}", final_meta.freq); // "Final frequency: 1000"
27
28 Ok(())
29}Sourcepub fn remove(&self, key: &str) -> Result<(), TransientError>
pub fn remove(&self, key: &str) -> Result<(), TransientError>
Removes a key-value pair and its associated metadata from the database.
§Errors
Can return an error if the transaction to remove the data fails.
Examples found in repository?
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 // 1. Open the database. It will be created if it doesn't exist.
8 let db = DB::new(Path::new("./my_database"))?;
9
10 // 2. Set a value with a 10-second TTL.
11 db.set("user:1", "Alice", Some(Duration::from_secs(10)))?;
12
13 // 3. Get the value back.
14 if let Some(value) = db.get("user:1")? {
15 println!("Found value: {}", value); // "Found value: Alice"
16 }
17
18 // 4. Remove the data.
19 db.remove("user:1")?;
20
21 Ok(())
22}Sourcepub fn get_metadata(
&self,
key: &str,
) -> Result<Option<Metadata>, TransientError>
pub fn get_metadata( &self, key: &str, ) -> Result<Option<Metadata>, TransientError>
Retrieves the metadata for a given key.
§Errors
Returns an error if the metadata cannot be retrieved or deserialized.
Examples found in repository?
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let db = DB::new(Path::new("./my_database"))?;
7
8 db.set("user:2", "Bob", None)?;
9
10 // Increment the frequency counter
11 db.increment_frequency("user:2")?;
12
13 // Get the metadata for the key
14 if let Some(meta) = db.get_metadata("user:2")? {
15 println!("'user:2' has been accessed {} time(s)", meta.freq);
16 // "'user:2' has been accessed 1 time(s)"
17 }
18
19 Ok(())
20}More examples
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 let db = Arc::new(DB::new("./my_database".as_ref())?);
8 db.set("concurrent_key", "initial_value", None)?;
9
10 let mut handles = vec![];
11 for _ in 0..10 {
12 let db_clone = Arc::clone(&db);
13 let handle = thread::spawn(move || {
14 for _ in 0..100 {
15 db_clone.increment_frequency("concurrent_key").unwrap();
16 }
17 });
18 handles.push(handle);
19 }
20
21 for handle in handles {
22 handle.join().unwrap();
23 }
24
25 let final_meta = db.get_metadata("concurrent_key")?.unwrap();
26 println!("Final frequency: {}", final_meta.freq); // "Final frequency: 1000"
27
28 Ok(())
29}Sourcepub fn flush(&self) -> Result<(), TransientError>
pub fn flush(&self) -> Result<(), TransientError>
Sourcepub fn backup_to(&self, path: &Path) -> Result<(), TransientError>
pub fn backup_to(&self, path: &Path) -> Result<(), TransientError>
Backup the database to the corresponding path.
§Errors
This function returns an Error if the following occurs:
- Any corresponding folder in the path is not found
- Zip or sled fails because of any reason
- IOError when the file is being access by the OS for something else
- Failing to parse any data to a u8
Examples found in repository?
41fn main() -> Result<(), Box<dyn std::error::Error>> {
42 thread::spawn(server_main);
43
44 // Let the thread build the app first
45 // and Let prometheus scrape once
46 sleep(Duration::new(15, 0));
47
48 let db = DB::new(Path::new("./databasetest")).unwrap();
49
50 db.set("H", "haha", None).unwrap();
51 db.set("HAHAHHAH", "Skib", None).unwrap();
52 db.set("HI", "h", None).unwrap();
53 db.set("Chronos", "Temporal", None).unwrap();
54 db.set("pop", "HAHAHAHH", Some(Duration::new(0, 100000)))
55 .unwrap();
56 for i in 0..1000 {
57 db.get("HI").unwrap();
58 db.set(&format!("{i}"), "h", None).unwrap();
59 }
60 db.backup_to(Path::new("./backup/")).unwrap();
61
62 Ok(())
63}Sourcepub fn load_from(path: &Path, db_path: &Path) -> Result<DB, TransientError>
pub fn load_from(path: &Path, db_path: &Path) -> Result<DB, TransientError>
This function loads the backup archive from the path given and loads the database in the db_path
§Errors
This Function will fail if the following happens:
- Any corresponding folder in the path is not found
- Zip or sled fails because of any reason
- IOError when the file is being access by the OS for something else
- It fails to parse the .epoch file which may occur due to data corruption or wrong formatting.