-
Notifications
You must be signed in to change notification settings - Fork 23
Conversation
c89dafb
to
db1b5a8
Compare
// db.Set([]byte("foo"), []byte("bar")) | ||
// db.SetSync([]byte("true"), []byte("tendermint")) | ||
// db.Delete([]byte("true")) | ||
// db.Deletesync([]byte("true")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DeleteSync
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I'll update that.
func NewBadgerDB(dbName, dir string) (*BadgerDB, error) { | ||
// BadgerDB doesn't expose a way for us to | ||
// create a DB with the user's supplied name. | ||
if err := os.MkdirAll(dir, 0755); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you think MkdirAll
belongs to NewBadgerDBWithOptions
function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so, db.NewDB uses NewBadgerDB and expects the directory making to be handled magically. Moving it out of NewBadgerDB would mean that we'd have to document separately that BadgerDB needs to have its directory made before-hand, and that would make it awkward.
if err := os.MkdirAll(dir, 0755); err != nil { | ||
return nil, err | ||
} | ||
opts := new(badger.Options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if we just do opts := badger.DefaultOptions
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason, I initially thought badger.DefaultOptions
was a pointer but somewhere I noticed not and left that in, lol. I'll update it, thank you!
db/badger_db.go
Outdated
func (b *BadgerDB) Get(key []byte) []byte { | ||
valueItem := new(badger.KVItem) | ||
if err := b.kv.Get(key, valueItem); err != nil { | ||
// Unfortunate that Get can't return errors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯
db/badger_db.go
Outdated
} | ||
var valueSave []byte | ||
err := valueItem.Value(func(origValue []byte) error { | ||
// TODO: Decide if we should just assign valueSave to origValue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so why can't we just assign?
db/badger_db.go
Outdated
// Hesitant to do DeleteAsync because that changes the | ||
// expected ordering | ||
func (bb *badgerDBBatch) Delete(key []byte) { | ||
bb.db.Delete(key) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no error handling?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 'error handling' present with our structure doesn't return an error yet I am apprehensive about adding panics in Delete.
db/badger_db.go
Outdated
func (bb *badgerDBBatch) Write() { | ||
bb.entriesMu.Lock() | ||
entries := bb.entries | ||
bb.entries = nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if somebody calls set
on this batch after this? code will panic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, after this, it starts a new batch. Take a look at the code in Set https://github.com/tendermint/tmlibs/pull/58/files#diff-9a61ac3e18917559e9062e23d4e9435dR237
or
Cool! Can we base this on Alexis' branch (#57) ? I'd love to see some benchmarks of performance vs our Go LevelDB |
also, tests are failing with a missing dependency error. |
alexis' branch was merged into develop. so this branch needs to be rebased against develop |
Updates #30 Adds a backend for BadgerDB as requested at #30 (comment) and tests for it along. BadgerDB has a few problems: a) It doesn't have a BatchDelete, our fallback is thus Delete because if do DeleteAsync, by the time batch.Write is invoked, we can't be sure that the deletions have ran b) Retrieving values from iterators requires a secondary allocation equal to the length of the current key. See https://godoc.org/github.com/dgraph-io/badger#KV.NewIterator c) It seems to have arbitrary options for the size of the log file varying between 10MB to 2GB. Currently with our DB API, we can't pass in the required file size unless we invoke: ```go db.NewBadgerDBWithOptions(&db.Options{ ValueLogFileSize: desiredFileSize, }) ``` Anyways, I've arbitrarily set the default value log file size to 1GB given that Tendermint does a whole lot of heavy lifting with keyvalue stores <-- cite my sources
db1b5a8
to
ac4290b
Compare
TODO: - IteratorPrefix does not count in prefix - badgerDBIterator#Error should return err from Key() or Value()
ok. I've rebased the PR. @odeke-em could you address some of my comments above and TODO here 2a54ceb. Also, I would love to see benchmarks too #58 (comment) |
I also have a concern that we're adding another dependency (github.com/dgraph-io/badger) to our list of deps, which is already long. Is there a way we could only require it if it's being used? |
|
If we're going to support a bunch of backends and don't want to pull in all the deps, we can do something like:
|
@melekes I mean do we want the DB though? If we do, I don't see how we can avoid adding the dependency. @cloudhead what do you mean by "not pull in all the deps"? By including all those imports, the respective object code has to be compiled and linked. Also I believe we already have that style of registering backends Lines 50 to 64 in d9525c0
|
@melekes thank you for the vets, I'll update them! |
Fixed the code + tests to conform to *vet warnings and also add a getter and setter for badgerDBIterator's lastErr. Thanks to @melekes for the suggestions.
Uncovered dgraph-io/badger#308 which perhaps will require us to use the latest BadgerDB since they no longer use v0.8(which we started with) plus until that issue is resolved, our benchmarks are invalid or spuriously error out.
c4a9fc5
to
dfe935f
Compare
@odeke-em sorry probably wasn't clear: the code snippet I wrote would happen user-side, not in tmlibs. So the user can import additional backends and register them with tmlibs/db. By default, tmlibs/db wouldn't come with any disk-based backends. |
On today's (2018 feb 5th) tendermint dev meeting Bucky mentioned that according to Bucky's and Jae's research, BadgerDB is not mature enough for us to be used. Shall this PR be closed? If not, what's the priority / use case? |
Yeah @greg-szabo in deed, I raised some problems here #58 (comment) and also in the filed issue on BadgerDB dgraph-io/badger#308, their API had drastically changed in the span of 2 weeks, but also that the max length of their keys is 1<<16 dgraph-io/badger#308 (comment). |
Closing this PR. Thanks for the work on it @odeke-em , even though we pass on BadgerDB, it was an important point to raise and discuss it. |
Updates #30
Adds a backend for BadgerDB as requested at
#30 (comment)
and tests for it along.
BadgerDB has a few problems:
a) It doesn't have a BatchDelete, our fallback is thus Delete
because if do DeleteAsync, by the time batch.Write is invoked,
we can't be sure that the deletions have ran
b) Retrieving values from iterators requires a secondary allocation
equal to the length of the current key.
See https://godoc.org/github.com/dgraph-io/badger#KV.NewIterator
c) It seems to have arbitrary options for the size of the
log file varying between 10MB to 2GB. Currently with our
DB API, we can't pass in the required file size unless we
invoke:
Anyways, I've arbitrarily set the default value log file size to 1GB
given that Tendermint does a whole lot of heavy lifting with
keyvalue stores <-- cite my sources