I have implemented the levigo wrapper in my project so I can use LevelDB. The declaration is fairly boilerplate, like so:
func NewLeveldbStorage(dbPath string) *leveldbStorage {
opts := levigo.NewOptions()
opts.SetCache(levigo.NewLRUCache(3<<30))
opts.SetCreateIfMissing(true)
log.Debugf("Entering Open")
db, err := levigo.Open(dbPath, opts); if err != nil {
log.Fatal("BOOM %v", err)
}
log.Debugf("Finished calling open")
opts.Close()
return &leveldbStorage{db:db}
}
Here is the struct returned:
type leveldbStorage struct {
db *levigo.DB
}
I then made a few simple GET and STORE commands on the struct that essentially just use s.db.Get
and s.db.Put
. This works fine in my tests, but when I run the following benchmark:
func BenchmarkLeviDbGet(b *testing.B) {
s := storage.NewLeveldbStorage("/path/to/db")
value := "value"
uid,_ := s.Store(value)
b.ResetTimer()
for i := 0; i < b.N; i++ {
s.Get(uid)
}
This benchmark, when run, returns:
2014/10/12 21:17:09 BOOM %vIO error: lock /path/to/db/LOCK: already held by process
Is there an appropriate way to use levigo/leveldb to enable multithreaded reading? What about writing? I would not be surprised if multithreaded writing is not possible, but multithreaded reading seems like it should be. What am I doing wrong here?
You either need to close the database file or use a global instance to it, you can't open the file multiple times, you can however access the same instance from multiple goroutines.