Skip to content

Instantly share code, notes, and snippets.

@magik6k
Last active April 12, 2019 21:34
Show Gist options
  • Save magik6k/8c379cc02b443495e4809170fb8803a9 to your computer and use it in GitHub Desktop.
Save magik6k/8c379cc02b443495e4809170fb8803a9 to your computer and use it in GitHub Desktop.
package gctest
import (
"fmt"
"io"
"io/ioutil"
"math/rand"
"os"
"path/filepath"
"syscall"
"testing"
"time"
"github.com/dustin/go-humanize"
ds "github.com/ipfs/go-datastore"
"github.com/dgraph-io/badger"
)
const bdir = "/tmp/badger"
const (
entryC = 300000
preC = 10000
entryS = 10000
)
func TestGc(t *testing.T) {
opts := badger.DefaultOptions
if err := os.RemoveAll(bdir); err != nil {
t.Fatal(err)
}
opts.Dir = bdir
opts.ValueDir = bdir
opts.Logger = nil
db, err := badger.Open(opts)
if err != nil {
t.Fatal(err)
}
r := rand.New(rand.NewSource(555))
wb := db.NewWriteBatch()
for i := 0; i < preC; i++ { // put non-deletable entries
b, err := ioutil.ReadAll(io.LimitReader(r, entryS))
if err != nil {
t.Fatal(err)
}
if err := wb.Set(ds.RandomKey().Bytes(), b, 0); err != nil {
t.Fatal(err)
}
}
if err := wb.Flush(); err != nil {
t.Fatal(err)
}
pds(t, "non-deletable put")
wb = db.NewWriteBatch()
es := make([][]byte, entryC)
for i := 0; i < entryC; i++ { // put deletable entries
b, err := ioutil.ReadAll(io.LimitReader(r, entryS))
if err != nil {
t.Fatal(err)
}
es[i] = ds.RandomKey().Bytes()
if err := wb.Set(es[i], b, 0); err != nil {
t.Fatal(err)
}
}
if err := wb.Flush(); err != nil {
t.Fatal(err)
}
pds(t, "data put")
if err := db.Close(); err != nil {
t.Fatal(err)
}
pds(t, "put closed")
db, err = badger.Open(opts)
if err != nil {
t.Fatal(err)
}
pds(t, "del-open")
wb = db.NewWriteBatch()
for _, e := range es {
if err := wb.Delete(e); err != nil {
t.Fatal(err)
}
}
if err := wb.Flush(); err != nil {
t.Fatal(err)
}
pds(t, "after del")
for err == nil {
err = db.RunValueLogGC(0.5)
pds(t, "gc-step")
}
if err != badger.ErrNoRewrite {
t.Fatal(err)
}
pds(t, "gc")
if err := db.Close(); err != nil {
t.Fatal(err)
}
pds(t, "close-gc")
}
func pds(t *testing.T, prefix string) {
time.Sleep(1*time.Second) // wait for things to settle down a bit
i, real, sst, vlog, err := dirSize(bdir)
if err != nil {
t.Fatal(err)
}
fmt.Printf("\x1b[32m%s: %s(%s); sst: %s; vlog: %s\x1b[39m\n",
prefix,
humanize.Bytes(uint64(i)),
humanize.Bytes(uint64(real)),
humanize.Bytes(uint64(sst)),
humanize.Bytes(uint64(vlog)))
}
func dirSize(path string) (int64, int64, int64, int64, error) {
var size int64
var real int64
var sst int64
var vlog int64
err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
size += info.Size()
real += (info.Sys().(*syscall.Stat_t)).Blocks * 512
if len(info.Name()) < 10 {
return err
}
if info.Name()[7] == 's' {
sst += info.Size()
}
if info.Name()[7] == 'v' {
vlog += info.Size()
}
}
return err
})
return size, real, sst, vlog, err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment