Use NonNull in DBRawIteratorWithThreadMode (#650)

master
Michal Nazarewicz 2 years ago committed by GitHub
parent 701d46198b
commit 653d37f3cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 50
      src/db_iterator.rs

@ -70,7 +70,7 @@ pub type DBRawIterator<'a> = DBRawIteratorWithThreadMode<'a, DB>;
/// let _ = DB::destroy(&Options::default(), path);
/// ```
pub struct DBRawIteratorWithThreadMode<'a, D: DBAccess> {
inner: *mut ffi::rocksdb_iterator_t,
inner: std::ptr::NonNull<ffi::rocksdb_iterator_t>,
/// When iterate_upper_bound is set, the inner C iterator keeps a pointer to the upper bound
/// inside `_readopts`. Storing this makes sure the upper bound is always alive when the
@ -82,13 +82,8 @@ pub struct DBRawIteratorWithThreadMode<'a, D: DBAccess> {
impl<'a, D: DBAccess> DBRawIteratorWithThreadMode<'a, D> {
pub(crate) fn new(db: &D, readopts: ReadOptions) -> Self {
unsafe {
Self {
inner: ffi::rocksdb_create_iterator(db.inner(), readopts.inner),
_readopts: readopts,
db: PhantomData,
}
}
let inner = unsafe { ffi::rocksdb_create_iterator(db.inner(), readopts.inner) };
Self::from_inner(inner, readopts)
}
pub(crate) fn new_cf(
@ -96,14 +91,23 @@ impl<'a, D: DBAccess> DBRawIteratorWithThreadMode<'a, D> {
cf_handle: *mut ffi::rocksdb_column_family_handle_t,
readopts: ReadOptions,
) -> Self {
unsafe {
let inner =
unsafe { ffi::rocksdb_create_iterator_cf(db.inner(), readopts.inner, cf_handle) };
Self::from_inner(inner, readopts)
}
fn from_inner(inner: *mut ffi::rocksdb_iterator_t, readopts: ReadOptions) -> Self {
// This unwrap will never fail since rocksdb_create_iterator and
// rocksdb_create_iterator_cf functions always return non-null. They
// use new and deference the result so any nulls would end up in SIGSEGV
// there and we have bigger issue.
let inner = std::ptr::NonNull::new(inner).unwrap();
Self {
inner: ffi::rocksdb_create_iterator_cf(db.inner(), readopts.inner, cf_handle),
inner,
_readopts: readopts,
db: PhantomData,
}
}
}
/// Returns `true` if the iterator is valid. An iterator is invalidated when
/// it reaches the end of its defined range, or when it encounters an error.
@ -112,7 +116,7 @@ impl<'a, D: DBAccess> DBRawIteratorWithThreadMode<'a, D> {
/// returned `false`, use the [`status`](DBRawIteratorWithThreadMode::status) method. `status` will never
/// return an error when `valid` is `true`.
pub fn valid(&self) -> bool {
unsafe { ffi::rocksdb_iter_valid(self.inner) != 0 }
unsafe { ffi::rocksdb_iter_valid(self.inner.as_ptr()) != 0 }
}
/// Returns an error `Result` if the iterator has encountered an error
@ -122,7 +126,7 @@ impl<'a, D: DBAccess> DBRawIteratorWithThreadMode<'a, D> {
/// Performing a seek will discard the current status.
pub fn status(&self) -> Result<(), Error> {
unsafe {
ffi_try!(ffi::rocksdb_iter_get_error(self.inner));
ffi_try!(ffi::rocksdb_iter_get_error(self.inner.as_ptr()));
}
Ok(())
}
@ -160,7 +164,7 @@ impl<'a, D: DBAccess> DBRawIteratorWithThreadMode<'a, D> {
/// ```
pub fn seek_to_first(&mut self) {
unsafe {
ffi::rocksdb_iter_seek_to_first(self.inner);
ffi::rocksdb_iter_seek_to_first(self.inner.as_ptr());
}
}
@ -197,7 +201,7 @@ impl<'a, D: DBAccess> DBRawIteratorWithThreadMode<'a, D> {
/// ```
pub fn seek_to_last(&mut self) {
unsafe {
ffi::rocksdb_iter_seek_to_last(self.inner);
ffi::rocksdb_iter_seek_to_last(self.inner.as_ptr());
}
}
@ -232,7 +236,7 @@ impl<'a, D: DBAccess> DBRawIteratorWithThreadMode<'a, D> {
unsafe {
ffi::rocksdb_iter_seek(
self.inner,
self.inner.as_ptr(),
key.as_ptr() as *const c_char,
key.len() as size_t,
);
@ -271,7 +275,7 @@ impl<'a, D: DBAccess> DBRawIteratorWithThreadMode<'a, D> {
unsafe {
ffi::rocksdb_iter_seek_for_prev(
self.inner,
self.inner.as_ptr(),
key.as_ptr() as *const c_char,
key.len() as size_t,
);
@ -281,14 +285,14 @@ impl<'a, D: DBAccess> DBRawIteratorWithThreadMode<'a, D> {
/// Seeks to the next key.
pub fn next(&mut self) {
unsafe {
ffi::rocksdb_iter_next(self.inner);
ffi::rocksdb_iter_next(self.inner.as_ptr());
}
}
/// Seeks to the previous key.
pub fn prev(&mut self) {
unsafe {
ffi::rocksdb_iter_prev(self.inner);
ffi::rocksdb_iter_prev(self.inner.as_ptr());
}
}
@ -300,7 +304,8 @@ impl<'a, D: DBAccess> DBRawIteratorWithThreadMode<'a, D> {
unsafe {
let mut key_len: size_t = 0;
let key_len_ptr: *mut size_t = &mut key_len;
let key_ptr = ffi::rocksdb_iter_key(self.inner, key_len_ptr) as *const c_uchar;
let key_ptr =
ffi::rocksdb_iter_key(self.inner.as_ptr(), key_len_ptr) as *const c_uchar;
Some(slice::from_raw_parts(key_ptr, key_len as usize))
}
@ -317,7 +322,8 @@ impl<'a, D: DBAccess> DBRawIteratorWithThreadMode<'a, D> {
unsafe {
let mut val_len: size_t = 0;
let val_len_ptr: *mut size_t = &mut val_len;
let val_ptr = ffi::rocksdb_iter_value(self.inner, val_len_ptr) as *const c_uchar;
let val_ptr =
ffi::rocksdb_iter_value(self.inner.as_ptr(), val_len_ptr) as *const c_uchar;
Some(slice::from_raw_parts(val_ptr, val_len as usize))
}
@ -330,7 +336,7 @@ impl<'a, D: DBAccess> DBRawIteratorWithThreadMode<'a, D> {
impl<'a, D: DBAccess> Drop for DBRawIteratorWithThreadMode<'a, D> {
fn drop(&mut self) {
unsafe {
ffi::rocksdb_iter_destroy(self.inner);
ffi::rocksdb_iter_destroy(self.inner.as_ptr());
}
}
}

Loading…
Cancel
Save