YXKP4AIWDBIWBBUDWF66YIPG5ECMHNKEV3PX6KYXOVXY3EWG3WGQC }}/// Represents an exclusive lock taken on the environment.pub struct Exclusive(std::fs::File);#[cfg(feature = "mmap")]impl Drop for Exclusive {fn drop(&mut self) {self.0.unlock().unwrap_or(());}}/// Represents a shared lock taken on the environment.pub struct Shared(std::fs::File);#[cfg(feature = "mmap")]impl Drop for Shared {fn drop(&mut self) {self.0.unlock().unwrap_or(());
unsafe impl<T> Send for Env<T> {}unsafe impl<T> Sync for Env<T> {}
struct RootLock {/// It is undefined behavior to have a file mmapped for than once.#[cfg(feature = "mmap")]lock_file: Option<std::fs::File>,rw: parking_lot::RawRwLock,n_txn: AtomicUsize,}unsafe impl Send for Env {}unsafe impl Sync for Env {}
let mut versions = Vec::with_capacity(glob.n_versions as usize);for _ in 0..glob.n_versions {versions.push(Mutex::new(()))
let mut roots = Vec::with_capacity(glob.n_roots as usize);for _ in 0..glob.n_roots {roots.push(RootLock {rw: <parking_lot::RawRwLock as parking_lot::lock_api::RawRwLock>::INIT,n_txn: AtomicUsize::new(0),lock_file: None,})
impl Env<Shared> {/// Initialize an environment. `length` must be a strictly/// positive multiple of 4096. The same file can only be open in/// one process or thread at the same time, and this is enforced/// by a locked file.#[cfg(feature = "mmap")]pub fn new_shared<P: AsRef<Path>>(path: P, length: u64) -> Result<Env<Shared>, Error> {let lock_file = OpenOptions::new().read(true).write(true).truncate(false).create(true).open(path.as_ref().join("db").with_extension("lock"))?;lock_file.lock_shared()?;let mut env = unsafe { Self::new_nolock(path, length)? };env.lock_file = Some(Shared(lock_file));Ok(env)}
impl Env {
/// positive multiple of 4096. Returns an error if the database is/// locked by another process or thread.
/// positive multiple of 4096.////// The `n_roots` parameter is the maximum number of mutable/// transactions that can commit during a single immutable/// transaction, and must be at most 255. If it is 1, mutable/// transactions exclude all immutable transactions.
pub fn try_new_shared<P: AsRef<Path>>(path: P, length: u64) -> Result<Env<Shared>, Error> {let lock_file = OpenOptions::new().read(true).write(true).truncate(false).create(true).open(path.as_ref().join("db").with_extension("lock"))?;lock_file.try_lock_shared()?;let mut env = unsafe { Self::new_nolock(path, length)? };env.lock_file = Some(Shared(lock_file));Ok(env)}}impl Env<Exclusive> {/// Initialize an environment. `length` must be a strictly/// positive multiple of 4096. The same file can only be open in/// one process or thread at the same time, and this is enforced/// by a locked file.#[cfg(feature = "mmap")]pub fn new<P: AsRef<Path>>(path: P, length: u64) -> Result<Env<Exclusive>, Error> {let lock_file = OpenOptions::new().read(true).write(true).truncate(false).create(true).open(path.as_ref().join("db").with_extension("lock"))?;lock_file.lock_exclusive()?;let mut env = unsafe { Self::new_nolock(path, length)? };env.lock_file = Some(Exclusive(lock_file));Ok(env)}/// Initialize an environment. `length` must be a strictly/// positive multiple of 4096. Returns an error if the database is/// locked by another process or thread.#[cfg(feature = "mmap")]pub fn try_new<P: AsRef<Path>>(path: P, length: u64) -> Result<Env<Exclusive>, Error> {let lock_file = OpenOptions::new().read(true).write(true).truncate(false).create(true).open(path.as_ref().join("db").with_extension("lock"))?;lock_file.try_lock_exclusive()?;let mut env = unsafe { Self::new_nolock(path, length)? };env.lock_file = Some(Exclusive(lock_file));
pub fn new<P: AsRef<Path>>(path: P, length: u64, n_roots: usize) -> Result<Env, Error> {assert!(n_roots < 256);let path = path.as_ref();let mut env = unsafe { Self::new_nolock(path, length, n_roots)? };for (n, l) in env.roots.iter_mut().enumerate() {l.lock_file = Some(OpenOptions::new().read(true).write(true).truncate(false).create(true).open(path.join("db").with_extension(&format!("lock{}", n)))?);}
pub fn new_anon(length: u64) -> Result<Env<Exclusive>, Error> {let length = std::cmp::max(length, 4096).next_power_of_two();
pub fn new_anon(length: u64, n_roots: usize) -> Result<Env, Error> {let length = (std::cmp::max(length, 4096) + 4095) & !4096;
unsafe { env.roots[self.root].unlock_shared() }
let old_n_txn = env.roots[self.root].n_txn.fetch_sub(1, Ordering::SeqCst);if old_n_txn == 1 {unsafe { env.roots[self.root].rw.unlock_shared() }if let Some(ref f) = env.roots[self.root].lock_file {f.unlock().unwrap_or(())}}