Files
nostrlib/eventstore/badger/delete.go

86 lines
2.0 KiB
Go

package badger
import (
"fmt"
"log"
"fiatjaf.com/nostr"
"fiatjaf.com/nostr/eventstore/codec/betterbinary"
"github.com/dgraph-io/badger/v4"
)
var serialDelete uint32 = 0
func (b *BadgerBackend) DeleteEvent(id nostr.ID) error {
fmt.Println("...", id)
deletionHappened := false
err := b.Update(func(txn *badger.Txn) error {
var err error
deletionHappened, err = b.delete(txn, id)
return err
})
if err != nil {
return err
}
// after deleting, run garbage collector (sometimes)
if deletionHappened {
serialDelete = (serialDelete + 1) % 256
if serialDelete == 0 {
if err := b.RunValueLogGC(0.8); err != nil && err != badger.ErrNoRewrite {
log.Println("badger gc errored:" + err.Error())
}
}
}
return nil
}
func (b *BadgerBackend) delete(txn *badger.Txn, id nostr.ID) (bool, error) {
idx := make([]byte, 1, 5)
idx[0] = rawEventStorePrefix
// query event by id to get its idx
prefix := make([]byte, 1+8)
prefix[0] = indexIdPrefix
copy(prefix[1:], id[0:8])
opts := badger.IteratorOptions{
PrefetchValues: false,
}
// also grab the actual event so we can calculate its indexes
var evt nostr.Event
it := txn.NewIterator(opts)
defer it.Close()
it.Seek(prefix)
if it.ValidForPrefix(prefix) {
idx = append(idx, it.Item().Key()[1+8:1+8+4]...)
item, err := txn.Get(idx)
if err == badger.ErrKeyNotFound {
// this event doesn't exist or is already deleted
return false, nil
} else if err != nil {
return false, fmt.Errorf("failed to fetch event %x to delete: %w", id[:], err)
} else {
if err := item.Value(func(bin []byte) error {
return betterbinary.Unmarshal(bin, &evt)
}); err != nil {
return false, fmt.Errorf("failed to unmarshal event %x to delete: %w", id[:], err)
}
}
}
// calculate all index keys we have for this event and delete them
for k := range b.getIndexKeysForEvent(evt, idx[1:]) {
if err := txn.Delete(k); err != nil {
return false, err
}
}
// delete the raw event
return true, txn.Delete(idx)
}