Skip to content

Commit

Permalink
Replace simple cache with free cache to avoid GC runtimes
Browse files Browse the repository at this point in the history
  • Loading branch information
aalda committed Nov 22, 2018
1 parent 9e9dd6a commit 7ef38b2
Show file tree
Hide file tree
Showing 9 changed files with 216 additions and 28 deletions.
2 changes: 1 addition & 1 deletion balloon/balloon.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ type Balloon struct {
func NewBalloon(store storage.Store, hasherF func() hashing.Hasher) (*Balloon, error) {

// create caches
hyperCache := cache.NewSimpleCache(1 << 2)
hyperCache := cache.NewFreeCache(hyper.CacheSize)

// create trees
historyTree := history.NewHistoryTree(hasherF, store, 30)
Expand Down
86 changes: 86 additions & 0 deletions balloon/cache/free.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
Copyright 2018 Banco Bilbao Vizcaya Argentaria, S.A.
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 cache

import (
"bytes"
"runtime/debug"

"github.com/bbva/qed/balloon/navigator"
"github.com/bbva/qed/hashing"
"github.com/bbva/qed/storage"
"github.com/coocood/freecache"
)

type FreeCache struct {
cached *freecache.Cache
}

func NewFreeCache(initialSize int) *FreeCache {
cache := freecache.NewCache(initialSize)
debug.SetGCPercent(20)
return &FreeCache{cached: cache}
}

func (c FreeCache) Get(pos navigator.Position) (hashing.Digest, bool) {
value, err := c.cached.Get(pos.Bytes())
if err != nil {
return nil, false
}
return value, true
}

func (c *FreeCache) Put(pos navigator.Position, value hashing.Digest) {
c.cached.Set(pos.Bytes(), value, 0)
}

func (c *FreeCache) Fill(r storage.KVPairReader) (err error) {
defer r.Close()
for {
entries := make([]*storage.KVPair, 100)
n, err := r.Read(entries)
if err != nil || n == 0 {
break
}
for _, entry := range entries {
if entry != nil {
c.cached.Set(entry.Key, entry.Value, 0)
}
}
}
return nil
}

func (c FreeCache) Size() int {
return int(c.cached.EntryCount())
}

func (c FreeCache) Equal(o *FreeCache) bool {
it := c.cached.NewIterator()
entry := it.Next()
for entry != nil {
v2, err := o.cached.Get(entry.Key)
if err != nil {
return false
}
if !bytes.Equal(entry.Value, v2) {
return false
}
entry = it.Next()
}
return true
}
73 changes: 73 additions & 0 deletions balloon/cache/free_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
Copyright 2018 Banco Bilbao Vizcaya Argentaria, S.A.
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 cache

import (
"testing"

"github.com/bbva/qed/balloon/navigator"
"github.com/bbva/qed/hashing"
"github.com/bbva/qed/util"
"github.com/stretchr/testify/require"
)

func TestFreeCache(t *testing.T) {

testCases := []struct {
pos navigator.Position
value hashing.Digest
cached bool
}{
{&navigator.FakePosition{[]byte{0x0}, 0}, hashing.Digest{0x1}, true},
{&navigator.FakePosition{[]byte{0x1}, 0}, hashing.Digest{0x2}, true},
{&navigator.FakePosition{[]byte{0x2}, 0}, hashing.Digest{0x3}, false},
}

cache := NewFreeCache(100 * 1024)

for i, c := range testCases {
if c.cached {
cache.Put(c.pos, c.value)
}

cachedValue, ok := cache.Get(c.pos)

if c.cached {
require.Truef(t, ok, "The key should exists in cache in test case %d", i)
require.Equalf(t, c.value, cachedValue, "The cached value should be equal to stored value in test case %d", i)
} else {
require.Falsef(t, ok, "The key should not exist in cache in test case %d", i)
}
}
}

func TestFillFreeCache(t *testing.T) {

numElems := uint64(10000)
cache := NewFreeCache(10000 * 1024)
reader := NewFakeKVPairReader(numElems)

err := cache.Fill(reader)

require.NoError(t, err)
require.Truef(t, reader.Remaining == 0, "All elements should be cached. Remaining: %d", reader.Remaining)

for i := uint64(0); i < numElems; i++ {
pos := &navigator.FakePosition{util.Uint64AsBytes(i), 0}
_, ok := cache.Get(pos)
require.Truef(t, ok, "The element in position %v should be in cache", pos)
}
}
25 changes: 0 additions & 25 deletions balloon/cache/simple_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ import (
"github.com/bbva/qed/hashing"
"github.com/bbva/qed/util"
"github.com/stretchr/testify/require"

"github.com/bbva/qed/storage"
"github.com/bbva/qed/testutils/rand"
)

func TestSimpleCache(t *testing.T) {
Expand Down Expand Up @@ -75,25 +72,3 @@ func TestFillSimpleCache(t *testing.T) {
require.Truef(t, ok, "The element in position %v should be in cache", pos)
}
}

type FakeKVPairReader struct {
Remaining uint64
index uint64
}

func NewFakeKVPairReader(numElems uint64) *FakeKVPairReader {
return &FakeKVPairReader{numElems, 0}
}

func (r *FakeKVPairReader) Read(buffer []*storage.KVPair) (n int, err error) {
for n = 0; r.Remaining > 0 && n < len(buffer); n++ {
pos := &navigator.FakePosition{util.Uint64AsBytes(r.index), 0}
buffer[n] = &storage.KVPair{pos.Bytes(), rand.Bytes(8)}
r.Remaining--
r.index++
}
return n, nil
}
func (r *FakeKVPairReader) Close() {
r.Remaining = 0
}
24 changes: 24 additions & 0 deletions balloon/cache/test_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"github.com/bbva/qed/balloon/navigator"
"github.com/bbva/qed/hashing"
"github.com/bbva/qed/storage"
"github.com/bbva/qed/testutils/rand"
"github.com/bbva/qed/util"
)

type FakeCache struct {
Expand All @@ -39,3 +41,25 @@ func (c *FakeCache) Put(pos navigator.Position, value hashing.Digest) {}
func (c *FakeCache) Fill(r storage.KVPairReader) error { return nil }

func (c FakeCache) Size() int { return 1 }

type FakeKVPairReader struct {
Remaining uint64
index uint64
}

func NewFakeKVPairReader(numElems uint64) *FakeKVPairReader {
return &FakeKVPairReader{numElems, 0}
}

func (r *FakeKVPairReader) Read(buffer []*storage.KVPair) (n int, err error) {
for n = 0; r.Remaining > 0 && n < len(buffer); n++ {
pos := &navigator.FakePosition{util.Uint64AsBytes(r.index), 0}
buffer[n] = &storage.KVPair{pos.Bytes(), rand.Bytes(8)}
r.Remaining--
r.index++
}
return n, nil
}
func (r *FakeKVPairReader) Close() {
r.Remaining = 0
}
4 changes: 4 additions & 0 deletions balloon/hyper/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ import (
"github.com/bbva/qed/util"
)

const (
CacheSize int = (1 << 26) * 68 // 2^26 elements * 68 bytes for entry
)

type HyperTree struct {
store storage.Store
cache cache.ModifiableCache
Expand Down
5 changes: 3 additions & 2 deletions balloon/hyper/tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,8 @@ func BenchmarkAdd(b *testing.B) {
defer closeF()

hasher := hashing.NewSha256Hasher()
simpleCache := cache.NewSimpleCache(0)
tree := NewHyperTree(hashing.NewSha256Hasher, store, simpleCache)
freeCache := cache.NewFreeCache(CacheSize)
tree := NewHyperTree(hashing.NewSha256Hasher, store, freeCache)

b.ResetTimer()
b.N = 100000
Expand All @@ -299,4 +299,5 @@ func BenchmarkAdd(b *testing.B) {
_, mutations, _ := tree.Add(key, uint64(i))
store.Mutate(mutations)
}

}
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,24 @@ module github.com/bbva/qed
require (
github.com/bbva/raft-badger v0.1.1
github.com/boltdb/bolt v1.3.1 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/coocood/freecache v1.0.1
github.com/coreos/bbolt v1.3.0
github.com/dgraph-io/badger v1.5.4
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c
github.com/hashicorp/go-msgpack v0.0.0-20150518234257-fa3f63826f7c
github.com/hashicorp/go-multierror v1.0.0 // indirect
github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86 // indirect
github.com/hashicorp/memberlist v0.1.0
github.com/hashicorp/raft v1.0.0
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/influxdata/tdigest v0.0.0-20180711151920-a7d76c6f093a // indirect
github.com/kr/pty v1.1.3 // indirect
github.com/lucasb-eyer/go-colorful v0.0.0-20180709185858-c7842319cf3a // indirect
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 // indirect
github.com/miekg/dns v1.0.15 // indirect
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
github.com/spf13/cobra v0.0.3
github.com/spf13/pflag v1.0.3 // indirect
github.com/streadway/quantile v0.0.0-20150917103942-b0c588724d25 // indirect
Expand Down
18 changes: 18 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ github.com/AndreasBriese/bbloom v0.0.0-20170702084017-28f7e881ca57 h1:CVuXDbdzPW
github.com/AndreasBriese/bbloom v0.0.0-20170702084017-28f7e881ca57/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7 h1:PqzgE6kAMi81xWQA2QIVxjWkFHptGgC547vchpUbtFo=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/armon/go-metrics v0.0.0-20180713145231-3c58d8115a78 h1:mdRSArcFLfW0VoL34LZAKSz6LkkK4jFxVx2xYavACMg=
github.com/armon/go-metrics v0.0.0-20180713145231-3c58d8115a78/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I=
Expand All @@ -14,6 +15,10 @@ github.com/bbva/raft-badger v0.1.1 h1:v0BlEP2glTd3o1U4ShD4HtyGc08PXt4gcEBdO6Fh7O
github.com/bbva/raft-badger v0.1.1/go.mod h1:KqKb1IrW6hsgFSzXTavxddJH+5E3TmDxBbFhitk0vpY=
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/coocood/freecache v1.0.1 h1:oFyo4msX2c0QIKU+kuMJUwsKamJ+AKc2JJrKcMszJ5M=
github.com/coocood/freecache v1.0.1/go.mod h1:ePwxCDzOYvARfHdr1pByNct1at3CoKnsipOHwKlNbzI=
github.com/coreos/bbolt v1.3.0 h1:HIgH5xUWXT914HCI671AxuTTqjj64UOFr7pHn48LUTI=
github.com/coreos/bbolt v1.3.0/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand All @@ -30,14 +35,22 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.0.0-20150518234257-fa3f63826f7c h1:BTAbnbegUIMB6xmQCwWE8yRzbA4XSpnZY5hvRJC188I=
github.com/hashicorp/go-msgpack v0.0.0-20150518234257-fa3f63826f7c/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86 h1:7YOlAIO2YWnJZkQp7B5eFykaIY7C9JndqAFQyVV5BhM=
github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/memberlist v0.1.0 h1:qSsCiC0WYD39lbSitKNt40e30uorm2Ss/d4JGU1hzH8=
github.com/hashicorp/memberlist v0.1.0/go.mod h1:ncdBp14cuox2iFOq3kDiquKU6fqsTBc3W6JvZwjxxsE=
github.com/hashicorp/raft v1.0.0 h1:htBVktAOtGs4Le5Z7K8SF5H2+oWsQFYVmOgH5loro7Y=
github.com/hashicorp/raft v1.0.0/go.mod h1:DVSAWItjLjTOkVbSpWQ0j0kUADIvDaCtBxIcbNAQLkI=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
Expand All @@ -54,12 +67,17 @@ github.com/lucasb-eyer/go-colorful v0.0.0-20180709185858-c7842319cf3a h1:B2QfFRl
github.com/lucasb-eyer/go-colorful v0.0.0-20180709185858-c7842319cf3a/go.mod h1:NXg0ArsFk0Y01623LgUqoqcouGDB+PwCCQlrwrG6xJ4=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/miekg/dns v1.0.15 h1:9+UupePBQCG6zf1q/bGmTO1vumoG13jsrbWOSX1W6Tw=
github.com/miekg/dns v1.0.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/pflag v1.0.2 h1:Fy0orTDgHdbnzHcsOgfCN4LtHf0ec3wwtiwJqwvf3Gc=
Expand Down

0 comments on commit 7ef38b2

Please sign in to comment.