Skip to main content

cubecl_environment/persistence/
mod.rs

1//! Key-value persistence.
2//!
3//! A [`Store`] is a typed in-memory map that syncs its content to an optional
4//! [`Storage`]: an embedded `SQLite` database on std targets, browser storage
5//! on wasm (feature `browser-cache`), or nothing at all. [`CacheOption`]
6//! decides whether the whole namespace is ingested at open or entries are
7//! faulted in one key at a time.
8//!
9//! Every cache is identified by a [`Namespace`], a `/`-separated string such
10//! as `autotune/0.11.0/cuda-0/matmul`. On std targets all the namespaces of a
11//! cache root share one database file (`cubecl.db`) and are told apart by a
12//! column rather than by a directory tree. Entries are therefore looked up per
13//! key, several processes can share a root safely through WAL, and shipping a
14//! subset of them is a query away (see [`crate::bundle`]).
15
16/// The writable half of persistence: where a namespace's entries live.
17pub mod storage;
18
19pub use storage::*;
20
21mod namespace;
22mod store;
23
24pub use namespace::Namespace;
25pub use store::*;
26
27/// `SQLite` persistence: the database file shared by every namespace of a
28/// cache root.
29#[cfg(native_cache)]
30pub mod sqlite;
31
32#[cfg(native_cache)]
33pub use sqlite::{Database, SqliteStorage, db_file_name};
34
35/// Browser storage (IndexedDB).
36#[cfg(browser_cache)]
37pub(crate) mod browser;
38
39/// Cache root location selection.
40///
41/// Available wherever there is a file system, not only when the `SQLite`
42/// backend is compiled in: the root is what names an environment on disk, and
43/// [`crate::environment`] exposes it independently of how entries are stored.
44#[cfg(std_io)]
45mod root;
46
47#[cfg(std_io)]
48pub use root::CacheConfig;
49
50/// The database-backed storage serving `namespace` in the active
51/// environment, degrading to process-wide memory when the database can't be
52/// opened.
53#[cfg(native_cache)]
54pub(crate) fn open_database_storage(namespace: &str) -> alloc::boxed::Box<dyn Storage> {
55    use alloc::{boxed::Box, string::ToString};
56
57    match Database::open_active() {
58        Some(database) => Box::new(SqliteStorage::new(database, namespace.to_string())),
59        // Isolate the memory fallback per environment, so a switch after the
60        // database failed to open doesn't serve the previous environment's
61        // entries.
62        None => Box::new(MemoryStorage::in_environment(namespace)),
63    }
64}