Update dependencies and add database statistics (#23)

Add database statistics in a new `Stats` type

Also bundles a few other changes:

- Switch from `gcc` crate to `cc` for building lmdb
- Bump `bitflags` crate to 1.0
- Bump minimum required `rustc` from `1.8` to `1.20`

This is a breaking change.
without.crypto
zach 7 years ago committed by Dan Burkert
parent 6539d449f0
commit 0f613773c1
  1. 2
      .travis.yml
  2. 4
      Cargo.toml
  3. 2
      README.md
  4. 3
      lmdb-sys/Cargo.toml
  5. 4
      lmdb-sys/build.rs
  6. 6
      src/cursor.rs
  7. 62
      src/environment.rs
  8. 4
      src/lib.rs

@ -9,7 +9,7 @@ os:
- osx - osx
rust: rust:
- 1.8.0 - 1.20.0
- stable - stable
- nightly - nightly

@ -23,11 +23,11 @@ members = [
] ]
[dependencies] [dependencies]
bitflags = "0.9" bitflags = "1"
libc = "0.2" libc = "0.2"
lmdb-sys = { version = "0.7.2", path = "lmdb-sys" } lmdb-sys = { version = "0.7.2", path = "lmdb-sys" }
[dev-dependencies] [dev-dependencies]
rand = "0.3" rand = "0.4"
tempdir = "0.3" tempdir = "0.3"
byteorder = "1.0" byteorder = "1.0"

@ -22,4 +22,4 @@ cargo build
* [x] Cursors. * [x] Cursors.
* [x] Zero-copy put API. * [x] Zero-copy put API.
* [x] Nested transactions. * [x] Nested transactions.
* [ ] Database statistics. * [x] Database statistics.

@ -20,5 +20,4 @@ libc = "0.2"
[build-dependencies] [build-dependencies]
pkg-config = "0.3" pkg-config = "0.3"
# https://github.com/alexcrichton/gcc-rs/issues/240 cc = "1"
gcc = "=0.3.51"

@ -1,5 +1,5 @@
extern crate pkg_config; extern crate pkg_config;
extern crate gcc; extern crate cc;
use std::env; use std::env;
use std::path::PathBuf; use std::path::PathBuf;
@ -11,7 +11,7 @@ fn main() {
lmdb.push("liblmdb"); lmdb.push("liblmdb");
if !pkg_config::find_library("liblmdb").is_ok() { if !pkg_config::find_library("liblmdb").is_ok() {
gcc::Config::new() cc::Build::new()
.file(lmdb.join("mdb.c")) .file(lmdb.join("mdb.c"))
.file(lmdb.join("midl.c")) .file(lmdb.join("midl.c"))
// https://github.com/LMDB/lmdb/blob/LMDB_0.9.21/libraries/liblmdb/Makefile#L25 // https://github.com/LMDB/lmdb/blob/LMDB_0.9.21/libraries/liblmdb/Makefile#L25

@ -349,7 +349,7 @@ mod test {
fn test_get_dup() { fn test_get_dup() {
let dir = TempDir::new("test").unwrap(); let dir = TempDir::new("test").unwrap();
let env = Environment::new().open(dir.path()).unwrap(); let env = Environment::new().open(dir.path()).unwrap();
let db = env.create_db(None, DUP_SORT).unwrap(); let db = env.create_db(None, DatabaseFlags::DUP_SORT).unwrap();
let mut txn = env.begin_rw_txn().unwrap(); let mut txn = env.begin_rw_txn().unwrap();
txn.put(db, b"key1", b"val1", WriteFlags::empty()).unwrap(); txn.put(db, b"key1", b"val1", WriteFlags::empty()).unwrap();
@ -395,7 +395,7 @@ mod test {
fn test_get_dupfixed() { fn test_get_dupfixed() {
let dir = TempDir::new("test").unwrap(); let dir = TempDir::new("test").unwrap();
let env = Environment::new().open(dir.path()).unwrap(); let env = Environment::new().open(dir.path()).unwrap();
let db = env.create_db(None, DUP_SORT | DUP_FIXED).unwrap(); let db = env.create_db(None, DatabaseFlags::DUP_SORT | DatabaseFlags::DUP_FIXED).unwrap();
let mut txn = env.begin_rw_txn().unwrap(); let mut txn = env.begin_rw_txn().unwrap();
txn.put(db, b"key1", b"val1", WriteFlags::empty()).unwrap(); txn.put(db, b"key1", b"val1", WriteFlags::empty()).unwrap();
@ -449,7 +449,7 @@ mod test {
fn test_iter_dup() { fn test_iter_dup() {
let dir = TempDir::new("test").unwrap(); let dir = TempDir::new("test").unwrap();
let env = Environment::new().open(dir.path()).unwrap(); let env = Environment::new().open(dir.path()).unwrap();
let db = env.create_db(None, DUP_SORT).unwrap(); let db = env.create_db(None, DatabaseFlags::DUP_SORT).unwrap();
let items: Vec<(&[u8], &[u8])> = vec!((b"a", b"1"), let items: Vec<(&[u8], &[u8])> = vec!((b"a", b"1"),
(b"a", b"2"), (b"a", b"2"),

@ -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());

@ -21,7 +21,7 @@ pub use cursor::{
IterDup, IterDup,
}; };
pub use database::Database; pub use database::Database;
pub use environment::{Environment, EnvironmentBuilder}; pub use environment::{Environment, Stat, EnvironmentBuilder};
pub use error::{Error, Result}; pub use error::{Error, Result};
pub use flags::*; pub use flags::*;
pub use transaction::{ pub use transaction::{
@ -107,7 +107,7 @@ mod test_utils {
builder.set_map_size(1_000_000); builder.set_map_size(1_000_000);
builder.open(dir.path()).expect("open lmdb env") builder.open(dir.path()).expect("open lmdb env")
}; };
let index = env.create_db(None, DUP_SORT).expect("open index db"); let index = env.create_db(None, DatabaseFlags::DUP_SORT).expect("open index db");
for height in 0..1000 { for height in 0..1000 {
let mut value = [0u8; 8]; let mut value = [0u8; 8];

Loading…
Cancel
Save