Repository: dgraph-io/badger
Pull request #1453 (2020-08-07 15:12:02)

Add gc command in badger
This PR adds a new `gc` command. `badger gc --dir` can be used to clean up all the vlog files that have more than 50% stale data.
 Use `badger gc --dry-run --dir xxx` to get information about stale data in every vlog file.

<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/dgraph-io/badger/1453)
<!-- Reviewable:end -->


jarifibrahim: ```
gc --dir xxx 
```
This should clean up whatever it can. Default discard ratio of 0.5.
`--files` blobs.

Patch:
diff --git a/README.md b/README.md
index 26c75a9..76bc17f 100644
--- a/README.md
+++ b/README.md
@@ -188,7 +188,7 @@ Below is a list of known projects that use Badger:
 * [Cete](https://github.com/mosuka/cete) - Simple and highly available distributed key-value store built on Badger. Makes it easy bringing up a cluster of Badger with Raft consensus algorithm by hashicorp/raft. 
 * [Volument](https://volument.com/) - A new take on website analytics backed by Badger.
 * [KVdb](https://kvdb.io/) - Hosted key-value store and serverless platform built on top of Badger.
-* [Terminotes] (https://gitlab.com/asad-awadia/terminotes) - Self hosted notes storage and search server - storage powered by BadgerDB
+* [Terminotes](https://gitlab.com/asad-awadia/terminotes) - Self hosted notes storage and search server - storage powered by BadgerDB
 
 If you are using Badger in a project please send a pull request to add it to the list.
 
diff --git a/badger/cmd/vloggc.go b/badger/cmd/vloggc.go
new file mode 100644
index 0000000..9a4eb72
--- /dev/null
+++ b/badger/cmd/vloggc.go
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2020 Dgraph Labs, Inc. and Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cmd
+
+import (
+	"fmt"
+	"math"
+	"sort"
+
+	"github.com/dgraph-io/badger/v2"
+	"github.com/spf13/cobra"
+)
+
+var gcCmd = &cobra.Command{
+	Use:   "gc command is used to clean the vlog files",
+	Short: "GC vlog files",
+	Long: ` GC command can be used to perform garbage collection of vlog files.
+	This command will gc all vlog files that have at least 50% stale data.
+
+	Use --dry-run flag to calculate the amount of stale data in each vlog
+	file.
+`,
+	RunE: gc,
+}
+
+type gcOptions struct {
+	dryRun     bool
+	numVersion int
+}
+
+var gopt gcOptions
+
+func init() {
+	RootCmd.AddCommand(gcCmd)
+	gcCmd.Flags().BoolVarP(&gopt.dryRun, "dry-run", "d", false, "Perform only sampling "+
+		"and don't do GC. This will output vlog files and their discard ratio.")
+	gcCmd.Flags().IntVarP(&gopt.numVersion, "num-versions", "n", 1, "Number of versions to keep. "+
+		"A value <= 0 would keep all the versions.")
+}
+
+func gc(cmd *cobra.Command, args []string) error {
+	if gopt.numVersion <= 0 {
+		gopt.numVersion = math.MaxUint32
+	}
+
+	opt := badger.DefaultOptions(sstDir).
+		WithValueDir(vlogDir).
+		WithNumVersionsToKeep(gopt.numVersion)
+
+	db, err := badger.Open(opt)
+	if err != nil {
+		return err
+	}
+	defer db.Close()
+
+	if gopt.dryRun {
+		res, err := db.SampleVlog()
+		if err != nil {
+			return err
+		}
+		sort.Slice(res, func(i, j int) bool { return res[i].DiscardRatio > res[j].DiscardRatio })
+
+		for _, r := range res {
+			fmt.Printf("Fid: %d DiscardRatio: %f\n", r.Fid, r.DiscardRatio)
+		}
+	} else {
+		return db.GCVlog()
+	}
+	return nil
+}
diff --git a/batch.go b/batch.go
index 4ec54ca..60fa2c0 100644
--- a/batch.go
+++ b/batch.go
@@ -82,6 +82,7 @@ func (wb *WriteBatch) Cancel() {
 	wb.txn.Discard()
 }
 
+// The caller of this callback must hold the lock.
 func (wb *WriteBatch) callback(err error) {
 	// sync.WaitGroup is thread-safe, so it doesn't need to be run inside wb.Lock.
 	defer wb.throttle.Done(err)
@@ -89,8 +90,6 @@ func (wb *WriteBatch) callback(err error) {
 		return
 	}
 
-	wb.Lock()
-	defer wb.Unlock()
 	if wb.err != nil {
 		return
 	}
diff --git a/db.go b/db.go
index 53b39ae..fe19b2a 100644
--- a/db.go
+++ b/db.go
@@ -1842,6 +1842,18 @@ func createDirs(opt Options) error {
 	return nil
 }
 
+// GCVlog will GC all the .vlog files that have more than 50% stale data. GC is
+// an expensive process and the GCVlog call could take some time to finish.
+func (db *DB) GCVlog() error {
+	return db.vlog.cleanVlog()
+}
+
+// SampleVlog can be used to collect information about the amount of stale data
+// in all the vlog files.
+func (db *DB) SampleVlog() ([]sampleResult, error) {
+	return db.vlog.getDiscardStats()
+}
+
 // Stream the contents of this DB to a new DB with options outOptions that will be
 // created in outDir.
 func (db *DB) StreamDB(outOptions Options) error {
diff --git a/docs/README.md b/docs/README.md
index 891bc79..7f0b846 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,17 +1,22 @@
 # Badger Docs
 
-If you are looking for Badger documentation, you might find https://dgraph.io/docs/badger much more readable.
+If you are looking for Badger's documentation, you might find https://dgraph.io/docs/badger much more readable.
 
-## Contributing
+## Getting Started
 
 We use [Hugo](https://gohugo.io/) for our documentation.
 
 ### Running locally
 
- Download and install the latest patch of hugo version v0.69.x from [here](https://github.com/gohugoio/hugo/releases/).
+1. Download and install the latest patch of Hugo version v0.69.x from [here](https://github.com/gohugoio/hugo/releases/).
+2. Run `hugo server` within the `docs` folder.
+3. Visit http://localhost:1313 to see the documentation site.
+
+## Contributing
 
-From within the docs folder, run the command below to get the theme.
+If you're interested in contributing to Badger, please review our [guidelines](../CONTRIBUTING.md).
 
-cd themes && git clone https://github.com/dgraph-io/hugo-docs
+## Contact
 
-Run hugo server within the docs folder and visit http://localhost:1313 to see the documentation site.
+- Please use [discuss.dgraph.io](https://discuss.dgraph.io) for questions, feature requests, and discussions.
+- Follow us on Twitter [@dgraphlabs](https://twitter.com/dgraphlabs).
diff --git a/docs/config.toml b/docs/config.toml
index a50fa59..e2a734c 100644
--- a/docs/config.toml
+++ b/docs/config.toml
@@ -31,8 +31,8 @@ noClasses = false
   weight = 3
 
 [[menu.main]]
-  name = "Project Using Badger"
-  url = "/project-using-badger/"
+  name = "Projects using Badger"
+  url = "/projects-using-badger/"
   identifier = "project-using-badger"
   weight = 4
 
diff --git a/docs/content/_index.md b/docs/content/_index.md
index 32c000c..64980ce 100644
--- a/docs/content/_index.md
+++ b/docs/content/_index.md
@@ -6,31 +6,147 @@ draft: false
 
 ![Badger mascot](/images/diggy-shadow.png)
 
+**Welcome to the official Badger documentation.**
+
 BadgerDB is an embeddable, persistent and fast key-value (KV) database written
 in pure Go. It is the underlying database for [Dgraph](https://dgraph.io), a
 fast, distributed graph database. It's meant to be a performant alternative to
 non-Go-based key-value stores like RocksDB.
 
-## Project Status [March 24, 2020]
+## Table of Contents
 
-Badger is stable and is being used to serve data sets worth hundreds of
-terabytes. Badger supports concurrent ACID transactions with serializable
-snapshot isolation (SSI) guarantees. A Jepsen-style bank test runs nightly for
-8h, with `--race` flag and ensures the maintenance of transactional guarantees.
-Badger has also been tested to work with filesystem level anomalies, to ensure
-persistence and consistency. Badger is being used by a number of projects which
-includes Dgraph, Jaeger Tracing, UsenetExpress, and many more.
+<section class="toc">
+  <div class="container">
+    <div class="row row-no-padding">
+      <div class="col-12 col-sm-6">
+        <div class="section-item">
+          <div class="section-name">
+            <a href="{{< relref "get-started/_index.md">}}">
+              Quickstart Guide
+            </a>
+          </div>
+          <p class="section-desc">
+            A single page quickstart guide to get started with BadgerDB
+          </p>
+        </div>
+      </div>
+      <div class="col-12 col-sm-6">
+        <div class="section-item">
+          <div class="section-name">
+            <a href="{{< relref "resources/_index.md">}}">
+              Resources
+            </a>
+          </div>
+          <p class="section-desc">
+            Additional resources and information
+          </p>
+        </div>
+      </div>
+      <div class="col-12 col-sm-6">
+        <div class="section-item">
+          <div class="section-name">
+            <a href="{{< relref "design/_index.md">}}">
+              Design
+            </a>
+          </div>
+          <p class="section-desc">
+            Design goals behind BadgerDB
+          </p>
+        </div>
+      </div>
+      <div class="col-12 col-sm-6">
+        <div class="section-item">
+          <div class="section-name">
+            <a href="{{< relref "projects-using-badger/_index.md">}}">
+              Projects using Badger
+            </a>
+          </div>
+          <p class="section-desc">
+            A list of known projects that use BadgerDB
+          </p>
+        </div>
+      </div>
+      <div class="col-12 col-sm-6">
+        <div class="section-item">
+          <div class="section-name">
+            <a href="/faq">
+              FAQ
+            </a>
+          </div>
+          <p class="section-desc">
+            Frequently asked questions
+          </p>
+        </div>
+      </div>
+      <div class="col-12 col-sm-6">
+        <div class="section-item">
+          <div class="section-name">
+            <a href="https://dgraph.io/badger">
+              Badger
+            </a>
+          </div>
+          <p class="section-desc">
+            Embeddable, persistent and fast key-value database that powers Dgraph
+          </p>
+        </div>
+      </div>
+    </div>
+  </div>
+</section>
 
-The list of projects using Badger can be found [here]({{<relref "projects-using-badger/index.md" >}}).
+## Changelog
 
-Badger v1.0 was released in Nov 2017, and the latest version that is data-compatible
-with v1.0 is v1.6.0.
+The [Changelog] is kept fairly up-to-date.
 
-Badger v2.0 was released in Nov 2019 with a new storage format which won't
+- Badger v1.0 was released in Nov 2017, and the latest version that is data-compatible
+with v1.0 is v1.6.0.
+- Badger v2.0 was released in Nov 2019 with a new storage format which won't
 be compatible with all of the v1.x. Badger v2.0 supports compression, encryption and uses a cache to speed up lookup.
 
-The [Changelog] is kept fairly up-to-date.
-
 For more details on our version naming schema please read [Choosing a version]({{< relref "get-started/index.md#choosing-a-version" >}}).
 
 [Changelog]:https://github.com/dgraph-io/badger/blob/master/CHANGELOG.md
+
+## Contribute
+
+<section class="toc">
+  <div class="container">
+    <div class="row row-no-padding">
+      <div class="col-12 col-sm-6">
+        <div class="section-item">
+          <div class="section-name">
+            <a href="https://github.com/dgraph-io/badger/blob/master/CONTRIBUTING.md">
+              Contribute to Badger
+            </a>
+          </div>
+          <p class="section-desc">
+            Get started with contributing fixes and enhancements to Badger and related software.
+          </p>
+        </div>
+      </div>
+      </div>
+  </div>
+</section>
+
+## Our Community
+
+**Badger is made better every day by the growing community and the contributors all over the world.**
+
+<section class="toc">
+  <div class="container">
+    <div class="row row-no-padding">
+      <div class="col-12 col-sm-6">
+        <div class="section-item">
+          <div class="section-name">
+            <a href="https://discuss.dgraph.io">
+              Community
+            </a>
+          </div>
+          <p class="section-desc">
+            Discuss Badger on the official community.
+          </p>
+        </div>
+      </div>
+    </div>
+  </div>
+</section>
diff --git a/docs/themes/hugo-docs/layouts/_default/article.html b/docs/themes/hugo-docs/layouts/_default/article.html
index ef4c5bc..4a86a71 100644
--- a/docs/themes/hugo-docs/layouts/_default/article.html
+++ b/docs/themes/hugo-docs/layouts/_default/article.html
@@ -1,17 +1,3 @@
-{{ $currentVersion := getenv "CURRENT_VERSION" }}
-{{ $versionString := getenv "VERSIONS" }}
-{{ $versions := split $versionString "," }}
-{{ $latestVersion := index $versions 0 }}
-
-{{ if (eq $currentVersion "master") }}
-  <div class="alert alert-warning">
-    <i class="fa fa-warning"></i> You are looking at the docs for the unreleased <code>master</code> branch of Badger. The latest version is <a href="{{ .Site.BaseURL }}/..">{{ $latestVersion }}</a>.
-  </div>
-{{ else if not (eq $latestVersion $currentVersion) }}
-  <div class="alert alert-warning">
-    <i class="fa fa-warning"></i> You are looking at the docs for an older version of Badger ({{ $currentVersion }}). The latest version is <a href="{{ .Site.BaseURL }}/..">{{ $latestVersion }}</a>.
-  </div>
-{{ end }}
 
 <article id="{{ .Slug }}">
   {{ partial "request-edit.html" . }}
diff --git a/pb/pb.pb.go b/pb/badgerpb2.pb.go
similarity index 81%
rename from pb/pb.pb.go
rename to pb/badgerpb2.pb.go
index 0d6fde3..edacec7 100644
--- a/pb/pb.pb.go
+++ b/pb/badgerpb2.pb.go
@@ -1,5 +1,5 @@
 // Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: pb.proto
+// source: badgerpb2.proto
 
 package pb
 
@@ -41,7 +41,7 @@ func (x EncryptionAlgo) String() string {
 }
 
 func (EncryptionAlgo) EnumDescriptor() ([]byte, []int) {
-	return fileDescriptor_f80abaa17e25ccc8, []int{0}
+	return fileDescriptor_e63e84f9f0d3998c, []int{0}
 }
 
 type ManifestChange_Operation int32
@@ -66,7 +66,7 @@ func (x ManifestChange_Operation) String() string {
 }
 
 func (ManifestChange_Operation) EnumDescriptor() ([]byte, []int) {
-	return fileDescriptor_f80abaa17e25ccc8, []int{3, 0}
+	return fileDescriptor_e63e84f9f0d3998c, []int{3, 0}
 }
 
 type Checksum_Algorithm int32
@@ -91,7 +91,7 @@ func (x Checksum_Algorithm) String() string {
 }
 
 func (Checksum_Algorithm) EnumDescriptor() ([]byte, []int) {
-	return fileDescriptor_f80abaa17e25ccc8, []int{6, 0}
+	return fileDescriptor_e63e84f9f0d3998c, []int{6, 0}
 }
 
 type KV struct {
@@ -114,7 +114,7 @@ func (m *KV) Reset()         { *m = KV{} }
 func (m *KV) String() string { return proto.CompactTextString(m) }
 func (*KV) ProtoMessage()    {}
 func (*KV) Descriptor() ([]byte, []int) {
-	return fileDescriptor_f80abaa17e25ccc8, []int{0}
+	return fileDescriptor_e63e84f9f0d3998c, []int{0}
 }
 func (m *KV) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -210,7 +210,7 @@ func (m *KVList) Reset()         { *m = KVList{} }
 func (m *KVList) String() string { return proto.CompactTextString(m) }
 func (*KVList) ProtoMessage()    {}
 func (*KVList) Descriptor() ([]byte, []int) {
-	return fileDescriptor_f80abaa17e25ccc8, []int{1}
+	return fileDescriptor_e63e84f9f0d3998c, []int{1}
 }
 func (m *KVList) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -258,7 +258,7 @@ func (m *ManifestChangeSet) Reset()         { *m = ManifestChangeSet{} }
 func (m *ManifestChangeSet) String() string { return proto.CompactTextString(m) }
 func (*ManifestChangeSet) ProtoMessage()    {}
 func (*ManifestChangeSet) Descriptor() ([]byte, []int) {
-	return fileDescriptor_f80abaa17e25ccc8, []int{2}
+	return fileDescriptor_e63e84f9f0d3998c, []int{2}
 }
 func (m *ManifestChangeSet) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -310,7 +310,7 @@ func (m *ManifestChange) Reset()         { *m = ManifestChange{} }
 func (m *ManifestChange) String() string { return proto.CompactTextString(m) }
 func (*ManifestChange) ProtoMessage()    {}
 func (*ManifestChange) Descriptor() ([]byte, []int) {
-	return fileDescriptor_f80abaa17e25ccc8, []int{3}
+	return fileDescriptor_e63e84f9f0d3998c, []int{3}
 }
 func (m *ManifestChange) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -394,7 +394,7 @@ func (m *BlockOffset) Reset()         { *m = BlockOffset{} }
 func (m *BlockOffset) String() string { return proto.CompactTextString(m) }
 func (*BlockOffset) ProtoMessage()    {}
 func (*BlockOffset) Descriptor() ([]byte, []int) {
-	return fileDescriptor_f80abaa17e25ccc8, []int{4}
+	return fileDescriptor_e63e84f9f0d3998c, []int{4}
 }
 func (m *BlockOffset) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -457,7 +457,7 @@ func (m *TableIndex) Reset()         { *m = TableIndex{} }
 func (m *TableIndex) String() string { return proto.CompactTextString(m) }
 func (*TableIndex) ProtoMessage()    {}
 func (*TableIndex) Descriptor() ([]byte, []int) {
-	return fileDescriptor_f80abaa17e25ccc8, []int{5}
+	return fileDescriptor_e63e84f9f0d3998c, []int{5}
 }
 func (m *TableIndex) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -519,7 +519,7 @@ func (m *Checksum) Reset()         { *m = Checksum{} }
 func (m *Checksum) String() string { return proto.CompactTextString(m) }
 func (*Checksum) ProtoMessage()    {}
 func (*Checksum) Descriptor() ([]byte, []int) {
-	return fileDescriptor_f80abaa17e25ccc8, []int{6}
+	return fileDescriptor_e63e84f9f0d3998c, []int{6}
 }
 func (m *Checksum) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -576,7 +576,7 @@ func (m *DataKey) Reset()         { *m = DataKey{} }
 func (m *DataKey) String() string { return proto.CompactTextString(m) }
 func (*DataKey) ProtoMessage()    {}
 func (*DataKey) Descriptor() ([]byte, []int) {
-	return fileDescriptor_f80abaa17e25ccc8, []int{7}
+	return fileDescriptor_e63e84f9f0d3998c, []int{7}
 }
 func (m *DataKey) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -647,54 +647,54 @@ func init() {
 	proto.RegisterType((*DataKey)(nil), "badgerpb2.DataKey")
 }
 
-func init() { proto.RegisterFile("pb.proto", fileDescriptor_f80abaa17e25ccc8) }
-
-var fileDescriptor_f80abaa17e25ccc8 = []byte{
-	// 691 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x54, 0xdd, 0x6e, 0xda, 0x4a,
-	0x10, 0xc6, 0xc6, 0xe1, 0x67, 0x08, 0x1c, 0xce, 0xea, 0x9c, 0xc8, 0x51, 0x15, 0x4a, 0x1c, 0x45,
-	0x45, 0x95, 0x0a, 0x2d, 0x54, 0xbd, 0x27, 0x84, 0x2a, 0x88, 0x44, 0x48, 0x9b, 0x28, 0x8a, 0x7a,
-	0x83, 0xd6, 0xf6, 0x00, 0x16, 0xfe, 0x93, 0x77, 0xb1, 0x42, 0x9e, 0xa0, 0x37, 0xbd, 0xef, 0x23,
-	0xf5, 0xb2, 0x17, 0x7d, 0x80, 0x2a, 0x7d, 0x91, 0xca, 0x6b, 0x83, 0x40, 0x6a, 0xef, 0x66, 0xbe,
-	0xf9, 0x76, 0x67, 0xbf, 0x6f, 0xc6, 0x86, 0x52, 0x68, 0xb6, 0xc3, 0x28, 0x10, 0x01, 0x29, 0x9b,
-	0xcc, 0x9e, 0x63, 0x14, 0x9a, 0x5d, 0xe3, 0x87, 0x02, 0xea, 0xf8, 0x9e, 0xd4, 0x21, 0xbf, 0xc4,
-	0xb5, 0xae, 0x34, 0x95, 0xd6, 0x21, 0x4d, 0x42, 0xf2, 0x1f, 0x1c, 0xc4, 0xcc, 0x5d, 0xa1, 0xae,
-	0x4a, 0x2c, 0x4d, 0xc8, 0x0b, 0x28, 0xaf, 0x38, 0x46, 0x53, 0x0f, 0x05, 0xd3, 0xf3, 0xb2, 0x52,
-	0x4a, 0x80, 0x1b, 0x14, 0x8c, 0xe8, 0x50, 0x8c, 0x31, 0xe2, 0x4e, 0xe0, 0xeb, 0x5a, 0x53, 0x69,
-	0x69, 0x74, 0x93, 0x92, 0x13, 0x00, 0x7c, 0x0c, 0x9d, 0x08, 0xf9, 0x94, 0x09, 0xfd, 0x40, 0x16,
-	0xcb, 0x19, 0xd2, 0x17, 0x84, 0x80, 0x26, 0x2f, 0x2c, 0xc8, 0x0b, 0x65, 0x9c, 0x74, 0xe2, 0x22,
-	0x42, 0xe6, 0x4d, 0x1d, 0x5b, 0x87, 0xa6, 0xd2, 0xaa, 0xd2, 0x52, 0x0a, 0x8c, 0x6c, 0xf2, 0x12,
-	0x2a, 0x59, 0xd1, 0x0e, 0x7c, 0xd4, 0x2b, 0x4d, 0xa5, 0x55, 0xa2, 0x90, 0x42, 0x97, 0x81, 0x8f,
-	0xc6, 0x2b, 0x28, 0x8c, 0xef, 0xaf, 0x1d, 0x2e, 0xc8, 0x09, 0xa8, 0xcb, 0x58, 0x57, 0x9a, 0xf9,
-	0x56, 0xa5, 0x5b, 0x6d, 0x6f, 0x85, 0xb7, 0xc7, 0xf7, 0x54, 0x5d, 0xc6, 0xc6, 0x15, 0xfc, 0x7b,
-	0xc3, 0x7c, 0x67, 0x86, 0x5c, 0x0c, 0x16, 0xcc, 0x9f, 0xe3, 0x2d, 0x0a, 0xd2, 0x83, 0xa2, 0x25,
-	0x13, 0x9e, 0x1d, 0x3c, 0xde, 0x39, 0xb8, 0x4f, 0xa7, 0x1b, 0xa6, 0xf1, 0x45, 0x85, 0xda, 0x7e,
-	0x8d, 0xd4, 0x40, 0x1d, 0xd9, 0xd2, 0x54, 0x8d, 0xaa, 0x23, 0x9b, 0xf4, 0x40, 0x9d, 0x84, 0xd2,
-	0xd0, 0x5a, 0xf7, 0xec, 0xaf, 0x57, 0xb6, 0x27, 0x21, 0x46, 0x4c, 0x38, 0x81, 0x4f, 0xd5, 0x49,
-	0x98, 0x0c, 0xe2, 0x1a, 0x63, 0x74, 0xa5, 0xdd, 0x55, 0x9a, 0x26, 0xe4, 0x7f, 0x28, 0x2c, 0x71,
-	0x9d, 0x78, 0x93, 0x5a, 0x7d, 0xb0, 0xc4, 0xf5, 0xc8, 0x26, 0x17, 0xf0, 0x0f, 0xfa, 0x56, 0xb4,
-	0x0e, 0x93, 0xe3, 0x53, 0xe6, 0xce, 0x03, 0xe9, 0x76, 0x6d, 0x4f, 0xc1, 0x70, 0xcb, 0xe8, 0xbb,
-	0xf3, 0x80, 0xd6, 0x70, 0x2f, 0x27, 0x4d, 0xa8, 0x58, 0x81, 0x17, 0x46, 0xc8, 0xe5, 0x28, 0x0b,
-	0xb2, 0xed, 0x2e, 0x64, 0x9c, 0x41, 0x79, 0xfb, 0x46, 0x02, 0x50, 0x18, 0xd0, 0x61, 0xff, 0x6e,
-	0x58, 0xcf, 0x25, 0xf1, 0xe5, 0xf0, 0x7a, 0x78, 0x37, 0xac, 0x2b, 0xc6, 0x08, 0x2a, 0x17, 0x6e,
-	0x60, 0x2d, 0x27, 0xb3, 0x19, 0x47, 0xf1, 0x87, 0x0d, 0x3b, 0x82, 0x42, 0x20, 0x6b, 0xd2, 0x91,
-	0x2a, 0xcd, 0xb2, 0x84, 0xe9, 0xa2, 0x9f, 0xc9, 0x4d, 0x42, 0xe3, 0xb3, 0x02, 0x70, 0xc7, 0x4c,
-	0x17, 0x47, 0xbe, 0x8d, 0x8f, 0xe4, 0x2d, 0x14, 0x53, 0xea, 0x66, 0x3c, 0x47, 0x3b, 0xe2, 0x76,
-	0x7a, 0xd2, 0x0d, 0x8d, 0x9c, 0xc2, 0xa1, 0xe9, 0x06, 0x81, 0x37, 0x9d, 0x39, 0xae, 0xc0, 0x28,
-	0xdb, 0xe9, 0x8a, 0xc4, 0x3e, 0x4a, 0x88, 0x9c, 0x43, 0x0d, 0xb9, 0x70, 0x3c, 0x26, 0xd0, 0x9e,
-	0x72, 0xe7, 0x09, 0xe5, 0x03, 0x34, 0x5a, 0xdd, 0xa2, 0xb7, 0xce, 0x13, 0x1a, 0x31, 0x94, 0x06,
-	0x0b, 0xb4, 0x96, 0x7c, 0xe5, 0x91, 0x77, 0xa0, 0x49, 0x87, 0x15, 0xe9, 0xf0, 0xc9, 0xce, 0x23,
-	0x36, 0x94, 0x76, 0x62, 0x68, 0xe4, 0x88, 0x85, 0x47, 0x25, 0x35, 0xd1, 0xc6, 0x57, 0x9e, 0xec,
-	0xaf, 0xd1, 0x24, 0x34, 0xce, 0xa1, 0xbc, 0x25, 0xa5, 0x5e, 0x0e, 0x7a, 0xdd, 0x41, 0x3d, 0x47,
-	0x0e, 0xa1, 0xf4, 0xf0, 0x70, 0xc5, 0xf8, 0xe2, 0xc3, 0xfb, 0xba, 0x62, 0x58, 0x50, 0xbc, 0x64,
-	0x82, 0x8d, 0x71, 0xbd, 0x33, 0x7a, 0x65, 0x77, 0xf4, 0x04, 0x34, 0x9b, 0x09, 0x96, 0x69, 0x93,
-	0x71, 0xb2, 0x80, 0x4e, 0x9c, 0x7d, 0xa7, 0xaa, 0x13, 0x27, 0xdf, 0xa1, 0x15, 0xa1, 0x94, 0xc8,
-	0x84, 0xdc, 0x9c, 0x3c, 0x2d, 0x67, 0x48, 0x5f, 0xbc, 0x3e, 0x86, 0xda, 0xfe, 0x6e, 0x90, 0x22,
-	0xe4, 0x19, 0xf2, 0x7a, 0xee, 0xa2, 0xf7, 0xed, 0xb9, 0xa1, 0x7c, 0x7f, 0x6e, 0x28, 0x3f, 0x9f,
-	0x1b, 0xca, 0xd7, 0x5f, 0x8d, 0xdc, 0xa7, 0xd3, 0xb9, 0x23, 0x16, 0x2b, 0xb3, 0x6d, 0x05, 0x5e,
-	0xc7, 0x9e, 0x47, 0x2c, 0x5c, 0xbc, 0x71, 0x82, 0x4e, 0xea, 0x41, 0x27, 0xee, 0x76, 0x42, 0xd3,
-	0x2c, 0xc8, 0xdf, 0x4d, 0xef, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3a, 0xcd, 0x7e, 0xad, 0x7a,
-	0x04, 0x00, 0x00,
+func init() { proto.RegisterFile("badgerpb2.proto", fileDescriptor_e63e84f9f0d3998c) }
+
+var fileDescriptor_e63e84f9f0d3998c = []byte{
+	// 689 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x54, 0xcd, 0x6e, 0xda, 0x40,
+	0x10, 0xc6, 0xc6, 0xe1, 0x67, 0x08, 0x84, 0xae, 0xda, 0xc8, 0x51, 0x15, 0x4a, 0x1c, 0x45, 0x45,
+	0x95, 0x0a, 0x2d, 0x54, 0xbd, 0x13, 0x42, 0x15, 0x44, 0x22, 0xa4, 0x4d, 0x14, 0x45, 0xbd, 0xa0,
+	0xc5, 0x1e, 0xc0, 0xc2, 0x7f, 0xf2, 0x2e, 0x56, 0xc8, 0x13, 0xf4, 0xd2, 0x7b, 0x1f, 0xa9, 0xc7,
+	0x1e, 0xfa, 0x00, 0x55, 0xfa, 0x22, 0x95, 0xd7, 0x86, 0x82, 0xd4, 0xde, 0x66, 0xbe, 0xf9, 0x76,
+	0x67, 0xbf, 0x6f, 0xc6, 0x86, 0x83, 0x09, 0xb3, 0x66, 0x18, 0x06, 0x93, 0x76, 0x33, 0x08, 0x7d,
+	0xe1, 0x93, 0xe2, 0x06, 0x30, 0x7e, 0x2a, 0xa0, 0x0e, 0xef, 0x48, 0x15, 0xb2, 0x0b, 0x5c, 0xe9,
+	0x4a, 0x5d, 0x69, 0xec, 0xd3, 0x38, 0x24, 0xcf, 0x61, 0x2f, 0x62, 0xce, 0x12, 0x75, 0x55, 0x62,
+	0x49, 0x42, 0x5e, 0x42, 0x71, 0xc9, 0x31, 0x1c, 0xbb, 0x28, 0x98, 0x9e, 0x95, 0x95, 0x42, 0x0c,
+	0x5c, 0xa3, 0x60, 0x44, 0x87, 0x7c, 0x84, 0x21, 0xb7, 0x7d, 0x4f, 0xd7, 0xea, 0x4a, 0x43, 0xa3,
+	0xeb, 0x94, 0x1c, 0x03, 0xe0, 0x43, 0x60, 0x87, 0xc8, 0xc7, 0x4c, 0xe8, 0x7b, 0xb2, 0x58, 0x4c,
+	0x91, 0xae, 0x20, 0x04, 0x34, 0x79, 0x61, 0x4e, 0x5e, 0x28, 0xe3, 0xb8, 0x13, 0x17, 0x21, 0x32,
+	0x77, 0x6c, 0x5b, 0x3a, 0xd4, 0x95, 0x46, 0x99, 0x16, 0x12, 0x60, 0x60, 0x91, 0x57, 0x50, 0x4a,
+	0x8b, 0x96, 0xef, 0xa1, 0x5e, 0xaa, 0x2b, 0x8d, 0x02, 0x85, 0x04, 0xba, 0xf0, 0x3d, 0x34, 0x5e,
+	0x43, 0x6e, 0x78, 0x77, 0x65, 0x73, 0x41, 0x8e, 0x41, 0x5d, 0x44, 0xba, 0x52, 0xcf, 0x36, 0x4a,
+	0xed, 0x72, 0xf3, 0xaf, 0x13, 0xc3, 0x3b, 0xaa, 0x2e, 0x22, 0xe3, 0x12, 0x9e, 0x5d, 0x33, 0xcf,
+	0x9e, 0x22, 0x17, 0xbd, 0x39, 0xf3, 0x66, 0x78, 0x83, 0x82, 0x74, 0x20, 0x6f, 0xca, 0x84, 0xa7,
+	0x07, 0x8f, 0xb6, 0x0e, 0xee, 0xd2, 0xe9, 0x9a, 0x69, 0x7c, 0x55, 0xa1, 0xb2, 0x5b, 0x23, 0x15,
+	0x50, 0x07, 0x96, 0x34, 0x55, 0xa3, 0xea, 0xc0, 0x22, 0x1d, 0x50, 0x47, 0x81, 0x34, 0xb4, 0xd2,
+	0x3e, 0xfd, 0xef, 0x95, 0xcd, 0x51, 0x80, 0x21, 0x13, 0xb6, 0xef, 0x51, 0x75, 0x14, 0xc4, 0x83,
+	0xb8, 0xc2, 0x08, 0x1d, 0x69, 0x77, 0x99, 0x26, 0x09, 0x79, 0x01, 0xb9, 0x05, 0xae, 0x62, 0x6f,
+	0x12, 0xab, 0xf7, 0x16, 0xb8, 0x1a, 0x58, 0xe4, 0x1c, 0x0e, 0xd0, 0x33, 0xc3, 0x55, 0x10, 0x1f,
+	0x1f, 0x33, 0x67, 0xe6, 0x4b, 0xb7, 0x2b, 0x3b, 0x0a, 0xfa, 0x1b, 0x46, 0xd7, 0x99, 0xf9, 0xb4,
+	0x82, 0x3b, 0x39, 0xa9, 0x43, 0xc9, 0xf4, 0xdd, 0x20, 0x44, 0x2e, 0x47, 0x99, 0x93, 0x6d, 0xb7,
+	0x21, 0xe3, 0x14, 0x8a, 0x9b, 0x37, 0x12, 0x80, 0x5c, 0x8f, 0xf6, 0xbb, 0xb7, 0xfd, 0x6a, 0x26,
+	0x8e, 0x2f, 0xfa, 0x57, 0xfd, 0xdb, 0x7e, 0x55, 0x31, 0x06, 0x50, 0x3a, 0x77, 0x7c, 0x73, 0x31,
+	0x9a, 0x4e, 0x39, 0x8a, 0x7f, 0x6c, 0xd8, 0x21, 0xe4, 0x7c, 0x59, 0x93, 0x8e, 0x94, 0x69, 0x9a,
+	0xc5, 0x4c, 0x07, 0xbd, 0x54, 0x6e, 0x1c, 0x1a, 0x5f, 0x14, 0x80, 0x5b, 0x36, 0x71, 0x70, 0xe0,
+	0x59, 0xf8, 0x40, 0xde, 0x41, 0x3e, 0xa1, 0xae, 0xc7, 0x73, 0xb8, 0x25, 0x6e, 0xab, 0x27, 0x5d,
+	0xd3, 0xc8, 0x09, 0xec, 0x4f, 0x1c, 0xdf, 0x77, 0xc7, 0x53, 0xdb, 0x11, 0x18, 0xa6, 0x3b, 0x5d,
+	0x92, 0xd8, 0x27, 0x09, 0x91, 0x33, 0xa8, 0x20, 0x17, 0xb6, 0xcb, 0x04, 0x5a, 0x63, 0x6e, 0x3f,
+	0xa2, 0x7c, 0x80, 0x46, 0xcb, 0x1b, 0xf4, 0xc6, 0x7e, 0x44, 0x23, 0x82, 0x42, 0x6f, 0x8e, 0xe6,
+	0x82, 0x2f, 0x5d, 0xf2, 0x1e, 0x34, 0xe9, 0xb0, 0x22, 0x1d, 0x3e, 0xde, 0x7a, 0xc4, 0x9a, 0xd2,
+	0x8c, 0x0d, 0x0d, 0x6d, 0x31, 0x77, 0xa9, 0xa4, 0xc6, 0xda, 0xf8, 0xd2, 0x95, 0xfd, 0x35, 0x1a,
+	0x87, 0xc6, 0x19, 0x14, 0x37, 0xa4, 0xc4, 0xcb, 0x5e, 0xa7, 0xdd, 0xab, 0x66, 0xc8, 0x3e, 0x14,
+	0xee, 0xef, 0x2f, 0x19, 0x9f, 0x7f, 0xfc, 0x50, 0x55, 0x0c, 0x13, 0xf2, 0x17, 0x4c, 0xb0, 0x21,
+	0xae, 0xb6, 0x46, 0xaf, 0x6c, 0x8f, 0x9e, 0x80, 0x66, 0x31, 0xc1, 0x52, 0x6d, 0x32, 0x8e, 0x17,
+	0xd0, 0x8e, 0xd2, 0xef, 0x54, 0xb5, 0xa3, 0xf8, 0x3b, 0x34, 0x43, 0x94, 0x12, 0x99, 0x90, 0x9b,
+	0x93, 0xa5, 0xc5, 0x14, 0xe9, 0x8a, 0x37, 0x47, 0x50, 0xd9, 0xdd, 0x0d, 0x92, 0x87, 0x2c, 0x43,
+	0x5e, 0xcd, 0x9c, 0x77, 0xbe, 0x3f, 0xd5, 0x94, 0x1f, 0x4f, 0x35, 0xe5, 0xd7, 0x53, 0x4d, 0xf9,
+	0xf6, 0xbb, 0x96, 0xf9, 0x7c, 0x32, 0xb3, 0xc5, 0x7c, 0x39, 0x69, 0x9a, 0xbe, 0xdb, 0xb2, 0x66,
+	0x21, 0x0b, 0xe6, 0x6f, 0x6d, 0xbf, 0x95, 0x78, 0xd0, 0x8a, 0xda, 0xad, 0x60, 0x32, 0xc9, 0xc9,
+	0xdf, 0x4d, 0xe7, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x88, 0x22, 0x82, 0x98, 0x81, 0x04, 0x00,
+	0x00,
 }
 
 func (m *KV) Marshal() (dAtA []byte, err error) {
@@ -732,45 +732,45 @@ func (m *KV) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		dAtA[i] = 0x58
 	}
 	if m.StreamId != 0 {
-		i = encodeVarintPb(dAtA, i, uint64(m.StreamId))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(m.StreamId))
 		i--
 		dAtA[i] = 0x50
 	}
 	if len(m.Meta) > 0 {
 		i -= len(m.Meta)
 		copy(dAtA[i:], m.Meta)
-		i = encodeVarintPb(dAtA, i, uint64(len(m.Meta)))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(len(m.Meta)))
 		i--
 		dAtA[i] = 0x32
 	}
 	if m.ExpiresAt != 0 {
-		i = encodeVarintPb(dAtA, i, uint64(m.ExpiresAt))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(m.ExpiresAt))
 		i--
 		dAtA[i] = 0x28
 	}
 	if m.Version != 0 {
-		i = encodeVarintPb(dAtA, i, uint64(m.Version))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(m.Version))
 		i--
 		dAtA[i] = 0x20
 	}
 	if len(m.UserMeta) > 0 {
 		i -= len(m.UserMeta)
 		copy(dAtA[i:], m.UserMeta)
-		i = encodeVarintPb(dAtA, i, uint64(len(m.UserMeta)))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(len(m.UserMeta)))
 		i--
 		dAtA[i] = 0x1a
 	}
 	if len(m.Value) > 0 {
 		i -= len(m.Value)
 		copy(dAtA[i:], m.Value)
-		i = encodeVarintPb(dAtA, i, uint64(len(m.Value)))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(len(m.Value)))
 		i--
 		dAtA[i] = 0x12
 	}
 	if len(m.Key) > 0 {
 		i -= len(m.Key)
 		copy(dAtA[i:], m.Key)
-		i = encodeVarintPb(dAtA, i, uint64(len(m.Key)))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(len(m.Key)))
 		i--
 		dAtA[i] = 0xa
 	}
@@ -809,7 +809,7 @@ func (m *KVList) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 					return 0, err
 				}
 				i -= size
-				i = encodeVarintPb(dAtA, i, uint64(size))
+				i = encodeVarintBadgerpb2(dAtA, i, uint64(size))
 			}
 			i--
 			dAtA[i] = 0xa
@@ -850,7 +850,7 @@ func (m *ManifestChangeSet) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 					return 0, err
 				}
 				i -= size
-				i = encodeVarintPb(dAtA, i, uint64(size))
+				i = encodeVarintBadgerpb2(dAtA, i, uint64(size))
 			}
 			i--
 			dAtA[i] = 0xa
@@ -884,32 +884,32 @@ func (m *ManifestChange) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		copy(dAtA[i:], m.XXX_unrecognized)
 	}
 	if m.Compression != 0 {
-		i = encodeVarintPb(dAtA, i, uint64(m.Compression))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(m.Compression))
 		i--
 		dAtA[i] = 0x30
 	}
 	if m.EncryptionAlgo != 0 {
-		i = encodeVarintPb(dAtA, i, uint64(m.EncryptionAlgo))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(m.EncryptionAlgo))
 		i--
 		dAtA[i] = 0x28
 	}
 	if m.KeyId != 0 {
-		i = encodeVarintPb(dAtA, i, uint64(m.KeyId))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(m.KeyId))
 		i--
 		dAtA[i] = 0x20
 	}
 	if m.Level != 0 {
-		i = encodeVarintPb(dAtA, i, uint64(m.Level))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(m.Level))
 		i--
 		dAtA[i] = 0x18
 	}
 	if m.Op != 0 {
-		i = encodeVarintPb(dAtA, i, uint64(m.Op))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(m.Op))
 		i--
 		dAtA[i] = 0x10
 	}
 	if m.Id != 0 {
-		i = encodeVarintPb(dAtA, i, uint64(m.Id))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(m.Id))
 		i--
 		dAtA[i] = 0x8
 	}
@@ -941,19 +941,19 @@ func (m *BlockOffset) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		copy(dAtA[i:], m.XXX_unrecognized)
 	}
 	if m.Len != 0 {
-		i = encodeVarintPb(dAtA, i, uint64(m.Len))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(m.Len))
 		i--
 		dAtA[i] = 0x18
 	}
 	if m.Offset != 0 {
-		i = encodeVarintPb(dAtA, i, uint64(m.Offset))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(m.Offset))
 		i--
 		dAtA[i] = 0x10
 	}
 	if len(m.Key) > 0 {
 		i -= len(m.Key)
 		copy(dAtA[i:], m.Key)
-		i = encodeVarintPb(dAtA, i, uint64(len(m.Key)))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(len(m.Key)))
 		i--
 		dAtA[i] = 0xa
 	}
@@ -985,14 +985,14 @@ func (m *TableIndex) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		copy(dAtA[i:], m.XXX_unrecognized)
 	}
 	if m.EstimatedSize != 0 {
-		i = encodeVarintPb(dAtA, i, uint64(m.EstimatedSize))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(m.EstimatedSize))
 		i--
 		dAtA[i] = 0x18
 	}
 	if len(m.BloomFilter) > 0 {
 		i -= len(m.BloomFilter)
 		copy(dAtA[i:], m.BloomFilter)
-		i = encodeVarintPb(dAtA, i, uint64(len(m.BloomFilter)))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(len(m.BloomFilter)))
 		i--
 		dAtA[i] = 0x12
 	}
@@ -1004,7 +1004,7 @@ func (m *TableIndex) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 					return 0, err
 				}
 				i -= size
-				i = encodeVarintPb(dAtA, i, uint64(size))
+				i = encodeVarintBadgerpb2(dAtA, i, uint64(size))
 			}
 			i--
 			dAtA[i] = 0xa
@@ -1038,12 +1038,12 @@ func (m *Checksum) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		copy(dAtA[i:], m.XXX_unrecognized)
 	}
 	if m.Sum != 0 {
-		i = encodeVarintPb(dAtA, i, uint64(m.Sum))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(m.Sum))
 		i--
 		dAtA[i] = 0x10
 	}
 	if m.Algo != 0 {
-		i = encodeVarintPb(dAtA, i, uint64(m.Algo))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(m.Algo))
 		i--
 		dAtA[i] = 0x8
 	}
@@ -1075,34 +1075,34 @@ func (m *DataKey) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 		copy(dAtA[i:], m.XXX_unrecognized)
 	}
 	if m.CreatedAt != 0 {
-		i = encodeVarintPb(dAtA, i, uint64(m.CreatedAt))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(m.CreatedAt))
 		i--
 		dAtA[i] = 0x20
 	}
 	if len(m.Iv) > 0 {
 		i -= len(m.Iv)
 		copy(dAtA[i:], m.Iv)
-		i = encodeVarintPb(dAtA, i, uint64(len(m.Iv)))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(len(m.Iv)))
 		i--
 		dAtA[i] = 0x1a
 	}
 	if len(m.Data) > 0 {
 		i -= len(m.Data)
 		copy(dAtA[i:], m.Data)
-		i = encodeVarintPb(dAtA, i, uint64(len(m.Data)))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(len(m.Data)))
 		i--
 		dAtA[i] = 0x12
 	}
 	if m.KeyId != 0 {
-		i = encodeVarintPb(dAtA, i, uint64(m.KeyId))
+		i = encodeVarintBadgerpb2(dAtA, i, uint64(m.KeyId))
 		i--
 		dAtA[i] = 0x8
 	}
 	return len(dAtA) - i, nil
 }
 
-func encodeVarintPb(dAtA []byte, offset int, v uint64) int {
-	offset -= sovPb(v)
+func encodeVarintBadgerpb2(dAtA []byte, offset int, v uint64) int {
+	offset -= sovBadgerpb2(v)
 	base := offset
 	for v >= 1<<7 {
 		dAtA[offset] = uint8(v&0x7f | 0x80)
@@ -1120,28 +1120,28 @@ func (m *KV) Size() (n int) {
 	_ = l
 	l = len(m.Key)
 	if l > 0 {
-		n += 1 + l + sovPb(uint64(l))
+		n += 1 + l + sovBadgerpb2(uint64(l))
 	}
 	l = len(m.Value)
 	if l > 0 {
-		n += 1 + l + sovPb(uint64(l))
+		n += 1 + l + sovBadgerpb2(uint64(l))
 	}
 	l = len(m.UserMeta)
 	if l > 0 {
-		n += 1 + l + sovPb(uint64(l))
+		n += 1 + l + sovBadgerpb2(uint64(l))
 	}
 	if m.Version != 0 {
-		n += 1 + sovPb(uint64(m.Version))
+		n += 1 + sovBadgerpb2(uint64(m.Version))
 	}
 	if m.ExpiresAt != 0 {
-		n += 1 + sovPb(uint64(m.ExpiresAt))
+		n += 1 + sovBadgerpb2(uint64(m.ExpiresAt))
 	}
 	l = len(m.Meta)
 	if l > 0 {
-		n += 1 + l + sovPb(uint64(l))
+		n += 1 + l + sovBadgerpb2(uint64(l))
 	}
 	if m.StreamId != 0 {
-		n += 1 + sovPb(uint64(m.StreamId))
+		n += 1 + sovBadgerpb2(uint64(m.StreamId))
 	}
 	if m.StreamDone {
 		n += 2
@@ -1161,7 +1161,7 @@ func (m *KVList) Size() (n int) {
 	if len(m.Kv) > 0 {
 		for _, e := range m.Kv {
 			l = e.Size()
-			n += 1 + l + sovPb(uint64(l))
+			n += 1 + l + sovBadgerpb2(uint64(l))
 		}
 	}
 	if m.XXX_unrecognized != nil {
@@ -1179,7 +1179,7 @@ func (m *ManifestChangeSet) Size() (n int) {
 	if len(m.Changes) > 0 {
 		for _, e := range m.Changes {
 			l = e.Size()
-			n += 1 + l + sovPb(uint64(l))
+			n += 1 + l + sovBadgerpb2(uint64(l))
 		}
 	}
 	if m.XXX_unrecognized != nil {
@@ -1195,22 +1195,22 @@ func (m *ManifestChange) Size() (n int) {
 	var l int
 	_ = l
 	if m.Id != 0 {
-		n += 1 + sovPb(uint64(m.Id))
+		n += 1 + sovBadgerpb2(uint64(m.Id))
 	}
 	if m.Op != 0 {
-		n += 1 + sovPb(uint64(m.Op))
+		n += 1 + sovBadgerpb2(uint64(m.Op))
 	}
 	if m.Level != 0 {
-		n += 1 + sovPb(uint64(m.Level))
+		n += 1 + sovBadgerpb2(uint64(m.Level))
 	}
 	if m.KeyId != 0 {
-		n += 1 + sovPb(uint64(m.KeyId))
+		n += 1 + sovBadgerpb2(uint64(m.KeyId))
 	}
 	if m.EncryptionAlgo != 0 {
-		n += 1 + sovPb(uint64(m.EncryptionAlgo))
+		n += 1 + sovBadgerpb2(uint64(m.EncryptionAlgo))
 	}
 	if m.Compression != 0 {
-		n += 1 + sovPb(uint64(m.Compression))
+		n += 1 + sovBadgerpb2(uint64(m.Compression))
 	}
 	if m.XXX_unrecognized != nil {
 		n += len(m.XXX_unrecognized)
@@ -1226,13 +1226,13 @@ func (m *BlockOffset) Size() (n int) {
 	_ = l
 	l = len(m.Key)
 	if l > 0 {
-		n += 1 + l + sovPb(uint64(l))
+		n += 1 + l + sovBadgerpb2(uint64(l))
 	}
 	if m.Offset != 0 {
-		n += 1 + sovPb(uint64(m.Offset))
+		n += 1 + sovBadgerpb2(uint64(m.Offset))
 	}
 	if m.Len != 0 {
-		n += 1 + sovPb(uint64(m.Len))
+		n += 1 + sovBadgerpb2(uint64(m.Len))
 	}
 	if m.XXX_unrecognized != nil {
 		n += len(m.XXX_unrecognized)
@@ -1249,15 +1249,15 @@ func (m *TableIndex) Size() (n int) {
 	if len(m.Offsets) > 0 {
 		for _, e := range m.Offsets {
 			l = e.Size()
-			n += 1 + l + sovPb(uint64(l))
+			n += 1 + l + sovBadgerpb2(uint64(l))
 		}
 	}
 	l = len(m.BloomFilter)
 	if l > 0 {
-		n += 1 + l + sovPb(uint64(l))
+		n += 1 + l + sovBadgerpb2(uint64(l))
 	}
 	if m.EstimatedSize != 0 {
-		n += 1 + sovPb(uint64(m.EstimatedSize))
+		n += 1 + sovBadgerpb2(uint64(m.EstimatedSize))
 	}
 	if m.XXX_unrecognized != nil {
 		n += len(m.XXX_unrecognized)
@@ -1272,10 +1272,10 @@ func (m *Checksum) Size() (n int) {
 	var l int
 	_ = l
 	if m.Algo != 0 {
-		n += 1 + sovPb(uint64(m.Algo))
+		n += 1 + sovBadgerpb2(uint64(m.Algo))
 	}
 	if m.Sum != 0 {
-		n += 1 + sovPb(uint64(m.Sum))
+		n += 1 + sovBadgerpb2(uint64(m.Sum))
 	}
 	if m.XXX_unrecognized != nil {
 		n += len(m.XXX_unrecognized)
@@ -1290,18 +1290,18 @@ func (m *DataKey) Size() (n int) {
 	var l int
 	_ = l
 	if m.KeyId != 0 {
-		n += 1 + sovPb(uint64(m.KeyId))
+		n += 1 + sovBadgerpb2(uint64(m.KeyId))
 	}
 	l = len(m.Data)
 	if l > 0 {
-		n += 1 + l + sovPb(uint64(l))
+		n += 1 + l + sovBadgerpb2(uint64(l))
 	}
 	l = len(m.Iv)
 	if l > 0 {
-		n += 1 + l + sovPb(uint64(l))
+		n += 1 + l + sovBadgerpb2(uint64(l))
 	}
 	if m.CreatedAt != 0 {
-		n += 1 + sovPb(uint64(m.CreatedAt))
+		n += 1 + sovBadgerpb2(uint64(m.CreatedAt))
 	}
 	if m.XXX_unrecognized != nil {
 		n += len(m.XXX_unrecognized)
@@ -1309,11 +1309,11 @@ func (m *DataKey) Size() (n int) {
 	return n
 }
 
-func sovPb(x uint64) (n int) {
+func sovBadgerpb2(x uint64) (n int) {
 	return (math_bits.Len64(x|1) + 6) / 7
 }
-func sozPb(x uint64) (n int) {
-	return sovPb(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+func sozBadgerpb2(x uint64) (n int) {
+	return sovBadgerpb2(uint64((x << 1) ^ uint64((int64(x) >> 63))))
 }
 func (m *KV) Unmarshal(dAtA []byte) error {
 	l := len(dAtA)
@@ -1323,7 +1323,7 @@ func (m *KV) Unmarshal(dAtA []byte) error {
 		var wire uint64
 		for shift := uint(0); ; shift += 7 {
 			if shift >= 64 {
-				return ErrIntOverflowPb
+				return ErrIntOverflowBadgerpb2
 			}
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
@@ -1351,7 +1351,7 @@ func (m *KV) Unmarshal(dAtA []byte) error {
 			var byteLen int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1364,11 +1364,11 @@ func (m *KV) Unmarshal(dAtA []byte) error {
 				}
 			}
 			if byteLen < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			postIndex := iNdEx + byteLen
 			if postIndex < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
@@ -1385,7 +1385,7 @@ func (m *KV) Unmarshal(dAtA []byte) error {
 			var byteLen int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1398,11 +1398,11 @@ func (m *KV) Unmarshal(dAtA []byte) error {
 				}
 			}
 			if byteLen < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			postIndex := iNdEx + byteLen
 			if postIndex < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
@@ -1419,7 +1419,7 @@ func (m *KV) Unmarshal(dAtA []byte) error {
 			var byteLen int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1432,11 +1432,11 @@ func (m *KV) Unmarshal(dAtA []byte) error {
 				}
 			}
 			if byteLen < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			postIndex := iNdEx + byteLen
 			if postIndex < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
@@ -1453,7 +1453,7 @@ func (m *KV) Unmarshal(dAtA []byte) error {
 			m.Version = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1472,7 +1472,7 @@ func (m *KV) Unmarshal(dAtA []byte) error {
 			m.ExpiresAt = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1491,7 +1491,7 @@ func (m *KV) Unmarshal(dAtA []byte) error {
 			var byteLen int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1504,11 +1504,11 @@ func (m *KV) Unmarshal(dAtA []byte) error {
 				}
 			}
 			if byteLen < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			postIndex := iNdEx + byteLen
 			if postIndex < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
@@ -1525,7 +1525,7 @@ func (m *KV) Unmarshal(dAtA []byte) error {
 			m.StreamId = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1544,7 +1544,7 @@ func (m *KV) Unmarshal(dAtA []byte) error {
 			var v int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1559,15 +1559,15 @@ func (m *KV) Unmarshal(dAtA []byte) error {
 			m.StreamDone = bool(v != 0)
 		default:
 			iNdEx = preIndex
-			skippy, err := skipPb(dAtA[iNdEx:])
+			skippy, err := skipBadgerpb2(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
 			if skippy < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if (iNdEx + skippy) < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if (iNdEx + skippy) > l {
 				return io.ErrUnexpectedEOF
@@ -1590,7 +1590,7 @@ func (m *KVList) Unmarshal(dAtA []byte) error {
 		var wire uint64
 		for shift := uint(0); ; shift += 7 {
 			if shift >= 64 {
-				return ErrIntOverflowPb
+				return ErrIntOverflowBadgerpb2
 			}
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
@@ -1618,7 +1618,7 @@ func (m *KVList) Unmarshal(dAtA []byte) error {
 			var msglen int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1631,11 +1631,11 @@ func (m *KVList) Unmarshal(dAtA []byte) error {
 				}
 			}
 			if msglen < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			postIndex := iNdEx + msglen
 			if postIndex < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
@@ -1647,15 +1647,15 @@ func (m *KVList) Unmarshal(dAtA []byte) error {
 			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
-			skippy, err := skipPb(dAtA[iNdEx:])
+			skippy, err := skipBadgerpb2(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
 			if skippy < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if (iNdEx + skippy) < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if (iNdEx + skippy) > l {
 				return io.ErrUnexpectedEOF
@@ -1678,7 +1678,7 @@ func (m *ManifestChangeSet) Unmarshal(dAtA []byte) error {
 		var wire uint64
 		for shift := uint(0); ; shift += 7 {
 			if shift >= 64 {
-				return ErrIntOverflowPb
+				return ErrIntOverflowBadgerpb2
 			}
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
@@ -1706,7 +1706,7 @@ func (m *ManifestChangeSet) Unmarshal(dAtA []byte) error {
 			var msglen int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1719,11 +1719,11 @@ func (m *ManifestChangeSet) Unmarshal(dAtA []byte) error {
 				}
 			}
 			if msglen < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			postIndex := iNdEx + msglen
 			if postIndex < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
@@ -1735,15 +1735,15 @@ func (m *ManifestChangeSet) Unmarshal(dAtA []byte) error {
 			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
-			skippy, err := skipPb(dAtA[iNdEx:])
+			skippy, err := skipBadgerpb2(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
 			if skippy < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if (iNdEx + skippy) < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if (iNdEx + skippy) > l {
 				return io.ErrUnexpectedEOF
@@ -1766,7 +1766,7 @@ func (m *ManifestChange) Unmarshal(dAtA []byte) error {
 		var wire uint64
 		for shift := uint(0); ; shift += 7 {
 			if shift >= 64 {
-				return ErrIntOverflowPb
+				return ErrIntOverflowBadgerpb2
 			}
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
@@ -1794,7 +1794,7 @@ func (m *ManifestChange) Unmarshal(dAtA []byte) error {
 			m.Id = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1813,7 +1813,7 @@ func (m *ManifestChange) Unmarshal(dAtA []byte) error {
 			m.Op = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1832,7 +1832,7 @@ func (m *ManifestChange) Unmarshal(dAtA []byte) error {
 			m.Level = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1851,7 +1851,7 @@ func (m *ManifestChange) Unmarshal(dAtA []byte) error {
 			m.KeyId = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1870,7 +1870,7 @@ func (m *ManifestChange) Unmarshal(dAtA []byte) error {
 			m.EncryptionAlgo = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1889,7 +1889,7 @@ func (m *ManifestChange) Unmarshal(dAtA []byte) error {
 			m.Compression = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1903,15 +1903,15 @@ func (m *ManifestChange) Unmarshal(dAtA []byte) error {
 			}
 		default:
 			iNdEx = preIndex
-			skippy, err := skipPb(dAtA[iNdEx:])
+			skippy, err := skipBadgerpb2(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
 			if skippy < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if (iNdEx + skippy) < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if (iNdEx + skippy) > l {
 				return io.ErrUnexpectedEOF
@@ -1934,7 +1934,7 @@ func (m *BlockOffset) Unmarshal(dAtA []byte) error {
 		var wire uint64
 		for shift := uint(0); ; shift += 7 {
 			if shift >= 64 {
-				return ErrIntOverflowPb
+				return ErrIntOverflowBadgerpb2
 			}
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
@@ -1962,7 +1962,7 @@ func (m *BlockOffset) Unmarshal(dAtA []byte) error {
 			var byteLen int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -1975,11 +1975,11 @@ func (m *BlockOffset) Unmarshal(dAtA []byte) error {
 				}
 			}
 			if byteLen < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			postIndex := iNdEx + byteLen
 			if postIndex < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
@@ -1996,7 +1996,7 @@ func (m *BlockOffset) Unmarshal(dAtA []byte) error {
 			m.Offset = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -2015,7 +2015,7 @@ func (m *BlockOffset) Unmarshal(dAtA []byte) error {
 			m.Len = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -2029,15 +2029,15 @@ func (m *BlockOffset) Unmarshal(dAtA []byte) error {
 			}
 		default:
 			iNdEx = preIndex
-			skippy, err := skipPb(dAtA[iNdEx:])
+			skippy, err := skipBadgerpb2(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
 			if skippy < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if (iNdEx + skippy) < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if (iNdEx + skippy) > l {
 				return io.ErrUnexpectedEOF
@@ -2060,7 +2060,7 @@ func (m *TableIndex) Unmarshal(dAtA []byte) error {
 		var wire uint64
 		for shift := uint(0); ; shift += 7 {
 			if shift >= 64 {
-				return ErrIntOverflowPb
+				return ErrIntOverflowBadgerpb2
 			}
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
@@ -2088,7 +2088,7 @@ func (m *TableIndex) Unmarshal(dAtA []byte) error {
 			var msglen int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -2101,11 +2101,11 @@ func (m *TableIndex) Unmarshal(dAtA []byte) error {
 				}
 			}
 			if msglen < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			postIndex := iNdEx + msglen
 			if postIndex < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
@@ -2122,7 +2122,7 @@ func (m *TableIndex) Unmarshal(dAtA []byte) error {
 			var byteLen int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -2135,11 +2135,11 @@ func (m *TableIndex) Unmarshal(dAtA []byte) error {
 				}
 			}
 			if byteLen < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			postIndex := iNdEx + byteLen
 			if postIndex < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
@@ -2156,7 +2156,7 @@ func (m *TableIndex) Unmarshal(dAtA []byte) error {
 			m.EstimatedSize = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -2170,15 +2170,15 @@ func (m *TableIndex) Unmarshal(dAtA []byte) error {
 			}
 		default:
 			iNdEx = preIndex
-			skippy, err := skipPb(dAtA[iNdEx:])
+			skippy, err := skipBadgerpb2(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
 			if skippy < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if (iNdEx + skippy) < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if (iNdEx + skippy) > l {
 				return io.ErrUnexpectedEOF
@@ -2201,7 +2201,7 @@ func (m *Checksum) Unmarshal(dAtA []byte) error {
 		var wire uint64
 		for shift := uint(0); ; shift += 7 {
 			if shift >= 64 {
-				return ErrIntOverflowPb
+				return ErrIntOverflowBadgerpb2
 			}
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
@@ -2229,7 +2229,7 @@ func (m *Checksum) Unmarshal(dAtA []byte) error {
 			m.Algo = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -2248,7 +2248,7 @@ func (m *Checksum) Unmarshal(dAtA []byte) error {
 			m.Sum = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -2262,15 +2262,15 @@ func (m *Checksum) Unmarshal(dAtA []byte) error {
 			}
 		default:
 			iNdEx = preIndex
-			skippy, err := skipPb(dAtA[iNdEx:])
+			skippy, err := skipBadgerpb2(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
 			if skippy < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if (iNdEx + skippy) < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if (iNdEx + skippy) > l {
 				return io.ErrUnexpectedEOF
@@ -2293,7 +2293,7 @@ func (m *DataKey) Unmarshal(dAtA []byte) error {
 		var wire uint64
 		for shift := uint(0); ; shift += 7 {
 			if shift >= 64 {
-				return ErrIntOverflowPb
+				return ErrIntOverflowBadgerpb2
 			}
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
@@ -2321,7 +2321,7 @@ func (m *DataKey) Unmarshal(dAtA []byte) error {
 			m.KeyId = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -2340,7 +2340,7 @@ func (m *DataKey) Unmarshal(dAtA []byte) error {
 			var byteLen int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -2353,11 +2353,11 @@ func (m *DataKey) Unmarshal(dAtA []byte) error {
 				}
 			}
 			if byteLen < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			postIndex := iNdEx + byteLen
 			if postIndex < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
@@ -2374,7 +2374,7 @@ func (m *DataKey) Unmarshal(dAtA []byte) error {
 			var byteLen int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -2387,11 +2387,11 @@ func (m *DataKey) Unmarshal(dAtA []byte) error {
 				}
 			}
 			if byteLen < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			postIndex := iNdEx + byteLen
 			if postIndex < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
@@ -2408,7 +2408,7 @@ func (m *DataKey) Unmarshal(dAtA []byte) error {
 			m.CreatedAt = 0
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return ErrIntOverflowPb
+					return ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
@@ -2422,15 +2422,15 @@ func (m *DataKey) Unmarshal(dAtA []byte) error {
 			}
 		default:
 			iNdEx = preIndex
-			skippy, err := skipPb(dAtA[iNdEx:])
+			skippy, err := skipBadgerpb2(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
 			if skippy < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if (iNdEx + skippy) < 0 {
-				return ErrInvalidLengthPb
+				return ErrInvalidLengthBadgerpb2
 			}
 			if (iNdEx + skippy) > l {
 				return io.ErrUnexpectedEOF
@@ -2445,7 +2445,7 @@ func (m *DataKey) Unmarshal(dAtA []byte) error {
 	}
 	return nil
 }
-func skipPb(dAtA []byte) (n int, err error) {
+func skipBadgerpb2(dAtA []byte) (n int, err error) {
 	l := len(dAtA)
 	iNdEx := 0
 	depth := 0
@@ -2453,7 +2453,7 @@ func skipPb(dAtA []byte) (n int, err error) {
 		var wire uint64
 		for shift := uint(0); ; shift += 7 {
 			if shift >= 64 {
-				return 0, ErrIntOverflowPb
+				return 0, ErrIntOverflowBadgerpb2
 			}
 			if iNdEx >= l {
 				return 0, io.ErrUnexpectedEOF
@@ -2470,7 +2470,7 @@ func skipPb(dAtA []byte) (n int, err error) {
 		case 0:
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return 0, ErrIntOverflowPb
+					return 0, ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return 0, io.ErrUnexpectedEOF
@@ -2486,7 +2486,7 @@ func skipPb(dAtA []byte) (n int, err error) {
 			var length int
 			for shift := uint(0); ; shift += 7 {
 				if shift >= 64 {
-					return 0, ErrIntOverflowPb
+					return 0, ErrIntOverflowBadgerpb2
 				}
 				if iNdEx >= l {
 					return 0, io.ErrUnexpectedEOF
@@ -2499,14 +2499,14 @@ func skipPb(dAtA []byte) (n int, err error) {
 				}
 			}
 			if length < 0 {
-				return 0, ErrInvalidLengthPb
+				return 0, ErrInvalidLengthBadgerpb2
 			}
 			iNdEx += length
 		case 3:
 			depth++
 		case 4:
 			if depth == 0 {
-				return 0, ErrUnexpectedEndOfGroupPb
+				return 0, ErrUnexpectedEndOfGroupBadgerpb2
 			}
 			depth--
 		case 5:
@@ -2515,7 +2515,7 @@ func skipPb(dAtA []byte) (n int, err error) {
 			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
 		}
 		if iNdEx < 0 {
-			return 0, ErrInvalidLengthPb
+			return 0, ErrInvalidLengthBadgerpb2
 		}
 		if depth == 0 {
 			return iNdEx, nil
@@ -2525,7 +2525,7 @@ func skipPb(dAtA []byte) (n int, err error) {
 }
 
 var (
-	ErrInvalidLengthPb        = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowPb          = fmt.Errorf("proto: integer overflow")
-	ErrUnexpectedEndOfGroupPb = fmt.Errorf("proto: unexpected end of group")
+	ErrInvalidLengthBadgerpb2        = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowBadgerpb2          = fmt.Errorf("proto: integer overflow")
+	ErrUnexpectedEndOfGroupBadgerpb2 = fmt.Errorf("proto: unexpected end of group")
 )
diff --git a/pb/pb.proto b/pb/badgerpb2.proto
similarity index 100%
rename from pb/pb.proto
rename to pb/badgerpb2.proto
diff --git a/pb/gen.sh b/pb/gen.sh
index 18e2d29..0b01769 100755
--- a/pb/gen.sh
+++ b/pb/gen.sh
@@ -1,11 +1,8 @@
 #!/bin/bash
 
-# You might need to go get -v github.com/gogo/protobuf/...
+# Run this script from its directory, so that badgerpb2.proto is where it's expected to
+# be.
 
-protos=${GOPATH-$HOME/go}/src/github.com/dgraph-io/badger/pb
-pushd $protos > /dev/null
-protoc --gofast_out=plugins=grpc:. -I=. pb.proto
+# You might need to go get -v github.com/gogo/protobuf/...
 
-# Move pb.pb.go file to the correct directory. This is necessary because protoc
-# would generate the pb.pb.go file inside a different directory.
-mv $protos/github.com/dgraph-io/badger/v2/pb/pb.pb.go ./
+protoc --gofast_out=plugins=grpc:. --gofast_opt=paths=source_relative -I=. badgerpb2.proto
diff --git a/value.go b/value.go
index 9a3547f..0ed99c6 100644
--- a/value.go
+++ b/value.go
@@ -1699,6 +1699,12 @@ func discardEntry(e Entry, vs y.ValueStruct, db *DB) bool {
 	return false
 }
 
+type reason struct {
+	total   float64
+	discard float64
+	count   int
+}
+
 func (vlog *valueLog) doRunGC(lf *logFile, discardRatio float64, tr trace.Trace) (err error) {
 	// Update stats before exiting
 	defer func() {
@@ -1708,31 +1714,61 @@ func (vlog *valueLog) doRunGC(lf *logFile, discardRatio float64, tr trace.Trace)
 			vlog.lfDiscardStats.Unlock()
 		}
 	}()
+	s := &sampler{
+		lf:            lf,
+		tr:            tr,
+		countRatio:    0.01, // 1% of num entries.
+		sizeRatio:     0.1,  // 10% of the file as window.
+		fromBeginning: false,
+	}
 
-	type reason struct {
-		total   float64
-		discard float64
-		count   int
+	if _, err = vlog.sample(s, discardRatio); err != nil {
+		return err
 	}
 
+	if err = vlog.rewrite(lf, tr); err != nil {
+		return err
+	}
+	tr.LazyPrintf("Done rewriting.")
+	return nil
+}
+
+type sampler struct {
+	lf            *logFile
+	tr            trace.Trace
+	sizeRatio     float64
+	countRatio    float64
+	fromBeginning bool
+}
+
+func (vlog *valueLog) sample(samp *sampler, discardRatio float64) (*reason, error) {
+	tr := samp.tr
+	sizePercent := samp.sizeRatio
+	countPercent := samp.countRatio
+	lf := samp.lf
+
 	fi, err := lf.fd.Stat()
 	if err != nil {
 		tr.LazyPrintf("Error while finding file size: %v", err)
 		tr.SetError()
-		return err
+		return nil, err
 	}
 
 	// Set up the sampling window sizes.
-	sizeWindow := float64(fi.Size()) * 0.1                          // 10% of the file as window.
-	sizeWindowM := sizeWindow / (1 << 20)                           // in MBs.
-	countWindow := int(float64(vlog.opt.ValueLogMaxEntries) * 0.01) // 1% of num entries.
+	sizeWindow := float64(fi.Size()) * sizePercent
+	sizeWindowM := sizeWindow / (1 << 20) // in MBs.
+	countWindow := int(float64(vlog.opt.ValueLogMaxEntries) * countPercent)
 	tr.LazyPrintf("Size window: %5.2f. Count window: %d.", sizeWindow, countWindow)
 
-	// Pick a random start point for the log.
-	skipFirstM := float64(rand.Int63n(fi.Size())) // Pick a random starting location.
-	skipFirstM -= sizeWindow                      // Avoid hitting EOF by moving back by window.
-	skipFirstM /= float64(mi)                     // Convert to MBs.
-	tr.LazyPrintf("Skip first %5.2f MB of file of size: %d MB", skipFirstM, fi.Size()/mi)
+	var skipFirstM float64
+	// Skip data only if fromBeginning is set to false. Pick a random start point.
+	if !samp.fromBeginning {
+		// Pick a random start point for the log.
+		skipFirstM := float64(rand.Int63n(fi.Size())) // Pick a random starting location.
+		skipFirstM -= sizeWindow                      // Avoid hitting EOF by moving back by window.
+		skipFirstM /= float64(mi)                     // Convert to MBs.
+		tr.LazyPrintf("Skip first %5.2f MB of file of size: %d MB", skipFirstM, fi.Size()/mi)
+	}
 	var skipped float64
 
 	var r reason
@@ -1791,6 +1827,7 @@ func (vlog *valueLog) doRunGC(lf *logFile, discardRatio float64, tr trace.Trace)
 			// This is still the active entry. This would need to be rewritten.
 
 		} else {
+			// Todo(ibrahim): Can this ever happen? See the else in rewrite function.
 			vlog.opt.Debugf("Reason=%+v\n", r)
 			buf, lf, err := vlog.readValueBytes(vp, s)
 			// we need to decide, whether to unlock the lock file immediately based on the
@@ -1817,22 +1854,17 @@ func (vlog *valueLog) doRunGC(lf *logFile, discardRatio float64, tr trace.Trace)
 	if err != nil {
 		tr.LazyPrintf("Error while iterating for RunGC: %v", err)
 		tr.SetError()
-		return err
+		return nil, err
 	}
 	tr.LazyPrintf("Fid: %d. Skipped: %5.2fMB Num iterations: %d. Data status=%+v\n",
 		lf.fid, skipped, numIterations, r)
-
 	// If we couldn't sample at least a 1000 KV pairs or at least 75% of the window size,
 	// and what we can discard is below the threshold, we should skip the rewrite.
 	if (r.count < countWindow && r.total < sizeWindowM*0.75) || r.discard < discardRatio*r.total {
 		tr.LazyPrintf("Skipping GC on fid: %d", lf.fid)
-		return ErrNoRewrite
+		return nil, ErrNoRewrite
 	}
-	if err = vlog.rewrite(lf, tr); err != nil {
-		return err
-	}
-	tr.LazyPrintf("Done rewriting.")
-	return nil
+	return &r, nil
 }
 
 func (vlog *valueLog) waitOnGC(lc *z.Closer) {
@@ -2003,3 +2035,119 @@ func (vlog *valueLog) populateDiscardStats() error {
 	vlog.lfDiscardStats.flushChan <- statsMap
 	return nil
 }
+
+func (vlog *valueLog) cleanVlog() error {
+	// Check if gc is not already running.
+	select {
+	case vlog.garbageCh <- struct{}{}:
+	default:
+		return errors.New("Gc already running")
+	}
+	defer func() { <-vlog.garbageCh }()
+
+	vlog.filesLock.RLock()
+	filesToGC := vlog.sortedFids()
+	vlog.filesLock.RUnlock()
+
+	head := atomic.LoadUint32(&vlog.maxFid)
+	for _, fid := range filesToGC {
+		tr := trace.New("Badger.ValueLog Sampling", "Sampling")
+		start := time.Now()
+		// stop on the head fid.
+		if fid == head {
+			break
+		}
+		vlog.filesLock.RLock()
+		lf, ok := vlog.filesMap[fid]
+		vlog.filesLock.RUnlock()
+		if !ok {
+			return errors.Errorf("Unknown fid %d", fid)
+		}
+
+		s := &sampler{
+			lf:            lf,
+			tr:            tr,
+			countRatio:    1, // 1% of num entries.
+			sizeRatio:     1, // 10% of the file as window.
+			fromBeginning: true,
+		}
+		vlog.db.opt.Logger.Infof("Sampling fid %d", fid)
+		r, err := vlog.sample(s, 0)
+		if err != nil {
+			return err
+		}
+		vlog.db.opt.Logger.Infof("Sampled fid %d. Took: %s", fid, time.Since(start))
+
+		// Skip vlog files with < 0.5 discard ratio.
+		if r.discard/r.total < 0.5 {
+			continue
+		}
+		vlog.db.opt.Logger.Infof("Rewriting fid %d", fid)
+		start = time.Now()
+		if err := vlog.rewrite(lf, tr); err != nil {
+			return errors.Wrapf(err, "file: %s", lf.fd.Name())
+		}
+		vlog.db.opt.Logger.Infof("Rewritten fid %d. Took: %s", fid, time.Since(start))
+	}
+
+	return nil
+}
+
+type sampleResult struct {
+	Fid          uint32
+	FileSize     int64
+	DiscardRatio float64
+}
+
+// getDiscardStats is used to collect and return the discard stats for all the files.
+func (vlog *valueLog) getDiscardStats() ([]sampleResult, error) {
+	vlog.filesLock.RLock()
+	filesToSample := vlog.sortedFids()
+	vlog.filesLock.RUnlock()
+
+	head := atomic.LoadUint32(&vlog.maxFid)
+
+	tr := trace.New("Badger.ValueLog Sampling", "Sampling")
+	tr.SetMaxEvents(100)
+	samp := &sampler{
+		countRatio:    1,    // 100% of entries in the file.
+		sizeRatio:     1,    // 100% of the file size.
+		fromBeginning: true, // Start reading from the start.
+		tr:            tr,
+	}
+
+	var result []sampleResult
+	for _, fid := range filesToSample {
+		// Skip the head file since it is actively being written.
+		if fid == head {
+			continue
+		}
+		start := time.Now()
+		vlog.db.opt.Logger.Infof("Sampling fid %d", fid)
+
+		vlog.filesLock.RLock()
+		lf, ok := vlog.filesMap[fid]
+		vlog.filesLock.RUnlock()
+		if !ok {
+			return nil, errors.Errorf("Unknown fid %d", fid)
+		}
+		samp.lf = lf
+		// Set discard ratio to 0 so that sample never returns a ErrNoRewrite error.
+		r, err := vlog.sample(samp, 0)
+		if err != nil {
+			return nil, errors.Wrapf(err, "file: %s", lf.fd.Name())
+		}
+
+		fstat, err := lf.fd.Stat()
+		if err != nil {
+			return nil, errors.Wrapf(err, "Unable to check stat for %q", lf.path)
+		}
+
+		result = append(result, sampleResult{
+			Fid:          fid,
+			DiscardRatio: r.discard / r.total,
+			FileSize:     fstat.Size()})
+		vlog.db.opt.Logger.Infof("Sampled fid %d. Took: %s", fid, time.Since(start))
+	}
+	return result, nil
+}


Test patch:
diff --git a/batch_test.go b/batch_test.go
index 4a970d4..273a297 100644
--- a/batch_test.go
+++ b/batch_test.go
@@ -18,6 +18,7 @@ package badger
 
 import (
 	"fmt"
+	"io/ioutil"
 	"testing"
 	"time"
 
@@ -144,3 +145,18 @@ func TestFlushPanic(t *testing.T) {
 		})
 	})
 }
+
+func TestBatchErrDeadlock(t *testing.T) {
+	dir, err := ioutil.TempDir("", "badger-test")
+	require.NoError(t, err)
+	defer removeDir(dir)
+
+	opt := DefaultOptions(dir)
+	db, err := OpenManaged(opt)
+	require.NoError(t, err)
+
+	wb := db.NewManagedWriteBatch()
+	require.NoError(t, wb.SetEntryAt(&Entry{Key: []byte("foo")}, 0))
+	require.Error(t, wb.Flush())
+	require.NoError(t, db.Close())
+}
diff --git a/db2_test.go b/db2_test.go
index 7b165e0..f0e6e59 100644
--- a/db2_test.go
+++ b/db2_test.go
@@ -829,6 +829,95 @@ func TestDropAllDropPrefix(t *testing.T) {
 	})
 }
 
+func TestCleanVlog(t *testing.T) {
+	opt := DefaultOptions("")
+	opt.ValueLogMaxEntries = 2
+	val := make([]byte, 2<<10)
+	rand.Read(val)
+
+	runBadgerTest(t, &opt, func(t *testing.T, db *DB) {
+		for i := 0; i < 100; i++ {
+			db.Update(func(txn *Txn) error {
+				txn.Set([]byte(fmt.Sprintf("foo-%d", i)), val)
+				return nil
+			})
+		}
+		// Use separate transaction for foo and bar writes so that they go into
+		// different files.
+		for i := 0; i < 100; i++ {
+			db.Update(func(txn *Txn) error {
+				txn.Set([]byte(fmt.Sprintf("bar-%d", i)), val)
+				return nil
+			})
+		}
+		count := 0
+		db.View(func(txn *Txn) error {
+			iopt := DefaultIteratorOptions
+			it := txn.NewIterator(iopt)
+			defer it.Close()
+			for it.Rewind(); it.Valid(); it.Next() {
+				count++
+				vs, err := it.Item().ValueCopy(nil)
+				require.NoError(t, err)
+				require.Equal(t, val, vs)
+			}
+			return nil
+		})
+
+		fileCount := len(db.vlog.filesMap)
+
+		// Drop all the foo-%d keys
+		require.NoError(t, db.DropPrefix([]byte("foo")))
+
+		res, err := db.SampleVlog()
+		require.NoError(t, err)
+		fullStaleFiles := 0
+		for _, r := range res {
+			fmt.Printf("r.Fid:%d, Ratio: %f Size: %d\n", r.Fid, r.DiscardRatio, r.FileSize)
+			if r.DiscardRatio == 1 {
+				fullStaleFiles++
+			}
+		}
+		require.Equal(t, 50, fullStaleFiles)
+
+		count2 := 0
+		db.View(func(txn *Txn) error {
+			iopt := DefaultIteratorOptions
+			it := txn.NewIterator(iopt)
+			defer it.Close()
+			for it.Rewind(); it.Valid(); it.Next() {
+				count2++
+				vs, err := it.Item().ValueCopy(nil)
+				require.NoError(t, err)
+				require.Equal(t, val, vs)
+			}
+			return nil
+		})
+
+		// We've dropped half the keys.
+		require.Equal(t, count/2, count2)
+
+		// Clean the vlog files.
+		require.NoError(t, db.GCVlog())
+		// Files should be less now.
+		require.Less(t, len(db.vlog.filesMap), fileCount)
+		count3 := 0
+		db.View(func(txn *Txn) error {
+			iopt := DefaultIteratorOptions
+			it := txn.NewIterator(iopt)
+			defer it.Close()
+			for it.Rewind(); it.Valid(); it.Next() {
+				count3++
+				vs, err := it.Item().ValueCopy(nil)
+				require.NoError(t, err)
+				require.Equal(t, val, vs)
+			}
+			return nil
+		})
+		// The amount of keys should be same.
+		require.Equal(t, count2, count3)
+	})
+}
 func TestIsClosed(t *testing.T) {
 	test := func(inMemory bool) {
 		opt := DefaultOptions("")