Skip to content
Snippets Groups Projects
Commit 588e0fff authored by Wolfgang Welz's avatar Wolfgang Welz
Browse files

Fix: race condition in Database.Get

parent 36d86d60
No related branches found
No related tags found
No related merge requests found
...@@ -10,22 +10,19 @@ var dbMap = make(map[string]*prefixDb) ...@@ -10,22 +10,19 @@ var dbMap = make(map[string]*prefixDb)
var mu sync.Mutex var mu sync.Mutex
type prefixDb struct { type prefixDb struct {
db *badger.DB db *badger.DB
name string name string
prefix []byte prefix []byte
openLock sync.Mutex
} }
func Get(name string) (Database, error) { func getPrefix(name string) []byte {
// avoid locking if it's a clean hit return []byte(name + "_")
if db, exists := dbMap[name]; exists { }
return db, nil
}
func Get(name string) (Database, error) {
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
// needs to be re-checked after locking
if db, exists := dbMap[name]; exists { if db, exists := dbMap[name]; exists {
return db, nil return db, nil
} }
...@@ -34,7 +31,7 @@ func Get(name string) (Database, error) { ...@@ -34,7 +31,7 @@ func Get(name string) (Database, error) {
db := &prefixDb{ db := &prefixDb{
db: badger, db: badger,
name: name, name: name,
prefix: []byte(name + "_"), prefix: getPrefix(name),
} }
dbMap[name] = db dbMap[name] = db
...@@ -43,21 +40,16 @@ func Get(name string) (Database, error) { ...@@ -43,21 +40,16 @@ func Get(name string) (Database, error) {
} }
func (this *prefixDb) Set(key []byte, value []byte) error { func (this *prefixDb) Set(key []byte, value []byte) error {
if err := this.db.Update(func(txn *badger.Txn) error { return txn.Set(append(this.prefix, key...), value) }); err != nil { err := this.db.Update(func(txn *badger.Txn) error {
return err return txn.Set(append(this.prefix, key...), value)
} })
return err
return nil
} }
func (this *prefixDb) Contains(key []byte) (bool, error) { func (this *prefixDb) Contains(key []byte) (bool, error) {
err := this.db.View(func(txn *badger.Txn) error { err := this.db.View(func(txn *badger.Txn) error {
_, err := txn.Get(append(this.prefix, key...)) _, err := txn.Get(append(this.prefix, key...))
if err != nil { return err
return err
}
return nil
}) })
if err == badger.ErrKeyNotFound { if err == badger.ErrKeyNotFound {
...@@ -88,8 +80,7 @@ func (this *prefixDb) Get(key []byte) ([]byte, error) { ...@@ -88,8 +80,7 @@ func (this *prefixDb) Get(key []byte) ([]byte, error) {
func (this *prefixDb) Delete(key []byte) error { func (this *prefixDb) Delete(key []byte) error {
err := this.db.Update(func(txn *badger.Txn) error { err := this.db.Update(func(txn *badger.Txn) error {
err := txn.Delete(append(this.prefix, key...)) return txn.Delete(append(this.prefix, key...))
return err
}) })
return err return err
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment