use crocksdb_ffi::{self, DBTableProperties, DBTablePropertiesCollection,
DBTablePropertiesCollectionIterator, DBTableProperty,
DBUserCollectedProperties, DBUserCollectedPropertiesIterator};
use libc::size_t;
use std::{mem, slice, str};
use std::marker::PhantomData;
use std::ops::{Deref, Index};
pub struct TablePropertiesCollectionView(DBTablePropertiesCollection);
impl TablePropertiesCollectionView {
pub unsafe fn from_ptr<'a>(
collection: *const DBTablePropertiesCollection,
) -> &'a TablePropertiesCollectionView {
let c = &*collection;
mem::transmute(c)
}
pub fn iter(&self) -> TablePropertiesCollectionIter {
self.into_iter()
}
pub fn len(&self) -> usize {
unsafe { crocksdb_ffi::crocksdb_table_properties_collection_len(&self.0) }
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl<'a> IntoIterator for &'a TablePropertiesCollectionView {
type Item = (&'a str, &'a TableProperties);
type IntoIter = TablePropertiesCollectionIter<'a>;
fn into_iter(self) -> Self::IntoIter {
TablePropertiesCollectionIter::new(self)
}
}
pub struct TablePropertiesCollectionIter<'a> {
props: PhantomData<&'a TablePropertiesCollection>,
inner: *mut DBTablePropertiesCollectionIterator,
}
impl<'a> Drop for TablePropertiesCollectionIter<'a> {
fn drop(&mut self) {
unsafe {
crocksdb_ffi::crocksdb_table_properties_collection_iter_destroy(self.inner);
}
}
}
impl<'a> TablePropertiesCollectionIter<'a> {
fn new(props: &'a TablePropertiesCollectionView) -> TablePropertiesCollectionIter<'a> {
unsafe {
TablePropertiesCollectionIter {
props: PhantomData,
inner: crocksdb_ffi::crocksdb_table_properties_collection_iter_create(&props.0),
}
}
}
}
impl<'a> Iterator for TablePropertiesCollectionIter<'a> {
type Item = (&'a str, &'a TableProperties);
fn next(&mut self) -> Option<(&'a str, &'a TableProperties)> {
unsafe {
if !crocksdb_ffi::crocksdb_table_properties_collection_iter_valid(self.inner) {
return None;
}
let mut klen: size_t = 0;
let k =
crocksdb_ffi::crocksdb_table_properties_collection_iter_key(self.inner, &mut klen);
let bytes = slice::from_raw_parts(k, klen);
let key = str::from_utf8(bytes).unwrap();
let props = crocksdb_ffi::crocksdb_table_properties_collection_iter_value(self.inner);
let val = TableProperties::from_ptr(props);
crocksdb_ffi::crocksdb_table_properties_collection_iter_next(self.inner);
Some((key, val))
}
}
}
pub struct TablePropertiesCollection {
inner: *mut DBTablePropertiesCollection,
}
impl Drop for TablePropertiesCollection {
fn drop(&mut self) {
unsafe {
crocksdb_ffi::crocksdb_table_properties_collection_destroy(self.inner);
}
}
}
impl TablePropertiesCollection {
pub unsafe fn from_raw(ptr: *mut DBTablePropertiesCollection) -> TablePropertiesCollection {
TablePropertiesCollection { inner: ptr }
}
}
impl Deref for TablePropertiesCollection {
type Target = TablePropertiesCollectionView;
fn deref(&self) -> &TablePropertiesCollectionView {
unsafe { TablePropertiesCollectionView::from_ptr(self.inner) }
}
}
pub struct TableProperties {
inner: DBTableProperties,
}
impl TableProperties {
pub unsafe fn from_ptr<'a>(ptr: *const DBTableProperties) -> &'a TableProperties {
let res = &*ptr;
mem::transmute(res)
}
fn get_u64(&self, prop: DBTableProperty) -> u64 {
unsafe { crocksdb_ffi::crocksdb_table_properties_get_u64(&self.inner, prop) }
}
fn get_str(&self, prop: DBTableProperty) -> &str {
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);
str::from_utf8(bytes).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) -> &str {
self.get_str(DBTableProperty::ColumnFamilyName)
}
pub fn filter_policy_name(&self) -> &str {
self.get_str(DBTableProperty::FilterPolicyName)
}
pub fn comparator_name(&self) -> &str {
self.get_str(DBTableProperty::ComparatorName)
}
pub fn merge_operator_name(&self) -> &str {
self.get_str(DBTableProperty::MergeOperatorName)
}
pub fn prefix_extractor_name(&self) -> &str {
self.get_str(DBTableProperty::PrefixExtractorName)
}
pub fn property_collectors_names(&self) -> &str {
self.get_str(DBTableProperty::PropertyCollectorsNames)
}
pub fn compression_name(&self) -> &str {
self.get_str(DBTableProperty::CompressionName)
}
pub fn user_collected_properties(&self) -> &UserCollectedProperties {
unsafe {
let ptr = crocksdb_ffi::crocksdb_table_properties_get_user_properties(&self.inner);
UserCollectedProperties::from_ptr(ptr)
}
}
}
pub struct UserCollectedProperties {
inner: DBUserCollectedProperties,
}
impl UserCollectedProperties {
unsafe fn from_ptr<'a>(ptr: *const DBUserCollectedProperties) -> &'a UserCollectedProperties {
let prop = &*ptr;
mem::transmute(prop)
}
pub fn get<Q: AsRef<[u8]>>(&self, index: Q) -> Option<&[u8]> {
let bytes = index.as_ref();
let mut size = 0;
unsafe {
let ptr = crocksdb_ffi::crocksdb_user_collected_properties_get(
&self.inner,
bytes.as_ptr(),
bytes.len(),
&mut size,
);
if ptr.is_null() {
return None;
}
Some(slice::from_raw_parts(ptr, size))
}
}
pub fn len(&self) -> usize {
unsafe { crocksdb_ffi::crocksdb_user_collected_properties_len(&self.inner) }
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl<Q: AsRef<[u8]>> Index<Q> for UserCollectedProperties {
type Output = [u8];
fn index(&self, index: Q) -> &[u8] {
let key = index.as_ref();
self.get(key)
.unwrap_or_else(|| panic!("no entry found for key {:?}", key))
}
}
impl<'a> IntoIterator for &'a UserCollectedProperties {
type Item = (&'a [u8], &'a [u8]);
type IntoIter = UserCollectedPropertiesIter<'a>;
fn into_iter(self) -> Self::IntoIter {
UserCollectedPropertiesIter::new(self)
}
}
pub struct UserCollectedPropertiesIter<'a> {
props: PhantomData<&'a UserCollectedProperties>,
inner: *mut DBUserCollectedPropertiesIterator,
}
impl<'a> Drop for UserCollectedPropertiesIter<'a> {
fn drop(&mut self) {
unsafe {
crocksdb_ffi::crocksdb_user_collected_properties_iter_destroy(self.inner);
}
}
}
impl<'a> UserCollectedPropertiesIter<'a> {
fn new(props: &'a UserCollectedProperties) -> UserCollectedPropertiesIter<'a> {
unsafe {
UserCollectedPropertiesIter {
props: PhantomData,
inner: crocksdb_ffi::crocksdb_user_collected_properties_iter_create(&props.inner),
}
}
}
}
impl<'a> Iterator for UserCollectedPropertiesIter<'a> {
type Item = (&'a [u8], &'a [u8]);
fn next(&mut self) -> Option<(&'a [u8], &'a [u8])> {
unsafe {
if !crocksdb_ffi::crocksdb_user_collected_properties_iter_valid(self.inner) {
return None;
}
let mut klen: size_t = 0;
let k =
crocksdb_ffi::crocksdb_user_collected_properties_iter_key(self.inner, &mut klen);
let key = slice::from_raw_parts(k, klen);
let mut vlen: size_t = 0;
let v =
crocksdb_ffi::crocksdb_user_collected_properties_iter_value(self.inner, &mut vlen);
let val = slice::from_raw_parts(v, vlen);
crocksdb_ffi::crocksdb_user_collected_properties_iter_next(self.inner);
Some((key, val))
}
}
}