Skip to content
Snippets Groups Projects
Commit 3adb203d authored by Hans Moog's avatar Hans Moog
Browse files

Feat: changed database to use a single badger instance with prefixes

parent a0c10851
No related branches found
No related tags found
No related merge requests found
package database
import (
"os"
"sync"
"github.com/dgraph-io/badger"
"github.com/dgraph-io/badger/options"
)
var instance *badger.DB
var openLock sync.Mutex
func GetBadgerInstance() (result *badger.DB, err error) {
openLock.Lock()
if instance == nil {
directory := *DIRECTORY.Value
if _, osErr := os.Stat(directory); osErr != nil {
err = osErr
return
} else if os.IsNotExist(err) {
if osErr := os.Mkdir(directory, 0700); osErr != nil {
err = osErr
return
}
}
opts := badger.DefaultOptions(directory)
opts.Logger = &logger{}
opts.Truncate = true
opts.TableLoadingMode = options.MemoryMap
db, badgerErr := badger.Open(opts)
if err != nil {
err = badgerErr
return
}
instance = db
}
openLock.Unlock()
result = instance
return
}
package database package database
import ( import (
"os"
"path/filepath"
"sync" "sync"
"github.com/dgraph-io/badger" "github.com/dgraph-io/badger"
"github.com/dgraph-io/badger/options"
) )
var databasesByName = make(map[string]*databaseImpl) var databasesByName = make(map[string]*databaseImpl)
...@@ -17,6 +14,7 @@ var ErrKeyNotFound = badger.ErrKeyNotFound ...@@ -17,6 +14,7 @@ var ErrKeyNotFound = badger.ErrKeyNotFound
type databaseImpl struct { type databaseImpl struct {
db *badger.DB db *badger.DB
name string name string
prefix []byte
openLock sync.Mutex openLock sync.Mutex
} }
...@@ -28,50 +26,24 @@ func Get(name string) (Database, error) { ...@@ -28,50 +26,24 @@ func Get(name string) (Database, error) {
return database, nil return database, nil
} }
database := &databaseImpl{ badgerInstance, err := GetBadgerInstance()
db: nil, if err != nil {
name: name,
}
if err := database.Open(); err != nil {
return nil, err return nil, err
} }
database := &databaseImpl{
db: badgerInstance,
name: name,
prefix: []byte(name + "_"),
}
databasesByName[name] = database databasesByName[name] = database
return databasesByName[name], nil return databasesByName[name], nil
} }
func (this *databaseImpl) Open() error {
this.openLock.Lock()
defer this.openLock.Unlock()
if this.db == nil {
directory := *DIRECTORY.Value
if _, err := os.Stat(directory); os.IsNotExist(err) {
if err := os.Mkdir(directory, 0700); err != nil {
return err
}
}
opts := badger.DefaultOptions(filepath.Join(directory, this.name))
opts.Logger = &logger{}
opts.Truncate = true
opts.TableLoadingMode = options.MemoryMap
db, err := badger.Open(opts)
if err != nil {
return err
}
this.db = db
}
return nil
}
func (this *databaseImpl) Set(key []byte, value []byte) error { func (this *databaseImpl) Set(key []byte, value []byte) error {
if err := this.db.Update(func(txn *badger.Txn) error { return txn.Set(key, value) }); err != nil { if err := this.db.Update(func(txn *badger.Txn) error { return txn.Set(append(this.prefix, key...), value) }); err != nil {
return err return err
} }
...@@ -80,7 +52,7 @@ func (this *databaseImpl) Set(key []byte, value []byte) error { ...@@ -80,7 +52,7 @@ func (this *databaseImpl) Set(key []byte, value []byte) error {
func (this *databaseImpl) Contains(key []byte) (bool, error) { func (this *databaseImpl) 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(key) _, err := txn.Get(append(this.prefix, key...))
if err != nil { if err != nil {
return err return err
} }
...@@ -99,7 +71,7 @@ func (this *databaseImpl) Get(key []byte) ([]byte, error) { ...@@ -99,7 +71,7 @@ func (this *databaseImpl) Get(key []byte) ([]byte, error) {
var result []byte = nil var result []byte = nil
err := this.db.View(func(txn *badger.Txn) error { err := this.db.View(func(txn *badger.Txn) error {
item, err := txn.Get(key) item, err := txn.Get(append(this.prefix, key...))
if err != nil { if err != nil {
return err return err
} }
...@@ -116,7 +88,7 @@ func (this *databaseImpl) Get(key []byte) ([]byte, error) { ...@@ -116,7 +88,7 @@ func (this *databaseImpl) Get(key []byte) ([]byte, error) {
func (this *databaseImpl) Delete(key []byte) error { func (this *databaseImpl) 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(key) err := txn.Delete(append(this.prefix, key...))
return err return err
}) })
return err return err
...@@ -124,8 +96,11 @@ func (this *databaseImpl) Delete(key []byte) error { ...@@ -124,8 +96,11 @@ func (this *databaseImpl) Delete(key []byte) error {
func (this *databaseImpl) ForEach(consumer func([]byte, []byte)) error { func (this *databaseImpl) ForEach(consumer func([]byte, []byte)) error {
err := this.db.View(func(txn *badger.Txn) error { err := this.db.View(func(txn *badger.Txn) error {
iteratorOptions := badger.DefaultIteratorOptions
iteratorOptions.Prefix = this.prefix
// create an iterator the default options // create an iterator the default options
it := txn.NewIterator(badger.DefaultIteratorOptions) it := txn.NewIterator(iteratorOptions)
defer it.Close() defer it.Close()
// loop through every key-value-pair and call the function // loop through every key-value-pair and call the function
...@@ -137,26 +112,9 @@ func (this *databaseImpl) ForEach(consumer func([]byte, []byte)) error { ...@@ -137,26 +112,9 @@ func (this *databaseImpl) ForEach(consumer func([]byte, []byte)) error {
return err return err
} }
consumer(item.Key(), value) consumer(item.Key()[len(this.prefix):], value)
} }
return nil return nil
}) })
return err return err
} }
func (this *databaseImpl) Close() error {
this.openLock.Lock()
defer this.openLock.Unlock()
if this.db != nil {
err := this.db.Close()
this.db = nil
if err != nil {
return err
}
}
return nil
}
package database package database
type Database interface { type Database interface {
Open() error
Set(key []byte, value []byte) error Set(key []byte, value []byte) error
Contains(key []byte) (bool, error) Contains(key []byte) (bool, error)
Get(key []byte) ([]byte, error) Get(key []byte) ([]byte, error)
ForEach(func(key []byte, value []byte)) error ForEach(func(key []byte, value []byte)) error
Delete(key []byte) error Delete(key []byte) error
Close() error
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment