Commit d7acfb70 authored by Huachao Huang's avatar Huachao Huang

fetch properties lazily

parent 0fe7d360
......@@ -35,7 +35,7 @@ pub struct 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) }
}
}
......@@ -1047,9 +1047,9 @@ impl DB {
pub fn get_properties_of_all_tables(&self) -> Result<TablePropertiesCollection, String> {
unsafe {
let props = TablePropertiesCollectionHandle::new();
ffi_try!(crocksdb_get_properties_of_all_tables(self.inner, props.inner));
props.normalize()
let handle = TablePropertiesCollectionHandle::new();
ffi_try!(crocksdb_get_properties_of_all_tables(self.inner, handle.inner));
Ok(TablePropertiesCollection::new(handle))
}
}
......@@ -1057,9 +1057,9 @@ impl DB {
cf: &CFHandle)
-> Result<TablePropertiesCollection, String> {
unsafe {
let props = TablePropertiesCollectionHandle::new();
ffi_try!(crocksdb_get_properties_of_all_tables_cf(self.inner, cf.inner, props.inner));
props.normalize()
let handle = TablePropertiesCollectionHandle::new();
ffi_try!(crocksdb_get_properties_of_all_tables_cf(self.inner, cf.inner, handle.inner));
Ok(TablePropertiesCollection::new(handle))
}
}
......@@ -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_lens: Vec<_> = ranges.iter().map(|x| x.end_key.len()).collect();
unsafe {
let props = TablePropertiesCollectionHandle::new();
let handle = TablePropertiesCollectionHandle::new();
ffi_try!(crocksdb_get_properties_of_tables_in_range(self.inner,
cf.inner,
ranges.len() as i32,
......@@ -1080,8 +1080,8 @@ impl DB {
start_keys_lens.as_ptr(),
limit_keys.as_ptr(),
limit_keys_lens.as_ptr(),
props.inner));
props.normalize()
handle.inner));
Ok(TablePropertiesCollection::new(handle))
}
}
}
......
......@@ -16,58 +16,20 @@ use crocksdb_ffi::{self, DBTableProperties, DBTableProperty, DBUserCollectedProp
DBTablePropertiesCollectionIterator};
use libc::size_t;
use std::collections::HashMap;
use std::marker::PhantomData;
use std::slice;
#[derive(Debug)]
pub struct TableProperties {
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 struct TablePropertiesCollection {
handle: TablePropertiesCollectionHandle,
}
pub type TablePropertiesCollection = HashMap<String, TableProperties>;
pub struct TablePropertiesHandle {
pub inner: *mut DBTableProperties,
}
impl TablePropertiesHandle {
fn new(inner: *mut DBTableProperties) -> TablePropertiesHandle {
TablePropertiesHandle { inner: inner }
impl TablePropertiesCollection {
pub fn new(handle: TablePropertiesCollectionHandle) -> TablePropertiesCollection {
TablePropertiesCollection { handle: handle }
}
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 {
unsafe { crocksdb_ffi::crocksdb_table_properties_get_user_properties(self.inner) }
pub fn iter(&self) -> TablePropertiesCollectionIter {
TablePropertiesCollectionIter::new(self, self.handle.inner)
}
}
......@@ -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 inner: *mut DBTablePropertiesCollectionIterator,
pub struct TablePropertiesCollectionIter<'a> {
props: &'a TablePropertiesCollection,
inner: *mut DBTablePropertiesCollectionIterator,
}
impl Drop for TablePropertiesCollectionIter {
impl<'a> Drop for TablePropertiesCollectionIter<'a> {
fn drop(&mut self) {
unsafe {
crocksdb_ffi::crocksdb_table_properties_collection_iter_destroy(self.inner);
......@@ -147,45 +68,159 @@ impl Drop for TablePropertiesCollectionIter {
}
}
impl TablePropertiesCollectionIter {
fn new(inner: *mut DBTablePropertiesCollection) -> TablePropertiesCollectionIter {
impl<'a> TablePropertiesCollectionIter<'a> {
fn new(props: &'a TablePropertiesCollection,
inner: *mut DBTablePropertiesCollection)
-> TablePropertiesCollectionIter<'a> {
unsafe {
TablePropertiesCollectionIter {
props: props,
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) }
}
fn next(&mut self) {
pub fn next(&mut self) {
unsafe {
crocksdb_ffi::crocksdb_table_properties_collection_iter_next(self.inner);
}
}
fn key(&self) -> Result<String, String> {
pub fn key(&self) -> String {
unsafe {
let mut klen: size_t = 0;
let k = crocksdb_ffi::crocksdb_table_properties_collection_iter_key(
self.inner, &mut klen as *mut size_t);
let k = crocksdb_ffi::crocksdb_table_properties_collection_iter_key(self.inner,
&mut 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()
}
}
fn value(&self) -> *mut DBTableProperties {
unsafe { crocksdb_ffi::crocksdb_table_properties_collection_iter_value(self.inner) }
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)
}
pub fn merge_operator_name(&self) -> String {
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 {
pub inner: *mut DBUserCollectedPropertiesIterator,
struct UserCollectedPropertiesIter<'a> {
phantom: PhantomData<&'a TableProperties<'a>>,
inner: *mut DBUserCollectedPropertiesIterator,
}
impl Drop for UserCollectedPropertiesIter {
impl<'a> Drop for UserCollectedPropertiesIter<'a> {
fn drop(&mut self) {
unsafe {
crocksdb_ffi::crocksdb_user_collected_properties_iter_destroy(self.inner);
......@@ -193,10 +228,13 @@ impl Drop for UserCollectedPropertiesIter {
}
}
impl UserCollectedPropertiesIter {
fn new(inner: *mut DBUserCollectedProperties) -> UserCollectedPropertiesIter {
impl<'a> UserCollectedPropertiesIter<'a> {
fn new(_: &'a TableProperties,
inner: *mut DBUserCollectedProperties)
-> UserCollectedPropertiesIter<'a> {
unsafe {
UserCollectedPropertiesIter {
phantom: PhantomData,
inner: crocksdb_ffi::crocksdb_user_collected_properties_iter_create(inner),
}
}
......@@ -215,9 +253,8 @@ impl UserCollectedPropertiesIter {
fn key(&self) -> &[u8] {
unsafe {
let mut klen: size_t = 0;
let k =
crocksdb_ffi::crocksdb_user_collected_properties_iter_key(self.inner,
&mut klen as *mut size_t);
let k = crocksdb_ffi::crocksdb_user_collected_properties_iter_key(self.inner,
&mut klen);
slice::from_raw_parts(k, klen)
}
}
......@@ -225,8 +262,8 @@ impl UserCollectedPropertiesIter {
fn value(&self) -> &[u8] {
unsafe {
let mut vlen: size_t = 0;
let v = crocksdb_ffi::crocksdb_user_collected_properties_iter_value(
self.inner, &mut vlen as *mut size_t);
let v = crocksdb_ffi::crocksdb_user_collected_properties_iter_value(self.inner,
&mut vlen);
slice::from_raw_parts(v, vlen)
}
}
......
......@@ -16,6 +16,7 @@ use rocksdb::{DB, Range, Options, Writable, DBEntryType, TablePropertiesCollecti
TablePropertiesCollector, TablePropertiesCollectorFactory};
use std::cmp::Ordering;
use std::collections::HashMap;
use std::ffi::CString;
use std::fmt;
use std::io::Cursor;
use tempdir::TempDir;
......@@ -39,6 +40,7 @@ fn decode_u32(x: &[u8]) -> u32 {
}
struct ExampleCollector {
name: CString,
num_keys: u32,
num_puts: u32,
num_merges: u32,
......@@ -49,6 +51,7 @@ struct ExampleCollector {
impl ExampleCollector {
fn new() -> ExampleCollector {
ExampleCollector {
name: CString::new("example-collector").unwrap(),
num_keys: 0,
num_puts: 0,
num_merges: 0,
......@@ -95,11 +98,11 @@ impl fmt::Display for ExampleCollector {
}
impl TablePropertiesCollector for ExampleCollector {
fn name(&self) -> &str {
"example-collector"
fn name(&self) -> &CString {
&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 {
self.num_keys += 1;
self.last_key.clear();
......@@ -119,17 +122,19 @@ impl TablePropertiesCollector for ExampleCollector {
}
}
struct ExampleFactory {}
struct ExampleFactory {
name: CString,
}
impl ExampleFactory {
fn new() -> ExampleFactory {
ExampleFactory {}
ExampleFactory { name: CString::new("example-factory").unwrap() }
}
}
impl TablePropertiesCollectorFactory for ExampleFactory {
fn name(&self) -> &str {
"example-factory"
fn name(&self) -> &CString {
&self.name
}
fn create_table_properties_collector(&mut self, _: u32) -> Box<TablePropertiesCollector> {
......@@ -143,12 +148,19 @@ fn check_collection(collection: &TablePropertiesCollection,
num_puts: u32,
num_merges: u32,
num_deletes: u32) {
let mut len = 0;
let mut res = ExampleCollector::new();
for (_, props) in collection {
assert_eq!(props.property_collectors_names, "[example-factory]");
res.add(&ExampleCollector::decode(&props.user_collected_properties));
let mut iter = collection.iter();
while iter.valid() {
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_puts, num_puts);
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