You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by ms...@apache.org on 2022/10/31 22:26:35 UTC
[incubator-teaclave] 03/03: Update rusty-leveldb version to v1.0.4
This is an automated email from the ASF dual-hosted git repository.
mssun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave.git
commit e5215555a01ef506f3b577dd36e6cd6e26ed9760
Author: sunhe05 <su...@baidu.com>
AuthorDate: Fri Oct 28 09:33:03 2022 +0000
Update rusty-leveldb version to v1.0.4
---
common/rusty_leveldb_sgx/Cargo.toml | 4 +-
common/rusty_leveldb_sgx/README.md | 22 +++--------
common/rusty_leveldb_sgx/src/block_builder.rs | 2 +-
common/rusty_leveldb_sgx/src/cache.rs | 54 +++++++++++++--------------
common/rusty_leveldb_sgx/src/db_impl.rs | 16 +++++---
common/rusty_leveldb_sgx/src/db_iter.rs | 14 ++++++-
common/rusty_leveldb_sgx/src/env.rs | 2 +-
common/rusty_leveldb_sgx/src/error.rs | 27 +++++++++++++-
common/rusty_leveldb_sgx/src/key_types.rs | 22 +++++------
common/rusty_leveldb_sgx/src/lib.rs | 1 +
common/rusty_leveldb_sgx/src/mem_env.rs | 8 ++--
common/rusty_leveldb_sgx/src/options.rs | 2 -
common/rusty_leveldb_sgx/src/skipmap.rs | 2 +-
common/rusty_leveldb_sgx/src/version.rs | 2 +-
common/rusty_leveldb_sgx/src/version_edit.rs | 8 ++--
common/rusty_leveldb_sgx/src/version_set.rs | 4 +-
common/rusty_leveldb_sgx/src/write_batch.rs | 12 +++---
17 files changed, 113 insertions(+), 89 deletions(-)
diff --git a/common/rusty_leveldb_sgx/Cargo.toml b/common/rusty_leveldb_sgx/Cargo.toml
index 2c09ebf9..035aceea 100644
--- a/common/rusty_leveldb_sgx/Cargo.toml
+++ b/common/rusty_leveldb_sgx/Cargo.toml
@@ -1,10 +1,10 @@
[package]
name = "rusty-leveldb"
-version = "0.3.0"
+version = "1.0.4"
authors = ["Lewin Bormann <lb...@spheniscida.de>"]
description = "A compatible re-implementation of LevelDB in Rust"
homepage = "https://github.com/dermesser/leveldb-rs"
-repository = "https://borgac.net/lbo/hg/"
+repository = "https://github.com/dermesser/leveldb-rs"
readme = "README.md"
keywords = ["LevelDB", "key-value", "database", "SSTable", "Google"]
license = "MIT"
diff --git a/common/rusty_leveldb_sgx/README.md b/common/rusty_leveldb_sgx/README.md
index 090264dc..49bead60 100644
--- a/common/rusty_leveldb_sgx/README.md
+++ b/common/rusty_leveldb_sgx/README.md
@@ -1,9 +1,8 @@
-# leveldb-rs
-[](https://ci.mesalock-linux.org/mesalock-linux/rusty_leveldb_sgx)
+# rusty-leveldb-sgx
[](https://crates.io/crates/rusty-leveldb)
A fully compatible implementation of LevelDB in Rust. (any incompatibility is a
-bug!)
+bug!) Be able to run inside SGX.
The implementation is very close to the original; often, you can see the same
algorithm translated 1:1, and class (struct) and method names are similar or
@@ -14,18 +13,7 @@ I do care, however, about bug reports.
## Status
-* User-facing methods exist: Read/Write/Delete; snapshots; iteration
-* Compaction is supported, including manual ones.
-* Fully synchronous: Efficiency gains by using non-atomic types, but writes may
- occasionally block during a compaction. In --release mode, an average compaction
- takes 0.2-0.5 seconds.
-* Compatibility with the original: Compression is not implemented so far; this works
- as long as compression is disabled in the original.
-* Performance is decent; while usually not par with the original, due to multi-threading
- in the original and language-inherent overhead (we are doing things the right way),
- it will be enough for most use cases.
-* Safe: While using many shared pointers, the implementation is generally safe. Many
- places use asserts though, so you may see a crash -- in which case you should file a bug.
+Working well, with a few rare bugs (see leveldb-rs issues).
## Goals
@@ -33,10 +21,10 @@ Some of the goals of this implementation are
* As few copies of data as possible; most of the time, slices of bytes (`&[u8]`)
are used. Owned memory is represented as `Vec<u8>` (and then possibly borrowed
- as slice).
+ as slice). Zero-copy is not always possible, though, and sometimes simplicity is favored.
* Correctness -- self-checking implementation, good test coverage, etc. Just
like the original implementation.
* Clarity; commented code, clear structure (hopefully doing a better job than
the original implementation).
* Coming close-ish to the original implementation; clarifying the translation of
- typical C++ constructs to Rust.
+ typical C++ constructs to Rust, and doing a better job at helping understand the internals.
diff --git a/common/rusty_leveldb_sgx/src/block_builder.rs b/common/rusty_leveldb_sgx/src/block_builder.rs
index ed20ef9b..fdaa1b88 100644
--- a/common/rusty_leveldb_sgx/src/block_builder.rs
+++ b/common/rusty_leveldb_sgx/src/block_builder.rs
@@ -39,7 +39,7 @@ impl BlockBuilder {
self.counter
}
- pub fn last_key<'a>(&'a self) -> &'a [u8] {
+ pub fn last_key(&self) -> &[u8] {
&self.last_key
}
diff --git a/common/rusty_leveldb_sgx/src/cache.rs b/common/rusty_leveldb_sgx/src/cache.rs
index 386e3272..c29228c3 100644
--- a/common/rusty_leveldb_sgx/src/cache.rs
+++ b/common/rusty_leveldb_sgx/src/cache.rs
@@ -2,7 +2,7 @@
use std::prelude::v1::*;
use std::collections::HashMap;
-use std::mem::{replace, swap};
+use std::mem::swap;
// No clone, no copy! That asserts that an LRUHandle exists only once.
type LRUHandle<T> = *mut LRUNode<T>;
@@ -88,7 +88,7 @@ impl<T> LRUList<T> {
// Set up the node after the new one
self.head.next.as_mut().unwrap().prev = Some(newp);
// Replace head.next with None and set the new node's next to that
- new.next = replace(&mut self.head.next, None);
+ new.next = self.head.next.take();
self.head.next = Some(new);
newp
@@ -111,21 +111,18 @@ impl<T> LRUList<T> {
}
fn remove_last(&mut self) -> Option<T> {
- if self.head.prev.is_some() {
- let mut lasto = unsafe {
- replace(
- &mut (*((*self.head.prev.unwrap()).prev.unwrap())).next,
- None,
- )
- };
-
- if let Some(ref mut last) = lasto {
- self.head.prev = last.prev;
- self.count -= 1;
- return replace(&mut (*last).data, None);
- } else {
- None
- }
+ if self.count() == 0 {
+ return None;
+ }
+ let mut lasto = unsafe { (*((*self.head.prev.unwrap()).prev.unwrap())).next.take() };
+
+ assert!(lasto.is_some());
+ if let Some(ref mut last) = lasto {
+ assert!(last.prev.is_some());
+ assert!(self.head.prev.is_some());
+ self.head.prev = last.prev;
+ self.count -= 1;
+ (*last).data.take()
} else {
None
}
@@ -133,21 +130,20 @@ impl<T> LRUList<T> {
fn remove(&mut self, node_handle: LRUHandle<T>) -> T {
unsafe {
- // If has next
- if let Some(ref mut nextp) = (*node_handle).next {
- (**nextp).prev = (*node_handle).prev;
- }
- // If has prev
- if let Some(ref mut prevp) = (*node_handle).prev {
- // swap prev.next
- // (node_handle will own itself now)
- swap(&mut (**prevp).next, &mut (*node_handle).next);
+ let d = (*node_handle).data.take().unwrap();
+ // Take ownership of node to be removed.
+ let mut current = (*(*node_handle).prev.unwrap()).next.take().unwrap();
+ let prev = current.prev.unwrap();
+ // Update previous node's successor.
+ if current.next.is_some() {
+ // Update next node's predecessor.
+ current.next.as_mut().unwrap().prev = current.prev.take();
}
+ (*prev).next = current.next.take();
self.count -= 1;
- // node_handle now only has references/objects that point to itself,
- // so it's safe to drop
- replace(&mut (*node_handle).data, None).unwrap()
+
+ d
}
}
diff --git a/common/rusty_leveldb_sgx/src/db_impl.rs b/common/rusty_leveldb_sgx/src/db_impl.rs
index 04cb7575..e2d9aa3f 100644
--- a/common/rusty_leveldb_sgx/src/db_impl.rs
+++ b/common/rusty_leveldb_sgx/src/db_impl.rs
@@ -191,13 +191,17 @@ impl DB {
let mut log_files = vec![];
for file in &filenames {
- if let Ok((num, typ)) = parse_file_name(&file) {
- expected.remove(&num);
- if typ == FileType::Log
- && (num >= self.vset.borrow().log_num || num == self.vset.borrow().prev_log_num)
- {
- log_files.push(num);
+ match parse_file_name(&file) {
+ Ok((num, typ)) => {
+ expected.remove(&num);
+ if typ == FileType::Log
+ && (num >= self.vset.borrow().log_num
+ || num == self.vset.borrow().prev_log_num)
+ {
+ log_files.push(num);
+ }
}
+ Err(e) => return Err(e.annotate(format!("While parsing {:?}", file))),
}
}
if !expected.is_empty() {
diff --git a/common/rusty_leveldb_sgx/src/db_iter.rs b/common/rusty_leveldb_sgx/src/db_iter.rs
index 72f2098f..f7dc090c 100644
--- a/common/rusty_leveldb_sgx/src/db_iter.rs
+++ b/common/rusty_leveldb_sgx/src/db_iter.rs
@@ -62,7 +62,7 @@ impl DBIterator {
/// record_read_sample records a read sample using the current contents of self.keybuf, which
/// should be an InternalKey.
- fn record_read_sample<'a>(&mut self, len: usize) {
+ fn record_read_sample(&mut self, len: usize) {
self.byte_count -= len as isize;
if self.byte_count < 0 {
let v = self.vset.borrow().current();
@@ -284,7 +284,7 @@ impl LdbIterator for DBIterator {
}
fn random_period() -> isize {
- rand::random::<isize>() % 2 * READ_BYTES_PERIOD
+ rand::random::<isize>() % (2 * READ_BYTES_PERIOD)
}
#[cfg(feature = "enclave_unit_test")]
@@ -292,6 +292,7 @@ pub mod tests {
use super::*;
use crate::db_impl::testutil::*;
use crate::db_impl::DB;
+ use crate::options;
use crate::test_util::LdbIteratorIter;
use crate::types::{current_key_val, Direction};
@@ -309,6 +310,7 @@ pub mod tests {
db_iter_deleted_entry_not_returned,
db_iter_deleted_entry_not_returned_memtable,
db_iter_repeated_open_close,
+ db_iter_allow_empty_key,
)
}
@@ -494,4 +496,12 @@ pub mod tests {
}
}
}
+
+ fn db_iter_allow_empty_key() {
+ let opt = options::for_test();
+ let mut db = DB::open("db", opt).unwrap();
+ assert!(db.new_iter().unwrap().next().is_none());
+ db.put(&[], &[]).unwrap();
+ assert!(db.new_iter().unwrap().next().is_some());
+ }
}
diff --git a/common/rusty_leveldb_sgx/src/env.rs b/common/rusty_leveldb_sgx/src/env.rs
index 33ce9838..04451e16 100644
--- a/common/rusty_leveldb_sgx/src/env.rs
+++ b/common/rusty_leveldb_sgx/src/env.rs
@@ -57,7 +57,7 @@ impl Logger {
Logger { dst: w }
}
- pub fn log(&mut self, message: &String) {
+ pub fn log(&mut self, message: &str) {
let _ = self.dst.write(message.as_bytes());
let _ = self.dst.write("\n".as_bytes());
}
diff --git a/common/rusty_leveldb_sgx/src/error.rs b/common/rusty_leveldb_sgx/src/error.rs
index 3f55bf95..929202bd 100644
--- a/common/rusty_leveldb_sgx/src/error.rs
+++ b/common/rusty_leveldb_sgx/src/error.rs
@@ -70,6 +70,13 @@ impl Status {
}
return Status { code, err };
}
+
+ pub fn annotate<S: AsRef<str>>(self, msg: S) -> Status {
+ Status {
+ code: self.code,
+ err: format!("{}: {}", msg.as_ref(), self.err),
+ }
+ }
}
/// LevelDB's result type
@@ -90,7 +97,7 @@ impl From<io::Error> for Status {
_ => StatusCode::IOError,
};
- Status::new(c, e.description())
+ Status::new(c, &e.to_string())
}
}
@@ -104,7 +111,23 @@ impl From<snap::Error> for Status {
fn from(e: snap::Error) -> Status {
Status {
code: StatusCode::CompressionError,
- err: e.description().to_string(),
+ err: e.to_string(),
}
}
}
+
+#[cfg(feature = "enclave_unit_test")]
+pub mod tests {
+ use super::{Status, StatusCode};
+ use std::prelude::v1::*;
+ use teaclave_test_utils::*;
+
+ pub fn run_tests() -> bool {
+ run_tests!(test_status_to_string,)
+ }
+
+ fn test_status_to_string() {
+ let s = Status::new(StatusCode::InvalidData, "Invalid data!");
+ assert_eq!("InvalidData: Invalid data!", s.to_string());
+ }
+}
diff --git a/common/rusty_leveldb_sgx/src/key_types.rs b/common/rusty_leveldb_sgx/src/key_types.rs
index 6c92dddc..0febc080 100644
--- a/common/rusty_leveldb_sgx/src/key_types.rs
+++ b/common/rusty_leveldb_sgx/src/key_types.rs
@@ -47,11 +47,11 @@ pub struct LookupKey {
const U64_SPACE: usize = 8;
impl LookupKey {
- pub fn new<'a>(k: UserKey<'a>, s: SequenceNumber) -> LookupKey {
+ pub fn new(k: UserKey, s: SequenceNumber) -> LookupKey {
LookupKey::new_full(k, s, ValueType::TypeValue)
}
- pub fn new_full<'a>(k: UserKey<'a>, s: SequenceNumber, t: ValueType) -> LookupKey {
+ pub fn new_full(k: UserKey, s: SequenceNumber, t: ValueType) -> LookupKey {
let mut key = Vec::new();
let internal_keylen = k.len() + U64_SPACE;
key.resize(k.len() + internal_keylen.required_space() + U64_SPACE, 0);
@@ -61,7 +61,7 @@ impl LookupKey {
writer
.write_varint(internal_keylen)
.expect("write to slice failed");
- writer.write(k).expect("write to slice failed");
+ writer.write_all(k).expect("write to slice failed");
writer
.write_fixedint(s << 8 | t as u64)
.expect("write to slice failed");
@@ -74,17 +74,17 @@ impl LookupKey {
}
/// Returns the full memtable-formatted key.
- pub fn memtable_key<'a>(&'a self) -> MemtableKey<'a> {
+ pub fn memtable_key(&self) -> MemtableKey {
self.key.as_slice()
}
/// Returns only the user key portion.
- pub fn user_key<'a>(&'a self) -> UserKey<'a> {
+ pub fn user_key(&self) -> UserKey {
&self.key[self.key_offset..self.key.len() - 8]
}
/// Returns key and tag.
- pub fn internal_key<'a>(&'a self) -> InternalKey<'a> {
+ pub fn internal_key(&self) -> InternalKey {
&self.key[self.key_offset..]
}
}
@@ -123,12 +123,12 @@ pub fn build_memtable_key(key: &[u8], value: &[u8], t: ValueType, seq: SequenceN
{
let mut writer = buf.as_mut_slice();
writer.write_varint(keysize).expect("write to slice failed");
- writer.write(key).expect("write to slice failed");
+ writer.write_all(key).expect("write to slice failed");
writer
.write_fixedint((t as u64) | (seq << 8))
.expect("write to slice failed");
writer.write_varint(valsize).expect("write to slice failed");
- writer.write(value).expect("write to slice failed");
+ writer.write_all(value).expect("write to slice failed");
assert_eq!(writer.len(), 0);
}
buf
@@ -137,7 +137,7 @@ pub fn build_memtable_key(key: &[u8], value: &[u8], t: ValueType, seq: SequenceN
/// Parses a memtable key and returns (keylen, key offset, tag, vallen, val offset).
/// If the key only contains (keylen, key, tag), the vallen and val offset return values will be
/// meaningless.
-pub fn parse_memtable_key<'a>(mkey: MemtableKey<'a>) -> (usize, usize, u64, usize, usize) {
+pub fn parse_memtable_key(mkey: MemtableKey) -> (usize, usize, u64, usize, usize) {
let (keylen, mut i): (usize, usize) = VarInt::decode_var(&mkey);
let keyoff = i;
i += keylen - 8;
@@ -181,7 +181,7 @@ pub fn cmp_memtable_key<'a, 'b>(
}
/// Parse a key in InternalKey format.
-pub fn parse_internal_key<'a>(ikey: InternalKey<'a>) -> (ValueType, SequenceNumber, UserKey<'a>) {
+pub fn parse_internal_key(ikey: InternalKey) -> (ValueType, SequenceNumber, UserKey) {
if ikey.is_empty() {
return (ValueType::TypeDeletion, 0, &ikey[0..0]);
}
@@ -212,7 +212,7 @@ pub fn cmp_internal_key<'a, 'b>(
/// truncate_to_userkey performs an in-place conversion from InternalKey to UserKey format.
pub fn truncate_to_userkey(ikey: &mut Vec<u8>) {
let len = ikey.len();
- assert!(len > 8);
+ assert!(len >= 8);
ikey.truncate(len - 8);
}
diff --git a/common/rusty_leveldb_sgx/src/lib.rs b/common/rusty_leveldb_sgx/src/lib.rs
index a5727b6e..96f82cbf 100644
--- a/common/rusty_leveldb_sgx/src/lib.rs
+++ b/common/rusty_leveldb_sgx/src/lib.rs
@@ -102,6 +102,7 @@ pub mod tests {
db_impl::tests::run_tests(),
db_iter::tests::run_tests(),
disk_env::tests::run_tests(),
+ error::tests::run_tests(),
filter::tests::run_tests(),
filter_block::tests::run_tests(),
key_types::tests::run_tests(),
diff --git a/common/rusty_leveldb_sgx/src/mem_env.rs b/common/rusty_leveldb_sgx/src/mem_env.rs
index 609e370b..cd6dd1f4 100644
--- a/common/rusty_leveldb_sgx/src/mem_env.rs
+++ b/common/rusty_leveldb_sgx/src/mem_env.rs
@@ -175,13 +175,15 @@ impl MemFS {
fn children_of(&self, p: &Path) -> Result<Vec<PathBuf>> {
let fs = self.store.lock()?;
let mut prefix = path_to_string(p);
- if !prefix.ends_with("/") {
- prefix.push('/');
+ let main_separator_str = std::path::MAIN_SEPARATOR.to_string();
+ if !prefix.ends_with(&main_separator_str) {
+ prefix.push(std::path::MAIN_SEPARATOR);
}
+
let mut children = Vec::new();
for k in fs.keys() {
if k.starts_with(&prefix) {
- children.push(Path::new(k.trim_start_matches(&prefix)).to_owned());
+ children.push(Path::new(k.strip_prefix(&prefix).unwrap_or(&k)).to_owned());
}
}
Ok(children)
diff --git a/common/rusty_leveldb_sgx/src/options.rs b/common/rusty_leveldb_sgx/src/options.rs
index edd57d04..5c81040e 100644
--- a/common/rusty_leveldb_sgx/src/options.rs
+++ b/common/rusty_leveldb_sgx/src/options.rs
@@ -40,8 +40,6 @@ pub fn int_to_compressiontype(i: u32) -> Option<CompressionType> {
/// Options contains general parameters for a LevelDB instance. Most of the names are
/// self-explanatory; the defaults are defined in the `Default` implementation.
-///
-/// Note: Compression is not yet implemented.
#[derive(Clone)]
pub struct Options {
pub cmp: Rc<Box<dyn Cmp>>,
diff --git a/common/rusty_leveldb_sgx/src/skipmap.rs b/common/rusty_leveldb_sgx/src/skipmap.rs
index 5b368f04..2b73ab62 100644
--- a/common/rusty_leveldb_sgx/src/skipmap.rs
+++ b/common/rusty_leveldb_sgx/src/skipmap.rs
@@ -236,7 +236,7 @@ impl InnerSkipMap {
}
// Construct new node
- let mut new_skips = Vec::with_capacity(new_height);
+ let mut new_skips = Vec::new();
new_skips.resize(new_height, None);
let mut new = Box::new(Node {
skips: new_skips,
diff --git a/common/rusty_leveldb_sgx/src/version.rs b/common/rusty_leveldb_sgx/src/version.rs
index db0d7c7b..7ac8041f 100644
--- a/common/rusty_leveldb_sgx/src/version.rs
+++ b/common/rusty_leveldb_sgx/src/version.rs
@@ -259,7 +259,7 @@ impl Version {
/// overlap_in_level returns true if the specified level's files overlap the range [smallest;
/// largest].
- pub fn overlap_in_level<'a, 'b>(
+ pub fn overlap_in_level<'a>(
&self,
level: usize,
smallest: UserKey<'a>,
diff --git a/common/rusty_leveldb_sgx/src/version_edit.rs b/common/rusty_leveldb_sgx/src/version_edit.rs
index 81eab837..9def74db 100644
--- a/common/rusty_leveldb_sgx/src/version_edit.rs
+++ b/common/rusty_leveldb_sgx/src/version_edit.rs
@@ -135,7 +135,7 @@ impl VersionEdit {
buf.write_varint(EditTag::Comparator as u32).unwrap();
// data is prefixed by a varint32 describing the length of the following chunk
buf.write_varint(cmp.len()).unwrap();
- buf.write(cmp.as_bytes()).unwrap();
+ buf.write_all(cmp.as_bytes()).unwrap();
}
if let Some(lognum) = self.log_number {
@@ -162,7 +162,7 @@ impl VersionEdit {
buf.write_varint(EditTag::CompactPointer as u32).unwrap();
buf.write_varint(cptr.level).unwrap();
buf.write_varint(cptr.key.len()).unwrap();
- buf.write(cptr.key.as_ref()).unwrap();
+ buf.write_all(cptr.key.as_ref()).unwrap();
}
for df in self.deleted.iter() {
@@ -178,9 +178,9 @@ impl VersionEdit {
buf.write_varint(nf.1.size).unwrap();
buf.write_varint(nf.1.smallest.len()).unwrap();
- buf.write(nf.1.smallest.as_ref()).unwrap();
+ buf.write_all(nf.1.smallest.as_ref()).unwrap();
buf.write_varint(nf.1.largest.len()).unwrap();
- buf.write(nf.1.largest.as_ref()).unwrap();
+ buf.write_all(nf.1.largest.as_ref()).unwrap();
}
buf
diff --git a/common/rusty_leveldb_sgx/src/version_set.rs b/common/rusty_leveldb_sgx/src/version_set.rs
index 37189762..08d690ee 100644
--- a/common/rusty_leveldb_sgx/src/version_set.rs
+++ b/common/rusty_leveldb_sgx/src/version_set.rs
@@ -891,8 +891,8 @@ pub fn set_current_file<P: AsRef<Path>>(
let tempfile = temp_file_name(dbname, manifest_file_num);
{
let mut f = env.open_writable_file(Path::new(&tempfile))?;
- f.write(manifest_base.as_os_str().as_bytes())?;
- f.write("\n".as_bytes())?;
+ f.write_all(manifest_base.as_os_str().as_bytes())?;
+ f.write_all("\n".as_bytes())?;
}
let currentfile = current_file_name(dbname);
if let Err(e) = env.rename(Path::new(&tempfile), Path::new(¤tfile)) {
diff --git a/common/rusty_leveldb_sgx/src/write_batch.rs b/common/rusty_leveldb_sgx/src/write_batch.rs
index 826e7131..b0c032b2 100644
--- a/common/rusty_leveldb_sgx/src/write_batch.rs
+++ b/common/rusty_leveldb_sgx/src/write_batch.rs
@@ -38,11 +38,13 @@ impl WriteBatch {
/// Adds an entry to a WriteBatch, to be added to the database.
#[allow(unused_assignments)]
pub fn put(&mut self, k: &[u8], v: &[u8]) {
- self.entries.write(&[ValueType::TypeValue as u8]).unwrap();
+ self.entries
+ .write_all(&[ValueType::TypeValue as u8])
+ .unwrap();
self.entries.write_varint(k.len()).unwrap();
- self.entries.write(k).unwrap();
+ self.entries.write_all(k).unwrap();
self.entries.write_varint(v.len()).unwrap();
- self.entries.write(v).unwrap();
+ self.entries.write_all(v).unwrap();
let c = self.count();
self.set_count(c + 1);
@@ -52,7 +54,7 @@ impl WriteBatch {
#[allow(unused_assignments)]
pub fn delete(&mut self, k: &[u8]) {
self.entries
- .write(&[ValueType::TypeDeletion as u8])
+ .write_all(&[ValueType::TypeDeletion as u8])
.unwrap();
self.entries.write_varint(k.len()).unwrap();
self.entries.write(k).unwrap();
@@ -87,7 +89,7 @@ impl WriteBatch {
u64::decode_fixed(&self.entries[SEQNUM_OFFSET..SEQNUM_OFFSET + 8])
}
- pub fn iter<'a>(&'a self) -> WriteBatchIter<'a> {
+ pub fn iter(&self) -> WriteBatchIter {
WriteBatchIter {
batch: self,
ix: HEADER_SIZE,
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org