Allow safe mode environment managers

Signed-off-by: Victor Porof <victor.porof@gmail.com>
without.crypto
Victor Porof 5 years ago
parent 7738b5a726
commit 7717f49841
  1. 3
      examples/iterator.rs
  2. 4
      examples/simple-store.rs
  3. 4
      src/lib.rs
  4. 75
      src/manager.rs
  5. 33
      tests/manager.rs

@ -31,7 +31,8 @@ fn main() {
fs::create_dir_all(root.path()).unwrap();
let p = root.path();
let created_arc = Manager::singleton().write().unwrap().get_or_create(p, Rkv::new::<Lmdb>).unwrap();
let mut manager = Manager::<LmdbEnvironment>::singleton().write().unwrap();
let created_arc = manager.get_or_create(p, Rkv::new::<Lmdb>).unwrap();
let k = created_arc.read().unwrap();
let store = k.open_single("store", StoreOptions::create()).unwrap();

@ -15,6 +15,7 @@ use rkv::backend::{
BackendStat,
Lmdb,
LmdbDatabase,
LmdbEnvironment,
LmdbRwTransaction,
};
use rkv::{
@ -61,7 +62,8 @@ fn main() {
let p = root.path();
// The manager enforces that each process opens the same lmdb environment at most once
let created_arc = Manager::singleton().write().unwrap().get_or_create(p, Rkv::new::<Lmdb>).unwrap();
let mut manager = Manager::<LmdbEnvironment>::singleton().write().unwrap();
let created_arc = manager.get_or_create(p, Rkv::new::<Lmdb>).unwrap();
let k = created_arc.read().unwrap();
// Creates a store called "store"

@ -41,7 +41,7 @@
//! ## Basic Usage
//! ```
//! use rkv::{Manager, Rkv, SingleStore, Value, StoreOptions};
//! use rkv::backend::Lmdb;
//! use rkv::backend::{Lmdb, LmdbEnvironment};
//! use std::fs;
//! use tempfile::Builder;
//!
@ -61,7 +61,7 @@
//! // at most once by caching a handle to each environment that it opens.
//! // Use it to retrieve the handle to an opened environment—or create one
//! // if it hasn't already been opened:
//! let mut manager = Manager::singleton().write().unwrap();
//! let mut manager = Manager::<LmdbEnvironment>::singleton().write().unwrap();
//! let created_arc = manager.get_or_create(path, Rkv::new::<Lmdb>).unwrap();
//! let env = created_arc.read().unwrap();
//!

@ -23,7 +23,10 @@ use std::sync::{
use lazy_static::lazy_static;
use crate::backend::LmdbEnvironment;
use crate::backend::{
LmdbEnvironment,
SafeModeEnvironment,
};
use crate::error::StoreError;
use crate::helpers::canonicalize_path;
use crate::Rkv;
@ -35,6 +38,7 @@ lazy_static! {
/// A process is only permitted to have one open handle to each Rkv environment.
/// This manager exists to enforce that constraint: don't open environments directly.
static ref MANAGER_LMDB: RwLock<Manager<LmdbEnvironment>> = RwLock::new(Manager::new());
static ref MANAGER_SAFE_MODE: RwLock<Manager<SafeModeEnvironment>> = RwLock::new(Manager::new());
}
/// A process is only permitted to have one open handle to each Rkv environment.
@ -99,6 +103,12 @@ impl Manager<LmdbEnvironment> {
}
}
impl Manager<SafeModeEnvironment> {
pub fn singleton() -> &'static RwLock<Manager<SafeModeEnvironment>> {
&*MANAGER_SAFE_MODE
}
}
#[cfg(test)]
mod tests {
use std::fs;
@ -112,7 +122,7 @@ mod tests {
/// Test that a manager can be created with simple type inference.
#[test]
fn test_simple() {
let _ = Manager::singleton().write().unwrap();
let _ = Manager::<LmdbEnvironment>::singleton().write().unwrap();
}
/// Test that a shared Rkv instance can be created with simple type inference.
@ -121,7 +131,7 @@ mod tests {
let root = Builder::new().prefix("test_simple").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let mut manager = Manager::singleton().write().unwrap();
let mut manager = Manager::<LmdbEnvironment>::singleton().write().unwrap();
let _ = manager.get_or_create(root.path(), Rkv::new::<Lmdb>).unwrap();
}
@ -190,3 +200,62 @@ mod tests {
assert!(Arc::ptr_eq(&created_arc, &fetched_arc));
}
}
#[cfg(test)]
mod tests_safe {
use std::fs;
use tempfile::Builder;
use super::*;
use crate::*;
use backend::SafeMode;
/// Test that a manager can be created with simple type inference.
#[test]
fn test_simple() {
let _ = Manager::<SafeModeEnvironment>::singleton().write().unwrap();
}
/// Test that a shared Rkv instance can be created with simple type inference.
#[test]
fn test_simple_2() {
let root = Builder::new().prefix("test_simple").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let mut manager = Manager::<SafeModeEnvironment>::singleton().write().unwrap();
let _ = manager.get_or_create(root.path(), Rkv::new::<SafeMode>).unwrap();
}
/// Test that the manager will return the same Rkv instance each time for each path.
#[test]
fn test_same() {
let root = Builder::new().prefix("test_same").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let mut manager = Manager::<SafeModeEnvironment>::new();
let p = root.path();
assert!(manager.get(p).expect("success").is_none());
let created_arc = manager.get_or_create(p, Rkv::new::<SafeMode>).expect("created");
let fetched_arc = manager.get(p).expect("success").expect("existed");
assert!(Arc::ptr_eq(&created_arc, &fetched_arc));
}
/// Test that the manager will return the same Rkv instance each time for each path.
#[test]
fn test_same_with_capacity() {
let root = Builder::new().prefix("test_same").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let mut manager = Manager::<SafeModeEnvironment>::new();
let p = root.path();
assert!(manager.get(p).expect("success").is_none());
let created_arc = manager.get_or_create_with_capacity(p, 10, Rkv::with_capacity::<SafeMode>).expect("created");
let fetched_arc = manager.get(p).expect("success").expect("existed");
assert!(Arc::ptr_eq(&created_arc, &fetched_arc));
}
}

@ -13,16 +13,20 @@ use std::sync::Arc;
use tempfile::Builder;
use rkv::backend::Lmdb;
use rkv::{
Manager,
Rkv,
use rkv::backend::{
Lmdb,
LmdbEnvironment,
SafeMode,
SafeModeEnvironment,
};
use rkv::Rkv;
#[test]
// Identical to the same-named unit test, but this one confirms that it works
// via the public MANAGER singleton.
// via the public MANAGER singleton for an LMDB backend.
#[test]
fn test_same() {
type Manager = rkv::Manager<LmdbEnvironment>;
let root = Builder::new().prefix("test_same_singleton").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
@ -33,3 +37,20 @@ fn test_same() {
let fetched_arc = Manager::singleton().read().unwrap().get(p).expect("success").expect("existed");
assert!(Arc::ptr_eq(&created_arc, &fetched_arc));
}
// Identical to the same-named unit test, but this one confirms that it works
// via the public MANAGER singleton for a safe mode backend.
#[test]
fn test_same_safe() {
type Manager = rkv::Manager<SafeModeEnvironment>;
let root = Builder::new().prefix("test_same_singleton").tempdir().expect("tempdir");
fs::create_dir_all(root.path()).expect("dir created");
let p = root.path();
assert!(Manager::singleton().read().unwrap().get(p).expect("success").is_none());
let created_arc = Manager::singleton().write().unwrap().get_or_create(p, Rkv::new::<SafeMode>).expect("created");
let fetched_arc = Manager::singleton().read().unwrap().get(p).expect("success").expect("existed");
assert!(Arc::ptr_eq(&created_arc, &fetched_arc));
}

Loading…
Cancel
Save