FinalCommander/content/database.go
DataHoarder 73c2443d25
All checks were successful
continuous-integration/drone/push Build is passing
Update to go 1.18, added Garbage collection for badger
2022-02-08 18:29:15 +01:00

111 lines
2.1 KiB
Go

package content
import (
"fmt"
"github.com/dgraph-io/badger/v3"
"time"
)
type Database struct {
handle *badger.DB
closeChannel chan bool
gcTicker *time.Ticker
}
func OpenDatabase(path string) (*Database, error) {
opts := badger.DefaultOptions(path)
opts.IndexCacheSize = 256 << 20 //256 MiB, TODO check relative to keys
db, err := badger.Open(opts)
if err != nil {
return nil, err
}
database := &Database{
handle: db,
gcTicker: time.NewTicker(time.Minute * 5),
closeChannel: make(chan bool),
}
go func() {
defer database.gcTicker.Stop()
for {
select {
case <-database.gcTicker.C:
for database.handle.RunValueLogGC(0.5) == nil {
}
case <-database.closeChannel:
return
}
}
}()
return database, nil
}
func (db *Database) GetEntry(key HashIdentifier) *Entry {
var entry *Entry
err := db.handle.View(func(txn *badger.Txn) error {
var err error
entry, err = db.getChain(txn, key)
return err
})
if err != nil {
return nil
}
return entry
}
func (db *Database) SetAlias(alias *Alias) error {
return db.handle.Update(func(txn *badger.Txn) error {
return txn.Set(alias.Key.Encode(), alias.Encode())
})
}
func (db *Database) SetEntry(entry *Entry) error {
return db.handle.Update(func(txn *badger.Txn) error {
b, err := entry.Encode()
if err != nil {
return err
}
return txn.Set(entry.Key.Encode(), b)
})
}
func (db *Database) RemoveEntry(key *HashIdentifier) error {
return db.handle.Update(func(txn *badger.Txn) error {
return txn.Delete(key.Encode())
})
}
func (db *Database) getChain(txn *badger.Txn, key HashIdentifier) (*Entry, error) {
item, err := txn.Get(key.Encode())
if err != nil {
return nil, err
}
var entry *Entry
err = item.Value(func(val []byte) error {
if key.IsKey() {
entry = DecodeEntry(key, val)
return nil
} else {
alias := DecodeAlias(key, val)
if alias == nil {
return fmt.Errorf("could not decode alias %x", key.Encode())
}
entry, err = db.getChain(txn, alias.Identifier)
return err
}
})
return entry, err
}
func (db *Database) Close() error {
db.closeChannel <- true
return db.handle.Close()
}