Skip to main content

grid_rs/
kvs.rs

1//! Key-value store.
2//!
3//! This module provides access to the host's key-value store. You should be able to manage keys,
4//! values, and stores from within your functions.
5//!
6//! *Note:* stores are based on namespace set within a function. This allows for multiple stores per
7//! function, persisting instance state.
8use crate::region::Region;
9
10unsafe extern "C" {
11    fn kv_get(namespace_ptr: usize, key_ptr: usize) -> usize;
12    fn kv_put(namespace_ptr: usize, key_ptr: usize, value_ptr: usize);
13    fn kv_delete(namespace_ptr: usize, key_ptr: usize);
14    fn kv_delete_store(namespace_ptr: usize);
15    fn kv_commit(namespace_ptr: usize);
16}
17
18/// Key-value storage endpoints.
19#[derive(Default)]
20pub struct Storage;
21
22impl Storage {
23    /// Get a value from the key-value store.
24    pub fn get(namespace: &str, key: &str) -> Option<Vec<u8>> {
25        let namespace = Region::build(namespace.as_bytes());
26        let namespace_ptr = &*namespace as *const Region;
27
28        let key = Region::build(key.as_bytes());
29        let key_ptr = &*key as *const Region;
30
31        let value_ptr = unsafe { kv_get(namespace_ptr as usize, key_ptr as usize) };
32        if value_ptr == 0 {
33            return None;
34        }
35
36        unsafe { Some(Region::consume(value_ptr as *mut Region)) }
37    }
38
39    /// Put a value into the key-value store.
40    pub fn put(namespace: &str, key: &str, value: &[u8]) {
41        let namespace = Region::build(namespace.as_bytes());
42        let namespace_ptr = &*namespace as *const Region;
43
44        let key = Region::build(key.as_bytes());
45        let key_ptr = &*key as *const Region;
46
47        let value = Region::build(value);
48        let value_ptr = &*value as *const Region;
49
50        unsafe { kv_put(namespace_ptr as usize, key_ptr as usize, value_ptr as usize) };
51    }
52
53    /// Delete a value from the key-value store.
54    pub fn delete(namespace: &str, key: &str) {
55        let namespace = Region::build(namespace.as_bytes());
56        let namespace_ptr = &*namespace as *const Region;
57
58        let key = Region::build(key.as_bytes());
59        let key_ptr = &*key as *const Region;
60
61        unsafe { kv_delete(namespace_ptr as usize, key_ptr as usize) };
62    }
63
64    /// Delete the entire key-value store.
65    pub fn delete_store(namespace: &str) {
66        let namespace = Region::build(namespace.as_bytes());
67        let namespace_ptr = &*namespace as *const Region;
68        
69        unsafe { kv_delete_store(namespace_ptr as usize) };
70    }
71
72    /// Persist the key-value store to the host storage.
73    pub fn commit(namespace: &str) {
74        let namespace = Region::build(namespace.as_bytes());
75        let namespace_ptr = &*namespace as *const Region;
76
77        unsafe { kv_commit(namespace_ptr as usize) };
78    }
79}