pub struct DB { /* 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
Implementations§
Source§impl DB
impl DB
Sourcepub fn new(path: &Path) -> Result<DB, Error>
pub fn new(path: &Path) -> Result<DB, Error>
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?
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 let db = DB::new(Path::new("./my_database"))?;
6
7 db.set("user:2", "Bob", None)?;
8
9 // Increment the frequency counter
10 db.increment_frequency("user:2")?;
11
12 // Get the metadata for the key
13 if let Some(meta) = db.get_metadata("user:2")? {
14 println!("'user:2' has been accessed {} time(s)", meta.freq);
15 // "'user:2' has been accessed 1 time(s)"
16 }
17
18 Ok(())
19}More examples
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 // 1. Open the database. It will be created if it doesn't exist.
7 let db = DB::new(Path::new("./my_database"))?;
8
9 // 2. Set a value with a 10-second TTL.
10 db.set("user:1", "Alice", Some(Duration::from_secs(10)))?;
11
12 // 3. Get the value back.
13 if let Some(value) = db.get("user:1")? {
14 println!("Found value: {}", value); // "Found value: Alice"
15 }
16
17 // 4. Remove the data.
18 db.remove("user:1")?;
19
20 Ok(())
21}5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let db = Arc::new(DB::new("./my_database".as_ref())?);
7 db.set("concurrent_key", "initial_value", None)?;
8
9 let mut handles = vec![];
10 for _ in 0..10 {
11 let db_clone = Arc::clone(&db);
12 let handle = thread::spawn(move || {
13 for _ in 0..100 {
14 db_clone.increment_frequency("concurrent_key").unwrap();
15 }
16 });
17 handles.push(handle);
18 }
19
20 for handle in handles {
21 handle.join().unwrap();
22 }
23
24 let final_meta = db.get_metadata("concurrent_key")?.unwrap();
25 println!("Final frequency: {}", final_meta.freq); // "Final frequency: 1000"
26
27 Ok(())
28}6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 let db = DB::new(Path::new("./my_database"))?;
8
9 // Set a key with a 2-second TTL
10 db.set("session:123", "user_token", Some(Duration::from_secs(2)))?;
11 println!("'session:123' is set.");
12
13 // The key exists initially
14 assert!(db.get("session:123")?.is_some());
15
16 // Wait for the TTL to expire
17 sleep(Duration::from_secs(3));
18
19 // The key should now be gone
20 assert!(db.get("session:123")?.is_none());
21 println!("'session:123' has expired.");
22
23 // You can also update a key to make it permanent
24 db.set(
25 "user:permanent",
26 "This will last forever",
27 Some(Duration::from_secs(1)),
28 )?;
29 db.set("user:permanent", "This will last forever", None)?; // Remove the TTL
30
31 sleep(Duration::from_secs(2));
32 assert!(db.get("user:permanent")?.is_some());
33 println!("'user:permanent' is still here.");
34
35 Ok(())
36}Sourcepub fn set(
&self,
key: &str,
val: &str,
ttl: Option<Duration>,
) -> Result<(), Box<dyn Error>>
pub fn set( &self, key: &str, val: &str, ttl: Option<Duration>, ) -> Result<(), Box<dyn Error>>
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?
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 let db = DB::new(Path::new("./my_database"))?;
6
7 db.set("user:2", "Bob", None)?;
8
9 // Increment the frequency counter
10 db.increment_frequency("user:2")?;
11
12 // Get the metadata for the key
13 if let Some(meta) = db.get_metadata("user:2")? {
14 println!("'user:2' has been accessed {} time(s)", meta.freq);
15 // "'user:2' has been accessed 1 time(s)"
16 }
17
18 Ok(())
19}More examples
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 // 1. Open the database. It will be created if it doesn't exist.
7 let db = DB::new(Path::new("./my_database"))?;
8
9 // 2. Set a value with a 10-second TTL.
10 db.set("user:1", "Alice", Some(Duration::from_secs(10)))?;
11
12 // 3. Get the value back.
13 if let Some(value) = db.get("user:1")? {
14 println!("Found value: {}", value); // "Found value: Alice"
15 }
16
17 // 4. Remove the data.
18 db.remove("user:1")?;
19
20 Ok(())
21}5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let db = Arc::new(DB::new("./my_database".as_ref())?);
7 db.set("concurrent_key", "initial_value", None)?;
8
9 let mut handles = vec![];
10 for _ in 0..10 {
11 let db_clone = Arc::clone(&db);
12 let handle = thread::spawn(move || {
13 for _ in 0..100 {
14 db_clone.increment_frequency("concurrent_key").unwrap();
15 }
16 });
17 handles.push(handle);
18 }
19
20 for handle in handles {
21 handle.join().unwrap();
22 }
23
24 let final_meta = db.get_metadata("concurrent_key")?.unwrap();
25 println!("Final frequency: {}", final_meta.freq); // "Final frequency: 1000"
26
27 Ok(())
28}6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 let db = DB::new(Path::new("./my_database"))?;
8
9 // Set a key with a 2-second TTL
10 db.set("session:123", "user_token", Some(Duration::from_secs(2)))?;
11 println!("'session:123' is set.");
12
13 // The key exists initially
14 assert!(db.get("session:123")?.is_some());
15
16 // Wait for the TTL to expire
17 sleep(Duration::from_secs(3));
18
19 // The key should now be gone
20 assert!(db.get("session:123")?.is_none());
21 println!("'session:123' has expired.");
22
23 // You can also update a key to make it permanent
24 db.set(
25 "user:permanent",
26 "This will last forever",
27 Some(Duration::from_secs(1)),
28 )?;
29 db.set("user:permanent", "This will last forever", None)?; // Remove the TTL
30
31 sleep(Duration::from_secs(2));
32 assert!(db.get("user:permanent")?.is_some());
33 println!("'user:permanent' is still here.");
34
35 Ok(())
36}Sourcepub fn get(&self, key: &str) -> Result<Option<String>, Box<dyn Error>>
pub fn get(&self, key: &str) -> Result<Option<String>, Box<dyn Error>>
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?
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 // 1. Open the database. It will be created if it doesn't exist.
7 let db = DB::new(Path::new("./my_database"))?;
8
9 // 2. Set a value with a 10-second TTL.
10 db.set("user:1", "Alice", Some(Duration::from_secs(10)))?;
11
12 // 3. Get the value back.
13 if let Some(value) = db.get("user:1")? {
14 println!("Found value: {}", value); // "Found value: Alice"
15 }
16
17 // 4. Remove the data.
18 db.remove("user:1")?;
19
20 Ok(())
21}More examples
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7 let db = DB::new(Path::new("./my_database"))?;
8
9 // Set a key with a 2-second TTL
10 db.set("session:123", "user_token", Some(Duration::from_secs(2)))?;
11 println!("'session:123' is set.");
12
13 // The key exists initially
14 assert!(db.get("session:123")?.is_some());
15
16 // Wait for the TTL to expire
17 sleep(Duration::from_secs(3));
18
19 // The key should now be gone
20 assert!(db.get("session:123")?.is_none());
21 println!("'session:123' has expired.");
22
23 // You can also update a key to make it permanent
24 db.set(
25 "user:permanent",
26 "This will last forever",
27 Some(Duration::from_secs(1)),
28 )?;
29 db.set("user:permanent", "This will last forever", None)?; // Remove the TTL
30
31 sleep(Duration::from_secs(2));
32 assert!(db.get("user:permanent")?.is_some());
33 println!("'user:permanent' is still here.");
34
35 Ok(())
36}Sourcepub fn increment_frequency(&self, key: &str) -> Result<(), Box<dyn Error>>
pub fn increment_frequency(&self, key: &str) -> Result<(), Box<dyn Error>>
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?
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 let db = DB::new(Path::new("./my_database"))?;
6
7 db.set("user:2", "Bob", None)?;
8
9 // Increment the frequency counter
10 db.increment_frequency("user:2")?;
11
12 // Get the metadata for the key
13 if let Some(meta) = db.get_metadata("user:2")? {
14 println!("'user:2' has been accessed {} time(s)", meta.freq);
15 // "'user:2' has been accessed 1 time(s)"
16 }
17
18 Ok(())
19}More examples
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let db = Arc::new(DB::new("./my_database".as_ref())?);
7 db.set("concurrent_key", "initial_value", None)?;
8
9 let mut handles = vec![];
10 for _ in 0..10 {
11 let db_clone = Arc::clone(&db);
12 let handle = thread::spawn(move || {
13 for _ in 0..100 {
14 db_clone.increment_frequency("concurrent_key").unwrap();
15 }
16 });
17 handles.push(handle);
18 }
19
20 for handle in handles {
21 handle.join().unwrap();
22 }
23
24 let final_meta = db.get_metadata("concurrent_key")?.unwrap();
25 println!("Final frequency: {}", final_meta.freq); // "Final frequency: 1000"
26
27 Ok(())
28}Sourcepub fn remove(&self, key: &str) -> Result<(), Box<dyn Error>>
pub fn remove(&self, key: &str) -> Result<(), Box<dyn Error>>
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?
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 // 1. Open the database. It will be created if it doesn't exist.
7 let db = DB::new(Path::new("./my_database"))?;
8
9 // 2. Set a value with a 10-second TTL.
10 db.set("user:1", "Alice", Some(Duration::from_secs(10)))?;
11
12 // 3. Get the value back.
13 if let Some(value) = db.get("user:1")? {
14 println!("Found value: {}", value); // "Found value: Alice"
15 }
16
17 // 4. Remove the data.
18 db.remove("user:1")?;
19
20 Ok(())
21}Sourcepub fn get_metadata(
&self,
key: &str,
) -> Result<Option<Metadata>, Box<dyn Error>>
pub fn get_metadata( &self, key: &str, ) -> Result<Option<Metadata>, Box<dyn Error>>
Retrieves the metadata for a given key.
§Errors
Returns an error if the metadata cannot be retrieved or deserialized.
Examples found in repository?
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 let db = DB::new(Path::new("./my_database"))?;
6
7 db.set("user:2", "Bob", None)?;
8
9 // Increment the frequency counter
10 db.increment_frequency("user:2")?;
11
12 // Get the metadata for the key
13 if let Some(meta) = db.get_metadata("user:2")? {
14 println!("'user:2' has been accessed {} time(s)", meta.freq);
15 // "'user:2' has been accessed 1 time(s)"
16 }
17
18 Ok(())
19}More examples
5fn main() -> Result<(), Box<dyn std::error::Error>> {
6 let db = Arc::new(DB::new("./my_database".as_ref())?);
7 db.set("concurrent_key", "initial_value", None)?;
8
9 let mut handles = vec![];
10 for _ in 0..10 {
11 let db_clone = Arc::clone(&db);
12 let handle = thread::spawn(move || {
13 for _ in 0..100 {
14 db_clone.increment_frequency("concurrent_key").unwrap();
15 }
16 });
17 handles.push(handle);
18 }
19
20 for handle in handles {
21 handle.join().unwrap();
22 }
23
24 let final_meta = db.get_metadata("concurrent_key")?.unwrap();
25 println!("Final frequency: {}", final_meta.freq); // "Final frequency: 1000"
26
27 Ok(())
28}