Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/database/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub mod kv;
pub mod batch;
pub mod management;
pub mod compaction;
pub mod size;
pub mod bytes;

#[allow(missing_docs)]
Expand Down
35 changes: 35 additions & 0 deletions src/database/size.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//! Compaction
use super::Database;
use super::key::Key;
use leveldb_sys::leveldb_approximate_sizes;
use libc::{c_char, size_t};

pub trait Size<'a, K: Key + 'a> {
fn approximate_size(&self, start: &'a K, stop: &'a K) -> u64;
}

impl<'a, K: Key + 'a> Size<'a, K> for Database<K> {
fn approximate_size(&self, start: &'a K, stop: &'a K) -> u64 {
// TODO: Find a way to get rid of these un-necessary copies, while keeping
// the code simple. If I put the unsafe call inside the closures, the borrow
// checker complains that size is borrowed inside the closures.
let start = start.as_slice(|s| Vec::from(s));
let stop = stop.as_slice(|s| Vec::from(s));

let start_ptr = start.as_ptr() as *const c_char;
let stop_ptr = stop.as_ptr() as *const c_char;

let mut size: u64 = 0;
unsafe {
leveldb_approximate_sizes(
self.database.ptr,
1,
&start_ptr as *const *const c_char,
&start.len() as *const size_t,
&stop_ptr as *const *const c_char,
&stop.len() as *const size_t,
&mut size as *mut u64);
}
size
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub use database::kv;
pub use database::batch;
pub use database::management;
pub use database::compaction;
pub use database::size;

#[allow(missing_docs)]
pub mod database;
Expand Down
22 changes: 22 additions & 0 deletions tests/size.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#[cfg(test)]
mod size {
use utils::{open_database,tmpdir,db_put_simple};
use leveldb::size::Size;

#[test]
fn test_iterator_from_to() {
let tmp = tmpdir("size");
let database = &mut open_database(tmp.path(), true);

assert_eq!(database.approximate_size(&0, &1_000_000), 0);

// We need to write a lot of data so it gets written to disk and size approximation works.
for i in 0..1_000_000 {
db_put_simple(database, i, &[0]);
}

assert!(database.approximate_size(&0, &1_000_000) > 1_000_000);
assert!(database.approximate_size(&1, &1000) < 1_000_000);
assert!(database.approximate_size(&1, &1000) > 1_000);
}
}
3 changes: 2 additions & 1 deletion tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ mod cache;
mod writebatch;
mod management;
mod compaction;
mod concurrent_access;
mod concurrent_access;
mod size;