62 lines
1.3 KiB
Go
62 lines
1.3 KiB
Go
package bolt
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/binary"
|
|
"log"
|
|
|
|
"github.com/nbd-wtf/go-nostr"
|
|
nostr_binary "github.com/nbd-wtf/go-nostr/binary"
|
|
bolt "go.etcd.io/bbolt"
|
|
)
|
|
|
|
func (b *BoltBackend) CountEvents(ctx context.Context, filter nostr.Filter) (int64, error) {
|
|
var count int64 = 0
|
|
|
|
queries, extraFilter, since, err := prepareQueries(filter)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
err = b.db.View(func(txn *bolt.Tx) error {
|
|
// actually iterate
|
|
for _, q := range queries {
|
|
bucket := txn.Bucket(q.bucket)
|
|
raw := txn.Bucket(bucketRaw)
|
|
|
|
c := bucket.Cursor()
|
|
for k, v := c.Seek(q.startingPoint); k != nil && bytes.HasPrefix(k, q.prefix); k, v = c.Prev() {
|
|
// "id" indexes don't contain a timestamp
|
|
if !q.skipTimestamp {
|
|
createdAt := binary.BigEndian.Uint32(k[len(k)-4:])
|
|
if createdAt < since {
|
|
break
|
|
}
|
|
}
|
|
|
|
if extraFilter == nil {
|
|
count++
|
|
} else {
|
|
// fetch actual event
|
|
val := raw.Get(v)
|
|
evt := &nostr.Event{}
|
|
if err := nostr_binary.Unmarshal(val, evt); err != nil {
|
|
log.Printf("bolt: value read error (id %x): %s\n", val[0:32], err)
|
|
break
|
|
}
|
|
|
|
// check if this matches the other filters that were not part of the index before yielding
|
|
if extraFilter.Matches(evt) {
|
|
count++
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
return count, err
|
|
}
|