changeset 56:d2a045a69a0a

Add encoding functionality to WriteBatch
author Lewin Bormann <lbo@spheniscida.de>
date Sun, 19 Jun 2016 17:50:26 +0200
parents 07f4454f6ea3
children fbdaaa9b266d
files Cargo.toml src/write_batch.rs
diffstat 2 files changed, 61 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/Cargo.toml	Sun Jun 19 17:10:19 2016 +0200
+++ b/Cargo.toml	Sun Jun 19 17:50:26 2016 +0200
@@ -5,6 +5,6 @@
 
 [dependencies]
 crc = "1.2"
-integer-encoding = "0.11.0"
+integer-encoding = "0.12.0"
 libc = "0.2"
 rand = "0.3"
--- a/src/write_batch.rs	Sun Jun 19 17:10:19 2016 +0200
+++ b/src/write_batch.rs	Sun Jun 19 17:50:26 2016 +0200
@@ -1,5 +1,6 @@
 use memtable::MemTable;
 use types::{Comparator, SequenceNumber, ValueType};
+use integer_encoding::VarInt;
 
 struct BatchEntry<'a> {
     key: &'a [u8],
@@ -45,6 +46,23 @@
         self.entries.clear()
     }
 
+    fn byte_size(&self) -> usize {
+        let mut size = 0;
+
+        for e in self.entries.iter() {
+            size += e.key.len() + e.key.len().required_space();
+
+            if let Some(v) = e.val {
+                size += v.len() + v.len().required_space();
+            } else {
+                size += 1;
+            }
+
+            size += 1; // account for tag
+        }
+        size
+    }
+
     fn iter<'b>(&'b self) -> WriteBatchIter<'b, 'a> {
         WriteBatchIter {
             batch: self,
@@ -63,6 +81,46 @@
             sequence_num += 1;
         }
     }
+
+    fn encode(&self) -> Vec<u8> {
+        let mut buf = Vec::with_capacity(self.byte_size());
+        let mut ix = 0;
+
+        for (k, v) in self.iter() {
+            if let Some(_) = v {
+                buf.push(ValueType::TypeValue as u8);
+            } else {
+                buf.push(ValueType::TypeDeletion as u8);
+            }
+
+            ix += 1;
+
+            let req = k.len().required_space();
+            buf.resize(ix + req, 0);
+            ix += k.len().encode_var(&mut buf[ix..ix + req]);
+
+            buf.extend_from_slice(k);
+            ix += k.len();
+
+            let req2;
+            let v_;
+
+            if let Some(v__) = v {
+                v_ = v__;
+                req2 = v_.len().required_space();
+            } else {
+                v_ = "".as_bytes();
+                req2 = 0.required_space();
+            }
+
+            buf.resize(ix + req2, 0);
+            ix += v_.len().encode_var(&mut buf[ix..ix + req2]);
+
+            buf.extend_from_slice(v_);
+            ix += v_.len();
+        }
+        buf
+    }
 }
 
 pub struct WriteBatchIter<'b, 'a: 'b> {
@@ -106,6 +164,8 @@
             }
         }
 
+        assert_eq!(b.byte_size(), 39);
+        assert_eq!(b.encode().len(), 39);
         assert_eq!(b.iter().count(), 5);
 
         let mut i = 0;