Skip to content

Commit 5c1b4c8

Browse files
author
Ibrahim Jarif
authored
Improvements: Manual Memory allocation via Calloc (#1459)
This PR contains a bunch of improvements 1. This PR reverts the following reverts (adds them back) - Revert "Compress/Encrypt Blocks in the background 6001230 - Revert "Buffer pool for decompression 800305e - Revert "fix: Fix race condition in block.incRef 63d9309 - Revert "add assert to check integer overflow for table size e0d058c 2. Calloc and Free for memory allocation - The block buffers for decompression and encryption are now allocated using calloc and free. The `y/calloc.go` file contains the code. The compaction changes are moved to a separate PR for easier cherry-picking #1466
1 parent 0b8eb4c commit 5c1b4c8

25 files changed

+758
-204
lines changed

badger/cmd/bank.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func toSlice(bal uint64) []byte {
125125
}
126126

127127
func getBalance(txn *badger.Txn, account int) (uint64, error) {
128-
item, err := txn.Get(key(account))
128+
item, err := get(txn, key(account))
129129
if err != nil {
130130
return 0, err
131131
}
@@ -197,14 +197,33 @@ func diff(a, b []account) string {
197197

198198
var errFailure = errors.New("test failed due to balance mismatch")
199199

200+
// get function will fetch the value for the key "k" either by using the
201+
// txn.Get API or the iterator.Seek API.
202+
func get(txn *badger.Txn, k []byte) (*badger.Item, error) {
203+
if rand.Int()%2 == 0 {
204+
return txn.Get(k)
205+
}
206+
207+
iopt := badger.DefaultIteratorOptions
208+
// PrefectValues is expensive. We don't need it here.
209+
iopt.PrefetchValues = false
210+
it := txn.NewIterator(iopt)
211+
defer it.Close()
212+
it.Seek(k)
213+
if it.Valid() {
214+
return it.Item(), nil
215+
}
216+
return nil, badger.ErrKeyNotFound
217+
}
218+
200219
// seekTotal retrives the total of all accounts by seeking for each account key.
201220
func seekTotal(txn *badger.Txn) ([]account, error) {
202221
expected := uint64(numAccounts) * uint64(initialBal)
203222
var accounts []account
204223

205224
var total uint64
206225
for i := 0; i < numAccounts; i++ {
207-
item, err := txn.Get(key(i))
226+
item, err := get(txn, key(i))
208227
if err != nil {
209228
log.Printf("Error for account: %d. err=%v. key=%q\n", i, err, key(i))
210229
return accounts, err
@@ -343,7 +362,11 @@ func runTest(cmd *cobra.Command, args []string) error {
343362
WithNumMemtables(2).
344363
// Do not GC any versions, because we need them for the disect..
345364
WithNumVersionsToKeep(int(math.MaxInt32)).
346-
WithValueThreshold(1) // Make all values go to value log
365+
WithValueThreshold(1). // Make all values go to value log
366+
WithCompression(options.ZSTD).
367+
WithKeepL0InMemory(false).
368+
WithMaxCacheSize(10 << 20)
369+
347370
if mmap {
348371
opts = opts.WithTableLoadingMode(options.MemoryMap)
349372
}

badger/cmd/write_bench.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,6 @@ func reportStats(c *y.Closer, db *badger.DB) {
347347
if showKeysCount {
348348
showKeysStats(db)
349349
}
350-
351350
// fetch directory contents
352351
if showDir {
353352
err := filepath.Walk(sstDir, func(path string, info os.FileInfo, err error) error {

db.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ func (db *DB) replayFunction() func(Entry, valuePointer) error {
194194
func Open(opt Options) (db *DB, err error) {
195195
// It's okay to have zero compactors which will disable all compactions but
196196
// we cannot have just one compactor otherwise we will end up with all data
197-
// one level 2.
197+
// on level 2.
198198
if opt.NumCompactors == 1 {
199199
return nil, errors.New("Cannot have 1 compactor. Need at least 2")
200200
}
@@ -324,6 +324,12 @@ func Open(opt Options) (db *DB, err error) {
324324
MaxCost: int64(float64(opt.MaxCacheSize) * 0.95),
325325
BufferItems: 64,
326326
Metrics: true,
327+
OnEvict: func(i *ristretto.Item) {
328+
table.BlockEvictHandler(i.Value)
329+
},
330+
OnReject: func(i *ristretto.Item) {
331+
table.BlockEvictHandler(i.Value)
332+
},
327333
}
328334
db.blockCache, err = ristretto.NewCache(&config)
329335
if err != nil {
@@ -986,6 +992,7 @@ func buildL0Table(ft flushTask, bopts table.Options) []byte {
986992
defer iter.Close()
987993
b := table.NewTableBuilder(bopts)
988994
defer b.Close()
995+
989996
var vp valuePointer
990997
for iter.SeekToFirst(); iter.Valid(); iter.Next() {
991998
if len(ft.dropPrefixes) > 0 && hasAnyPrefixes(iter.Key(), ft.dropPrefixes) {
@@ -997,7 +1004,7 @@ func buildL0Table(ft flushTask, bopts table.Options) []byte {
9971004
}
9981005
b.Add(iter.Key(), iter.Value(), vp.Len)
9991006
}
1000-
return b.Finish()
1007+
return b.Finish(true)
10011008
}
10021009

10031010
type flushTask struct {

db2_test.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ func createTableWithRange(t *testing.T, db *DB, start, end int) *table.Table {
547547
fd, err := y.CreateSyncedFile(table.NewFilename(fileID, db.opt.Dir), true)
548548
require.NoError(t, err)
549549

550-
_, err = fd.Write(b.Finish())
550+
_, err = fd.Write(b.Finish(false))
551551
require.NoError(t, err, "unable to write to file")
552552

553553
tab, err := table.OpenTable(fd, bopts)
@@ -670,16 +670,13 @@ func TestL0GCBug(t *testing.T) {
670670
// Simulate a crash by not closing db1 but releasing the locks.
671671
if db1.dirLockGuard != nil {
672672
require.NoError(t, db1.dirLockGuard.release())
673+
db1.dirLockGuard = nil
673674
}
674675
if db1.valueDirGuard != nil {
675676
require.NoError(t, db1.valueDirGuard.release())
677+
db1.valueDirGuard = nil
676678
}
677-
for _, f := range db1.vlog.filesMap {
678-
require.NoError(t, f.fd.Close())
679-
}
680-
require.NoError(t, db1.registry.Close())
681-
require.NoError(t, db1.lc.close())
682-
require.NoError(t, db1.manifest.close())
679+
require.NoError(t, db1.Close())
683680

684681
db2, err := Open(opts)
685682
require.NoError(t, err)

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.12
55
require (
66
github.com/DataDog/zstd v1.4.1
77
github.com/cespare/xxhash v1.1.0
8-
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de
8+
github.com/dgraph-io/ristretto v0.0.4-0.20200817124926-18e279725890
99
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2
1010
github.com/dustin/go-humanize v1.0.0
1111
github.com/golang/protobuf v1.3.1

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc
1313
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1414
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
1515
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
16-
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA=
17-
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
16+
github.com/dgraph-io/ristretto v0.0.4-0.20200817124926-18e279725890 h1:/6pLcQq2GNdLPOotXztuLDXYRPraTIzZMPiJW8HzAwg=
17+
github.com/dgraph-io/ristretto v0.0.4-0.20200817124926-18e279725890/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
1818
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
1919
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
2020
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=

key_registry.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ func validRegistry(fp *os.File, encryptionKey []byte) error {
159159
}
160160
if len(encryptionKey) > 0 {
161161
// Decrypting sanity text.
162-
if eSanityText, err = y.XORBlock(eSanityText, encryptionKey, iv); err != nil {
162+
if eSanityText, err = y.XORBlockAllocate(eSanityText, encryptionKey, iv); err != nil {
163163
return y.Wrapf(err, "During validRegistry")
164164
}
165165
}
@@ -200,7 +200,7 @@ func (kri *keyRegistryIterator) next() (*pb.DataKey, error) {
200200
}
201201
if len(kri.encryptionKey) > 0 {
202202
// Decrypt the key if the storage key exists.
203-
if dataKey.Data, err = y.XORBlock(dataKey.Data, kri.encryptionKey, dataKey.Iv); err != nil {
203+
if dataKey.Data, err = y.XORBlockAllocate(dataKey.Data, kri.encryptionKey, dataKey.Iv); err != nil {
204204
return nil, y.Wrapf(err, "While decrypting datakey in keyRegistryIterator.next")
205205
}
206206
}
@@ -254,7 +254,7 @@ func WriteKeyRegistry(reg *KeyRegistry, opt KeyRegistryOptions) error {
254254
eSanity := sanityText
255255
if len(opt.EncryptionKey) > 0 {
256256
var err error
257-
eSanity, err = y.XORBlock(eSanity, opt.EncryptionKey, iv)
257+
eSanity, err = y.XORBlockAllocate(eSanity, opt.EncryptionKey, iv)
258258
if err != nil {
259259
return y.Wrapf(err, "Error while encrpting sanity text in WriteKeyRegistry")
260260
}
@@ -395,7 +395,7 @@ func storeDataKey(buf *bytes.Buffer, storageKey []byte, k *pb.DataKey) error {
395395
return nil
396396
}
397397
var err error
398-
k.Data, err = y.XORBlock(k.Data, storageKey, k.Iv)
398+
k.Data, err = y.XORBlockAllocate(k.Data, storageKey, k.Iv)
399399
return err
400400
}
401401
// In memory datakey will be plain text so encrypting before storing to the disk.

levels.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ nextTable:
657657
numKeys, numSkips, time.Since(timeStart))
658658
if builder.Empty() {
659659
// Cleanup builder resources:
660-
builder.Finish()
660+
builder.Finish(false)
661661
builder.Close()
662662
continue
663663
}
@@ -677,7 +677,7 @@ nextTable:
677677
return nil, errors.Wrapf(err, "While opening new table: %d", fileID)
678678
}
679679

680-
if _, err := fd.Write(builder.Finish()); err != nil {
680+
if _, err := fd.Write(builder.Finish(false)); err != nil {
681681
return nil, errors.Wrapf(err, "Unable to write to file: %d", fileID)
682682
}
683683
tbl, err := table.OpenTable(fd, bopts)
@@ -688,7 +688,7 @@ nextTable:
688688
var tbl *table.Table
689689
var err error
690690
if s.kv.opt.InMemory {
691-
tbl, err = table.OpenInMemoryTable(builder.Finish(), fileID, &bopts)
691+
tbl, err = table.OpenInMemoryTable(builder.Finish(true), fileID, &bopts)
692692
} else {
693693
tbl, err = build(fileID)
694694
}
@@ -700,6 +700,9 @@ nextTable:
700700

701701
mu.Lock()
702702
newTables = append(newTables, tbl)
703+
num := atomic.LoadInt32(&table.NumBlocks)
704+
allocs := float64(atomic.LoadInt64(&y.NumAllocs)) / float64((1 << 20))
705+
s.kv.opt.Debugf("Num Blocks: %d. Num Allocs (MB): %.2f\n", num, allocs)
703706
mu.Unlock()
704707
}(builder)
705708
}

levels_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func createAndOpen(db *DB, td []keyValVersion, level int) {
4949
panic(err)
5050
}
5151

52-
if _, err = fd.Write(b.Finish()); err != nil {
52+
if _, err = fd.Write(b.Finish(false)); err != nil {
5353
panic(err)
5454
}
5555
tab, err := table.OpenTable(fd, opts)
@@ -740,7 +740,7 @@ func createEmptyTable(db *DB) *table.Table {
740740
b.Add(y.KeyWithTs([]byte("foo"), 1), y.ValueStruct{}, 0)
741741

742742
// Open table in memory to avoid adding changes to manifest file.
743-
tab, err := table.OpenInMemoryTable(b.Finish(), db.lc.reserveFileID(), &opts)
743+
tab, err := table.OpenInMemoryTable(b.Finish(true), db.lc.reserveFileID(), &opts)
744744
if err != nil {
745745
panic(err)
746746
}

manifest_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ func buildTable(t *testing.T, keyValues [][]string, bopts table.Options) *os.Fil
155155
UserMeta: 0,
156156
}, 0)
157157
}
158-
_, err = f.Write(b.Finish())
158+
_, err = f.Write(b.Finish(false))
159159
require.NoError(t, err, "unable to write to file.")
160160
f.Close()
161161
f, _ = y.OpenSyncedFile(filename, true)

0 commit comments

Comments
 (0)