Commit d7acfb70 authored by Huachao Huang's avatar Huachao Huang

fetch properties lazily

parent 0fe7d360
...@@ -35,7 +35,7 @@ pub struct CFHandle { ...@@ -35,7 +35,7 @@ pub struct CFHandle {
} }
impl CFHandle { impl CFHandle {
pub fn get_id(&self) -> u32 { pub fn id(&self) -> u32 {
unsafe { crocksdb_ffi::crocksdb_column_family_handle_get_id(self.inner) } unsafe { crocksdb_ffi::crocksdb_column_family_handle_get_id(self.inner) }
} }
} }
...@@ -1047,9 +1047,9 @@ impl DB { ...@@ -1047,9 +1047,9 @@ impl DB {
pub fn get_properties_of_all_tables(&self) -> Result<TablePropertiesCollection, String> { pub fn get_properties_of_all_tables(&self) -> Result<TablePropertiesCollection, String> {
unsafe { unsafe {
let props = TablePropertiesCollectionHandle::new(); let handle = TablePropertiesCollectionHandle::new();
ffi_try!(crocksdb_get_properties_of_all_tables(self.inner, props.inner)); ffi_try!(crocksdb_get_properties_of_all_tables(self.inner, handle.inner));
props.normalize() Ok(TablePropertiesCollection::new(handle))
} }
} }
...@@ -1057,9 +1057,9 @@ impl DB { ...@@ -1057,9 +1057,9 @@ impl DB {
cf: &CFHandle) cf: &CFHandle)
-> Result<TablePropertiesCollection, String> { -> Result<TablePropertiesCollection, String> {
unsafe { unsafe {
let props = TablePropertiesCollectionHandle::new(); let handle = TablePropertiesCollectionHandle::new();
ffi_try!(crocksdb_get_properties_of_all_tables_cf(self.inner, cf.inner, props.inner)); ffi_try!(crocksdb_get_properties_of_all_tables_cf(self.inner, cf.inner, handle.inner));
props.normalize() Ok(TablePropertiesCollection::new(handle))
} }
} }
...@@ -1072,7 +1072,7 @@ impl DB { ...@@ -1072,7 +1072,7 @@ impl DB {
let limit_keys: Vec<*const u8> = ranges.iter().map(|x| x.end_key.as_ptr()).collect(); let limit_keys: Vec<*const u8> = ranges.iter().map(|x| x.end_key.as_ptr()).collect();
let limit_keys_lens: Vec<_> = ranges.iter().map(|x| x.end_key.len()).collect(); let limit_keys_lens: Vec<_> = ranges.iter().map(|x| x.end_key.len()).collect();
unsafe { unsafe {
let props = TablePropertiesCollectionHandle::new(); let handle = TablePropertiesCollectionHandle::new();
ffi_try!(crocksdb_get_properties_of_tables_in_range(self.inner, ffi_try!(crocksdb_get_properties_of_tables_in_range(self.inner,
cf.inner, cf.inner,
ranges.len() as i32, ranges.len() as i32,
...@@ -1080,8 +1080,8 @@ impl DB { ...@@ -1080,8 +1080,8 @@ impl DB {
start_keys_lens.as_ptr(), start_keys_lens.as_ptr(),
limit_keys.as_ptr(), limit_keys.as_ptr(),
limit_keys_lens.as_ptr(), limit_keys_lens.as_ptr(),
props.inner)); handle.inner));
props.normalize() Ok(TablePropertiesCollection::new(handle))
} }
} }
} }
......
...@@ -16,58 +16,20 @@ use crocksdb_ffi::{self, DBTableProperties, DBTableProperty, DBUserCollectedProp ...@@ -16,58 +16,20 @@ use crocksdb_ffi::{self, DBTableProperties, DBTableProperty, DBUserCollectedProp
DBTablePropertiesCollectionIterator}; DBTablePropertiesCollectionIterator};
use libc::size_t; use libc::size_t;
use std::collections::HashMap; use std::collections::HashMap;
use std::marker::PhantomData;
use std::slice; use std::slice;
#[derive(Debug)] pub struct TablePropertiesCollection {
pub struct TableProperties { handle: TablePropertiesCollectionHandle,
pub data_size: u64,
pub index_size: u64,
pub filter_size: u64,
pub raw_key_size: u64,
pub raw_value_size: u64,
pub num_data_blocks: u64,
pub num_entries: u64,
pub format_version: u64,
pub fixed_key_len: u64,
pub column_family_id: u64,
pub column_family_name: String,
pub filter_policy_name: String,
pub comparator_name: String,
pub merge_operator_name: String,
pub prefix_extractor_name: String,
pub property_collectors_names: String,
pub compression_name: String,
pub user_collected_properties: HashMap<Vec<u8>, Vec<u8>>,
} }
pub type TablePropertiesCollection = HashMap<String, TableProperties>; impl TablePropertiesCollection {
pub fn new(handle: TablePropertiesCollectionHandle) -> TablePropertiesCollection {
pub struct TablePropertiesHandle { TablePropertiesCollection { handle: handle }
pub inner: *mut DBTableProperties,
}
impl TablePropertiesHandle {
fn new(inner: *mut DBTableProperties) -> TablePropertiesHandle {
TablePropertiesHandle { inner: inner }
}
fn get_u64(&self, prop: DBTableProperty) -> u64 {
unsafe { crocksdb_ffi::crocksdb_table_properties_get_u64(self.inner, prop) }
}
fn get_str(&self, prop: DBTableProperty) -> Result<String, String> {
unsafe {
let mut slen: size_t = 0;
let s = crocksdb_ffi::crocksdb_table_properties_get_str(self.inner,
prop,
&mut slen as *mut size_t);
let bytes = slice::from_raw_parts(s, slen);
String::from_utf8(bytes.to_owned()).or_else(|e| Err(format!("{}", e)))
}
} }
fn get_user_properties(&self) -> *mut DBUserCollectedProperties { pub fn iter(&self) -> TablePropertiesCollectionIter {
unsafe { crocksdb_ffi::crocksdb_table_properties_get_user_properties(self.inner) } TablePropertiesCollectionIter::new(self, self.handle.inner)
} }
} }
...@@ -91,55 +53,14 @@ impl TablePropertiesCollectionHandle { ...@@ -91,55 +53,14 @@ impl TablePropertiesCollectionHandle {
} }
} }
} }
pub fn normalize(&self) -> Result<TablePropertiesCollection, String> {
let mut collection = TablePropertiesCollection::new();
let mut it = TablePropertiesCollectionIter::new(self.inner);
while it.valid() {
let k = try!(it.key());
let v = TablePropertiesHandle::new(it.value());
let mut props = TableProperties {
data_size: v.get_u64(DBTableProperty::DataSize),
index_size: v.get_u64(DBTableProperty::IndexSize),
filter_size: v.get_u64(DBTableProperty::FilterSize),
raw_key_size: v.get_u64(DBTableProperty::RawKeySize),
raw_value_size: v.get_u64(DBTableProperty::RawValueSize),
num_data_blocks: v.get_u64(DBTableProperty::NumDataBlocks),
num_entries: v.get_u64(DBTableProperty::NumEntries),
format_version: v.get_u64(DBTableProperty::FormatVersion),
fixed_key_len: v.get_u64(DBTableProperty::FixedKeyLen),
column_family_id: v.get_u64(DBTableProperty::ColumnFamilyId),
column_family_name: try!(v.get_str(DBTableProperty::ColumnFamilyName)),
filter_policy_name: try!(v.get_str(DBTableProperty::FilterPolicyName)),
comparator_name: try!(v.get_str(DBTableProperty::ComparatorName)),
merge_operator_name: try!(v.get_str(DBTableProperty::MergeOperatorName)),
prefix_extractor_name: try!(v.get_str(DBTableProperty::PrefixExtractorName)),
property_collectors_names:
try!(v.get_str(DBTableProperty::PropertyCollectorsNames)),
compression_name: try!(v.get_str(DBTableProperty::CompressionName)),
user_collected_properties: HashMap::new(),
};
let mut user_it = UserCollectedPropertiesIter::new(v.get_user_properties());
while user_it.valid() {
{
let k = user_it.key();
let v = user_it.value();
props.user_collected_properties.insert(k.to_owned(), v.to_owned());
}
user_it.next();
}
collection.insert(k, props);
it.next();
}
Ok(collection)
}
} }
struct TablePropertiesCollectionIter { pub struct TablePropertiesCollectionIter<'a> {
pub inner: *mut DBTablePropertiesCollectionIterator, props: &'a TablePropertiesCollection,
inner: *mut DBTablePropertiesCollectionIterator,
} }
impl Drop for TablePropertiesCollectionIter { impl<'a> Drop for TablePropertiesCollectionIter<'a> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
crocksdb_ffi::crocksdb_table_properties_collection_iter_destroy(self.inner); crocksdb_ffi::crocksdb_table_properties_collection_iter_destroy(self.inner);
...@@ -147,45 +68,159 @@ impl Drop for TablePropertiesCollectionIter { ...@@ -147,45 +68,159 @@ impl Drop for TablePropertiesCollectionIter {
} }
} }
impl TablePropertiesCollectionIter { impl<'a> TablePropertiesCollectionIter<'a> {
fn new(inner: *mut DBTablePropertiesCollection) -> TablePropertiesCollectionIter { fn new(props: &'a TablePropertiesCollection,
inner: *mut DBTablePropertiesCollection)
-> TablePropertiesCollectionIter<'a> {
unsafe { unsafe {
TablePropertiesCollectionIter { TablePropertiesCollectionIter {
props: props,
inner: crocksdb_ffi::crocksdb_table_properties_collection_iter_create(inner), inner: crocksdb_ffi::crocksdb_table_properties_collection_iter_create(inner),
} }
} }
} }
fn valid(&self) -> bool { pub fn valid(&self) -> bool {
unsafe { crocksdb_ffi::crocksdb_table_properties_collection_iter_valid(self.inner) } unsafe { crocksdb_ffi::crocksdb_table_properties_collection_iter_valid(self.inner) }
} }
fn next(&mut self) { pub fn next(&mut self) {
unsafe { unsafe {
crocksdb_ffi::crocksdb_table_properties_collection_iter_next(self.inner); crocksdb_ffi::crocksdb_table_properties_collection_iter_next(self.inner);
} }
} }
fn key(&self) -> Result<String, String> { pub fn key(&self) -> String {
unsafe { unsafe {
let mut klen: size_t = 0; let mut klen: size_t = 0;
let k = crocksdb_ffi::crocksdb_table_properties_collection_iter_key( let k = crocksdb_ffi::crocksdb_table_properties_collection_iter_key(self.inner,
self.inner, &mut klen as *mut size_t); &mut klen);
let bytes = slice::from_raw_parts(k, klen); let bytes = slice::from_raw_parts(k, klen);
String::from_utf8(bytes.to_owned()).or_else(|e| Err(format!("{}", e))) String::from_utf8(bytes.to_owned()).unwrap()
}
}
pub fn value(&self) -> TableProperties {
unsafe {
let inner = crocksdb_ffi::crocksdb_table_properties_collection_iter_value(self.inner);
TableProperties::new(self.props, inner)
}
}
}
pub struct TableProperties<'a> {
phantom: PhantomData<&'a TablePropertiesCollection>,
inner: *mut DBTableProperties,
}
impl<'a> TableProperties<'a> {
fn new(_: &'a TablePropertiesCollection, inner: *mut DBTableProperties) -> TableProperties {
TableProperties {
phantom: PhantomData,
inner: inner,
}
}
fn get_u64(&self, prop: DBTableProperty) -> u64 {
unsafe { crocksdb_ffi::crocksdb_table_properties_get_u64(self.inner, prop) }
}
fn get_str(&self, prop: DBTableProperty) -> String {
unsafe {
let mut slen: size_t = 0;
let s = crocksdb_ffi::crocksdb_table_properties_get_str(self.inner, prop, &mut slen);
let bytes = slice::from_raw_parts(s, slen);
String::from_utf8(bytes.to_owned()).unwrap()
}
}
pub fn data_size(&self) -> u64 {
self.get_u64(DBTableProperty::DataSize)
}
pub fn index_size(&self) -> u64 {
self.get_u64(DBTableProperty::IndexSize)
}
pub fn filter_size(&self) -> u64 {
self.get_u64(DBTableProperty::FilterSize)
}
pub fn raw_key_size(&self) -> u64 {
self.get_u64(DBTableProperty::RawKeySize)
}
pub fn raw_value_size(&self) -> u64 {
self.get_u64(DBTableProperty::RawValueSize)
}
pub fn num_data_blocks(&self) -> u64 {
self.get_u64(DBTableProperty::NumDataBlocks)
}
pub fn num_entries(&self) -> u64 {
self.get_u64(DBTableProperty::NumEntries)
}
pub fn format_version(&self) -> u64 {
self.get_u64(DBTableProperty::FormatVersion)
} }
pub fn fixed_key_len(&self) -> u64 {
self.get_u64(DBTableProperty::FixedKeyLen)
}
pub fn column_family_id(&self) -> u64 {
self.get_u64(DBTableProperty::ColumnFamilyId)
}
pub fn column_family_name(&self) -> String {
self.get_str(DBTableProperty::ColumnFamilyName)
}
pub fn filter_policy_name(&self) -> String {
self.get_str(DBTableProperty::FilterPolicyName)
}
pub fn comparator_name(&self) -> String {
self.get_str(DBTableProperty::ComparatorName)
} }
fn value(&self) -> *mut DBTableProperties { pub fn merge_operator_name(&self) -> String {
unsafe { crocksdb_ffi::crocksdb_table_properties_collection_iter_value(self.inner) } self.get_str(DBTableProperty::MergeOperatorName)
}
pub fn prefix_extractor_name(&self) -> String {
self.get_str(DBTableProperty::PrefixExtractorName)
}
pub fn property_collectors_names(&self) -> String {
self.get_str(DBTableProperty::PropertyCollectorsNames)
}
pub fn compression_name(&self) -> String {
self.get_str(DBTableProperty::CompressionName)
}
pub fn user_collected_properties(&self) -> HashMap<Vec<u8>, Vec<u8>> {
let inner =
unsafe { crocksdb_ffi::crocksdb_table_properties_get_user_properties(self.inner) };
let mut iter = UserCollectedPropertiesIter::new(self, inner);
let mut props = HashMap::new();
while iter.valid() {
props.insert(iter.key().to_owned(), iter.value().to_owned());
iter.next();
}
props
} }
} }
struct UserCollectedPropertiesIter { struct UserCollectedPropertiesIter<'a> {
pub inner: *mut DBUserCollectedPropertiesIterator, phantom: PhantomData<&'a TableProperties<'a>>,
inner: *mut DBUserCollectedPropertiesIterator,
} }
impl Drop for UserCollectedPropertiesIter { impl<'a> Drop for UserCollectedPropertiesIter<'a> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
crocksdb_ffi::crocksdb_user_collected_properties_iter_destroy(self.inner); crocksdb_ffi::crocksdb_user_collected_properties_iter_destroy(self.inner);
...@@ -193,10 +228,13 @@ impl Drop for UserCollectedPropertiesIter { ...@@ -193,10 +228,13 @@ impl Drop for UserCollectedPropertiesIter {
} }
} }
impl UserCollectedPropertiesIter { impl<'a> UserCollectedPropertiesIter<'a> {
fn new(inner: *mut DBUserCollectedProperties) -> UserCollectedPropertiesIter { fn new(_: &'a TableProperties,
inner: *mut DBUserCollectedProperties)
-> UserCollectedPropertiesIter<'a> {
unsafe { unsafe {
UserCollectedPropertiesIter { UserCollectedPropertiesIter {
phantom: PhantomData,
inner: crocksdb_ffi::crocksdb_user_collected_properties_iter_create(inner), inner: crocksdb_ffi::crocksdb_user_collected_properties_iter_create(inner),
} }
} }
...@@ -215,9 +253,8 @@ impl UserCollectedPropertiesIter { ...@@ -215,9 +253,8 @@ impl UserCollectedPropertiesIter {
fn key(&self) -> &[u8] { fn key(&self) -> &[u8] {
unsafe { unsafe {
let mut klen: size_t = 0; let mut klen: size_t = 0;
let k = let k = crocksdb_ffi::crocksdb_user_collected_properties_iter_key(self.inner,
crocksdb_ffi::crocksdb_user_collected_properties_iter_key(self.inner, &mut klen);
&mut klen as *mut size_t);
slice::from_raw_parts(k, klen) slice::from_raw_parts(k, klen)
} }
} }
...@@ -225,8 +262,8 @@ impl UserCollectedPropertiesIter { ...@@ -225,8 +262,8 @@ impl UserCollectedPropertiesIter {
fn value(&self) -> &[u8] { fn value(&self) -> &[u8] {
unsafe { unsafe {
let mut vlen: size_t = 0; let mut vlen: size_t = 0;
let v = crocksdb_ffi::crocksdb_user_collected_properties_iter_value( let v = crocksdb_ffi::crocksdb_user_collected_properties_iter_value(self.inner,
self.inner, &mut vlen as *mut size_t); &mut vlen);
slice::from_raw_parts(v, vlen) slice::from_raw_parts(v, vlen)
} }
} }
......
...@@ -16,6 +16,7 @@ use rocksdb::{DB, Range, Options, Writable, DBEntryType, TablePropertiesCollecti ...@@ -16,6 +16,7 @@ use rocksdb::{DB, Range, Options, Writable, DBEntryType, TablePropertiesCollecti
TablePropertiesCollector, TablePropertiesCollectorFactory}; TablePropertiesCollector, TablePropertiesCollectorFactory};
use std::cmp::Ordering; use std::cmp::Ordering;
use std::collections::HashMap; use std::collections::HashMap;
use std::ffi::CString;
use std::fmt; use std::fmt;
use std::io::Cursor; use std::io::Cursor;
use tempdir::TempDir; use tempdir::TempDir;
...@@ -39,6 +40,7 @@ fn decode_u32(x: &[u8]) -> u32 { ...@@ -39,6 +40,7 @@ fn decode_u32(x: &[u8]) -> u32 {
} }
struct ExampleCollector { struct ExampleCollector {
name: CString,
num_keys: u32, num_keys: u32,
num_puts: u32, num_puts: u32,
num_merges: u32, num_merges: u32,
...@@ -49,6 +51,7 @@ struct ExampleCollector { ...@@ -49,6 +51,7 @@ struct ExampleCollector {
impl ExampleCollector { impl ExampleCollector {
fn new() -> ExampleCollector { fn new() -> ExampleCollector {
ExampleCollector { ExampleCollector {
name: CString::new("example-collector").unwrap(),
num_keys: 0, num_keys: 0,
num_puts: 0, num_puts: 0,
num_merges: 0, num_merges: 0,
...@@ -95,11 +98,11 @@ impl fmt::Display for ExampleCollector { ...@@ -95,11 +98,11 @@ impl fmt::Display for ExampleCollector {
} }
impl TablePropertiesCollector for ExampleCollector { impl TablePropertiesCollector for ExampleCollector {
fn name(&self) -> &str { fn name(&self) -> &CString {
"example-collector" &self.name
} }
fn add_userkey(&mut self, key: &[u8], _: &[u8], entry_type: DBEntryType) { fn add_userkey(&mut self, key: &[u8], _: &[u8], entry_type: DBEntryType, _: u64, _: u64) {
if key.cmp(&self.last_key) != Ordering::Equal { if key.cmp(&self.last_key) != Ordering::Equal {
self.num_keys += 1; self.num_keys += 1;
self.last_key.clear(); self.last_key.clear();
...@@ -119,17 +122,19 @@ impl TablePropertiesCollector for ExampleCollector { ...@@ -119,17 +122,19 @@ impl TablePropertiesCollector for ExampleCollector {
} }
} }
struct ExampleFactory {} struct ExampleFactory {
name: CString,
}
impl ExampleFactory { impl ExampleFactory {
fn new() -> ExampleFactory { fn new() -> ExampleFactory {
ExampleFactory {} ExampleFactory { name: CString::new("example-factory").unwrap() }
} }
} }
impl TablePropertiesCollectorFactory for ExampleFactory { impl TablePropertiesCollectorFactory for ExampleFactory {
fn name(&self) -> &str { fn name(&self) -> &CString {
"example-factory" &self.name
} }
fn create_table_properties_collector(&mut self, _: u32) -> Box<TablePropertiesCollector> { fn create_table_properties_collector(&mut self, _: u32) -> Box<TablePropertiesCollector> {
...@@ -143,12 +148,19 @@ fn check_collection(collection: &TablePropertiesCollection, ...@@ -143,12 +148,19 @@ fn check_collection(collection: &TablePropertiesCollection,
num_puts: u32, num_puts: u32,
num_merges: u32, num_merges: u32,
num_deletes: u32) { num_deletes: u32) {
let mut len = 0;
let mut res = ExampleCollector::new(); let mut res = ExampleCollector::new();
for (_, props) in collection { let mut iter = collection.iter();
assert_eq!(props.property_collectors_names, "[example-factory]"); while iter.valid() {
res.add(&ExampleCollector::decode(&props.user_collected_properties)); len += 1;
{
let v = iter.value();
assert_eq!(v.property_collectors_names(), "[example-factory]");
res.add(&ExampleCollector::decode(&v.user_collected_properties()));
}
iter.next();
} }
assert_eq!(collection.len() as u32, num_files); assert_eq!(len, num_files);
assert_eq!(res.num_keys, num_keys); assert_eq!(res.num_keys, num_keys);
assert_eq!(res.num_puts, num_puts); assert_eq!(res.num_puts, num_puts);
assert_eq!(res.num_merges, num_merges); assert_eq!(res.num_merges, num_merges);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment