Files
nostrlib/eventstore/badger/lib.go
2025-04-15 08:49:28 -03:00

101 lines
2.1 KiB
Go

package badger
import (
"encoding/binary"
"fmt"
"sync/atomic"
"github.com/dgraph-io/badger/v4"
"github.com/fiatjaf/eventstore"
"github.com/nbd-wtf/go-nostr"
)
const (
dbVersionKey byte = 255
rawEventStorePrefix byte = 0
indexCreatedAtPrefix byte = 1
indexIdPrefix byte = 2
indexKindPrefix byte = 3
indexPubkeyPrefix byte = 4
indexPubkeyKindPrefix byte = 5
indexTagPrefix byte = 6
indexTag32Prefix byte = 7
indexTagAddrPrefix byte = 8
)
var _ eventstore.Store = (*BadgerBackend)(nil)
type BadgerBackend struct {
Path string
MaxLimit int
MaxLimitNegentropy int
BadgerOptionsModifier func(badger.Options) badger.Options
// Experimental
SkipIndexingTag func(event *nostr.Event, tagName string, tagValue string) bool
// Experimental
IndexLongerTag func(event *nostr.Event, tagName string, tagValue string) bool
*badger.DB
serial atomic.Uint32
}
func (b *BadgerBackend) Init() error {
opts := badger.DefaultOptions(b.Path)
if b.BadgerOptionsModifier != nil {
opts = b.BadgerOptionsModifier(opts)
}
db, err := badger.Open(opts)
if err != nil {
return err
}
b.DB = db
if err := b.runMigrations(); err != nil {
return fmt.Errorf("error running migrations: %w", err)
}
if b.MaxLimit != 0 {
b.MaxLimitNegentropy = b.MaxLimit
} else {
b.MaxLimit = 1000
if b.MaxLimitNegentropy == 0 {
b.MaxLimitNegentropy = 16777216
}
}
if err := b.DB.View(func(txn *badger.Txn) error {
it := txn.NewIterator(badger.IteratorOptions{
Prefix: []byte{0},
Reverse: true,
})
it.Seek([]byte{1})
if it.Valid() {
key := it.Item().Key()
idx := key[1:]
serial := binary.BigEndian.Uint32(idx)
b.serial.Store(serial)
}
it.Close()
return nil
}); err != nil {
return fmt.Errorf("error initializing serial: %w", err)
}
return nil
}
func (b *BadgerBackend) Close() {
b.DB.Close()
}
func (b *BadgerBackend) Serial() []byte {
next := b.serial.Add(1)
vb := make([]byte, 5)
vb[0] = rawEventStorePrefix
binary.BigEndian.PutUint32(vb[1:], next)
return vb
}