@ -1,5 +1,5 @@
use libc ::{ c_uint , size_t } ;
use libc ::{ c_uint , size_t } ;
use std ::{ fmt , ptr , result } ;
use std ::{ fmt , ptr , result , mem } ;
use std ::ffi ::CString ;
use std ::ffi ::CString ;
#[ cfg(unix) ]
#[ cfg(unix) ]
use std ::os ::unix ::ffi ::OsStrExt ;
use std ::os ::unix ::ffi ::OsStrExt ;
@ -35,6 +35,11 @@ pub struct Environment {
dbi_open_mutex : Mutex < ( ) > ,
dbi_open_mutex : Mutex < ( ) > ,
}
}
/// Database statistics
///
/// Contains information about the size and layout of an LMDB database
pub struct Stat ( ffi ::MDB_stat ) ;
impl Environment {
impl Environment {
/// Creates a new builder for specifying options for opening an LMDB environment.
/// Creates a new builder for specifying options for opening an LMDB environment.
@ -151,6 +156,53 @@ impl Environment {
pub unsafe fn close_db ( & mut self , db : Database ) {
pub unsafe fn close_db ( & mut self , db : Database ) {
ffi ::mdb_dbi_close ( self . env , db . dbi ( ) ) ;
ffi ::mdb_dbi_close ( self . env , db . dbi ( ) ) ;
}
}
/// Get database statistics.
pub fn stat ( & self ) -> Result < Stat > {
unsafe {
let mut stat = Stat ( mem ::zeroed ( ) ) ;
lmdb_try ! ( ffi ::mdb_env_stat ( self . env ( ) , & mut stat . 0 ) ) ;
Ok ( stat )
}
}
}
impl Stat {
/// Size of database in bytes.
#[ inline ]
pub fn size ( & self ) -> u32 {
self . 0. ms_psize
}
/// Height of B-tree.
#[ inline ]
pub fn depth ( & self ) -> u32 {
self . 0. ms_depth
}
/// Number of internal (non-leaf) pages.
#[ inline ]
pub fn branch_pages ( & self ) -> usize {
self . 0. ms_branch_pages
}
/// Number of lead pages.
#[ inline ]
pub fn leaf_pages ( & self ) -> usize {
self . 0. ms_leaf_pages
}
/// Number of overflow pages.
#[ inline ]
pub fn overflow_pages ( & self ) -> usize {
self . 0. ms_overflow_pages
}
/// Number of data items.
#[ inline ]
pub fn entries ( & self ) -> usize {
self . 0. ms_entries
}
}
}
unsafe impl Send for Environment { }
unsafe impl Send for Environment { }
@ -285,7 +337,7 @@ mod test {
let dir = TempDir ::new ( "test" ) . unwrap ( ) ;
let dir = TempDir ::new ( "test" ) . unwrap ( ) ;
// opening non-existent env with read-only should fail
// opening non-existent env with read-only should fail
assert! ( Environment ::new ( ) . set_flags ( READ_ONLY )
assert! ( Environment ::new ( ) . set_flags ( EnvironmentFlags ::READ_ONLY )
. open ( dir . path ( ) )
. open ( dir . path ( ) )
. is_err ( ) ) ;
. is_err ( ) ) ;
@ -293,7 +345,7 @@ mod test {
assert! ( Environment ::new ( ) . open ( dir . path ( ) ) . is_ok ( ) ) ;
assert! ( Environment ::new ( ) . open ( dir . path ( ) ) . is_ok ( ) ) ;
// opening env with read-only should succeed
// opening env with read-only should succeed
assert! ( Environment ::new ( ) . set_flags ( READ_ONLY )
assert! ( Environment ::new ( ) . set_flags ( EnvironmentFlags ::READ_ONLY )
. open ( dir . path ( ) )
. open ( dir . path ( ) )
. is_ok ( ) ) ;
. is_ok ( ) ) ;
}
}
@ -310,7 +362,7 @@ mod test {
}
}
{ // read-only environment
{ // read-only environment
let env = Environment ::new ( ) . set_flags ( READ_ONLY )
let env = Environment ::new ( ) . set_flags ( EnvironmentFlags ::READ_ONLY )
. open ( dir . path ( ) )
. open ( dir . path ( ) )
. unwrap ( ) ;
. unwrap ( ) ;
@ -360,7 +412,7 @@ mod test {
let env = Environment ::new ( ) . open ( dir . path ( ) ) . unwrap ( ) ;
let env = Environment ::new ( ) . open ( dir . path ( ) ) . unwrap ( ) ;
assert! ( env . sync ( true ) . is_ok ( ) ) ;
assert! ( env . sync ( true ) . is_ok ( ) ) ;
} {
} {
let env = Environment ::new ( ) . set_flags ( READ_ONLY )
let env = Environment ::new ( ) . set_flags ( EnvironmentFlags ::READ_ONLY )
. open ( dir . path ( ) )
. open ( dir . path ( ) )
. unwrap ( ) ;
. unwrap ( ) ;
assert! ( env . sync ( true ) . is_err ( ) ) ;
assert! ( env . sync ( true ) . is_err ( ) ) ;