pub struct WriteBatchWithIndex { /* private fields */ }Expand description
A write batch that can also be read from, and that can be layered on top of a database iterator.
There is deliberately no vectored write here, unlike
WriteBatch::put_vectored.
WriteBatchWithIndex does not override the SliceParts overloads, so
rocksdb_writebatch_wi_putv and friends fall through to
WriteBatchBase, which concatenates the parts into a temporary
std::string and calls the single-slice path anyway. Joining the parts in
Rust costs the same copy and lets the caller reuse the buffer.
Values read out of the batch are copied, but iterators and pinned slices borrow, so the borrow checker is what keeps them from outliving their owner.
An iterator built with Self::iterator_with_base reads directly out of the
batch’s internal skip-list, so it cannot outlive the batch:
use rust_rocksdb::{DB, WriteBatchWithIndex};
let db = DB::open_default("foo").unwrap();
let mut iter = {
let mut wbwi = WriteBatchWithIndex::new(0, true);
wbwi.put(b"k", b"v");
wbwi.iterator_with_base(db.raw_iterator())
};
iter.seek_to_first();A slice from Self::get_pinned_from_batch_and_db pins a block in the
database’s block cache, so it cannot outlive the database:
use rust_rocksdb::{DB, ReadOptions, WriteBatchWithIndex};
let wbwi = WriteBatchWithIndex::new(0, true);
let readopts = ReadOptions::default();
let _value = {
let db = DB::open_default("foo").unwrap();
wbwi.get_pinned_from_batch_and_db(&db, b"k", &readopts).unwrap()
};Implementations§
Source§impl WriteBatchWithIndex
impl WriteBatchWithIndex
pub fn new(reserved_bytes: usize, overwrite_key: bool) -> Self
Sourcepub fn builder() -> WriteBatchWithIndexBuilder
pub fn builder() -> WriteBatchWithIndexBuilder
Starts building a batch with a custom comparator, size cap, or per-key checksums.
use rust_rocksdb::WriteBatchWithIndex;
let mut batch = WriteBatchWithIndex::builder()
.overwrite_key(true)
.max_bytes(1 << 20)
.protection_bytes_per_key(8)
.build();
batch.put(b"k", b"v");
assert_eq!(batch.len(), 1);pub fn len(&self) -> usize
Sourcepub fn size_in_bytes(&self) -> usize
pub fn size_in_bytes(&self) -> usize
Return WriteBatch serialized size (in bytes).
Sourcepub fn data(&self) -> &[u8] ⓘ
pub fn data(&self) -> &[u8] ⓘ
Return a reference to a byte array which represents a serialized version of the batch.
pub fn is_empty(&self) -> bool
pub fn get_from_batch<K>( &self, key: K, options: &Options, ) -> Result<Option<Vec<u8>>, Error>
pub fn get_from_batch_cf<K>( &self, cf: &impl AsColumnFamilyRef, key: K, options: &Options, ) -> Result<Option<Vec<u8>>, Error>
pub fn get_from_batch_and_db<T, I, K>( &self, db: &DBCommon<T, I>, key: K, readopts: &ReadOptions, ) -> Result<Option<Vec<u8>>, Error>
Sourcepub fn get_pinned_from_batch_and_db<'db, T, I, K>(
&self,
db: &'db DBCommon<T, I>,
key: K,
readopts: &ReadOptions,
) -> Result<Option<DBPinnableSlice<'db>>, Error>
pub fn get_pinned_from_batch_and_db<'db, T, I, K>( &self, db: &'db DBCommon<T, I>, key: K, readopts: &ReadOptions, ) -> Result<Option<DBPinnableSlice<'db>>, Error>
The returned slice pins a block inside db’s block cache, so its
lifetime is tied to db rather than to self. Letting lifetime elision
pick &self here would allow the slice to outlive the database and
release a cache handle into a destroyed cache.
pub fn get_from_batch_and_db_cf<T, I, K>( &self, db: &DBCommon<T, I>, cf: &impl AsColumnFamilyRef, key: K, readopts: &ReadOptions, ) -> Result<Option<Vec<u8>>, Error>
Sourcepub fn get_pinned_from_batch_and_db_cf<'db, T, I, K>(
&self,
db: &'db DBCommon<T, I>,
cf: &impl AsColumnFamilyRef,
key: K,
readopts: &ReadOptions,
) -> Result<Option<DBPinnableSlice<'db>>, Error>
pub fn get_pinned_from_batch_and_db_cf<'db, T, I, K>( &self, db: &'db DBCommon<T, I>, cf: &impl AsColumnFamilyRef, key: K, readopts: &ReadOptions, ) -> Result<Option<DBPinnableSlice<'db>>, Error>
The returned slice pins a block inside db’s block cache, so its
lifetime is tied to db rather than to self. See
Self::get_pinned_from_batch_and_db.
Sourcepub fn put<K, V>(&mut self, key: K, value: V)
pub fn put<K, V>(&mut self, key: K, value: V)
Insert a value into the database under the given key.
pub fn put_cf<K, V>(&mut self, cf: &impl AsColumnFamilyRef, key: K, value: V)
pub fn merge<K, V>(&mut self, key: K, value: V)
pub fn merge_cf<K, V>(&mut self, cf: &impl AsColumnFamilyRef, key: K, value: V)
Sourcepub fn delete<K: AsRef<[u8]>>(&mut self, key: K)
pub fn delete<K: AsRef<[u8]>>(&mut self, key: K)
Removes the database entry for key. Does nothing if the key was not found.
pub fn delete_cf<K: AsRef<[u8]>>(&mut self, cf: &impl AsColumnFamilyRef, key: K)
Sourcepub fn single_delete<K: AsRef<[u8]>>(&mut self, key: K)
pub fn single_delete<K: AsRef<[u8]>>(&mut self, key: K)
Removes the database entry for a key that was written exactly once.
This is a cheaper delete than delete, but it is only
correct when the key has had at most one put and no merge since the
last delete of that key. Using it on a key that was written more than
once leaves an older version visible, and RocksDB does not report that
as an error.
Sourcepub fn single_delete_cf<K: AsRef<[u8]>>(
&mut self,
cf: &impl AsColumnFamilyRef,
key: K,
)
pub fn single_delete_cf<K: AsRef<[u8]>>( &mut self, cf: &impl AsColumnFamilyRef, key: K, )
Removes the entry for a write-once key in the given column family.
See single_delete for when this is safe to use.
Sourcepub fn delete_range<K: AsRef<[u8]>>(&mut self, from: K, to: K)
pub fn delete_range<K: AsRef<[u8]>>(&mut self, from: K, to: K)
Removes entries in the range [from, to).
Range deletes are recorded in the batch but they are not indexed. Reads
and iterators that go through the batch, such as
get_from_batch and
iterator_with_base, do not see them. They
only take effect once the batch is written to the database.
Sourcepub fn delete_range_cf<K: AsRef<[u8]>>(
&mut self,
cf: &impl AsColumnFamilyRef,
from: K,
to: K,
)
pub fn delete_range_cf<K: AsRef<[u8]>>( &mut self, cf: &impl AsColumnFamilyRef, from: K, to: K, )
Removes entries in the range [from, to) of one column family.
See delete_range for why these are invisible to
reads through the batch.
Sourcepub fn put_log_data<V: AsRef<[u8]>>(&mut self, log_data: V)
pub fn put_log_data<V: AsRef<[u8]>>(&mut self, log_data: V)
Append a blob of arbitrary size to the records in this batch.
The blob goes to the write-ahead log but never to an SST file, and it
consumes no sequence number and does not change len.
Sourcepub fn set_save_point(&mut self)
pub fn set_save_point(&mut self)
Record the current state of the batch so it can be undone later.
Save points nest, so each call pushes onto a stack that
rollback_to_save_point pops from.
Sourcepub fn rollback_to_save_point(&mut self) -> Result<(), Error>
pub fn rollback_to_save_point(&mut self) -> Result<(), Error>
Undo every operation recorded since the most recent save point, and pop that save point.
Returns an error if there is no save point to roll back to.
Sourcepub unsafe fn update_timestamps<S, F>(
&mut self,
ts: S,
get_ts_size: F,
) -> Result<(), Error>
pub unsafe fn update_timestamps<S, F>( &mut self, ts: S, get_ts_size: F, ) -> Result<(), Error>
Overwrite the user-defined timestamp on every entry in the batch.
get_ts_size is called with each column family id the batch touches and
must return the timestamp width configured for that column family, or 0
if it does not use timestamps. ts must be exactly as wide as every
non-zero size it returns.
§Safety
Every key already recorded for a column family whose get_ts_size
returns a non-zero width must be at least that many bytes long, which in
practice means it was written through one of the _with_ts methods and
already carries a timestamp suffix of exactly that width. RocksDB
overwrites the last width bytes of each key without checking that the
key is that long, so a shorter key makes it write in front of the key and
corrupt the heap. Mixing plain put with a non-zero width
for the same column family is what usually triggers this.
§Errors
Returns an error if ts is empty, if its length differs from a non-zero
width returned by get_ts_size, or if get_ts_size reports that it
could not find the width for a column family.
Sourcepub fn iterator_with_base<'a, D>(
&'a self,
base_iterator: DBRawIteratorWithThreadMode<'a, D>,
) -> DBRawIteratorWithThreadMode<'a, D>where
D: DBAccess,
pub fn iterator_with_base<'a, D>(
&'a self,
base_iterator: DBRawIteratorWithThreadMode<'a, D>,
) -> DBRawIteratorWithThreadMode<'a, D>where
D: DBAccess,
The returned iterator reads directly out of this batch’s internal
skip-list and write buffer, so it must not outlive the batch. Binding
&self to the same lifetime as the base iterator is what enforces that;
with an independent lifetime on &self the iterator could outlive the
batch and read freed memory.
Sourcepub fn iterator_with_base_cf<'a, D>(
&'a self,
base_iterator: DBRawIteratorWithThreadMode<'a, D>,
cf: &impl AsColumnFamilyRef,
) -> DBRawIteratorWithThreadMode<'a, D>where
D: DBAccess,
pub fn iterator_with_base_cf<'a, D>(
&'a self,
base_iterator: DBRawIteratorWithThreadMode<'a, D>,
cf: &impl AsColumnFamilyRef,
) -> DBRawIteratorWithThreadMode<'a, D>where
D: DBAccess,
The returned iterator reads directly out of this batch, so it must not
outlive the batch. See Self::iterator_with_base.