get-fullidpubkey-by-serials.go raw
1 //go:build !(js && wasm)
2
3 package database
4
5 import (
6 "bytes"
7
8 "github.com/dgraph-io/badger/v4"
9 "next.orly.dev/pkg/lol/chk"
10 "next.orly.dev/pkg/database/indexes"
11 "next.orly.dev/pkg/database/indexes/types"
12 "next.orly.dev/pkg/interfaces/store"
13 )
14
15 // GetFullIdPubkeyBySerials seeks directly to each serial's prefix in the
16 // FullIdPubkey index. The input sers slice is expected to be sorted in
17 // ascending order, allowing efficient forward-only iteration via a single
18 // Badger iterator.
19 func (d *D) GetFullIdPubkeyBySerials(sers []*types.Uint40) (
20 fidpks []*store.IdPkTs, err error,
21 ) {
22 // Pre-allocate slice with exact capacity to reduce reallocations
23 fidpks = make([]*store.IdPkTs, 0, len(sers))
24 if len(sers) == 0 {
25 return
26 }
27 if err = d.View(
28 func(txn *badger.Txn) (err error) {
29 // Scope the iterator to the FullIdPubkey table using its 3-byte prefix.
30 buf := new(bytes.Buffer)
31 if err = indexes.NewPrefix(indexes.FullIdPubkey).MarshalWrite(buf); chk.E(err) {
32 return
33 }
34 tablePrefix := buf.Bytes()
35 it := txn.NewIterator(badger.IteratorOptions{Prefix: tablePrefix})
36 defer it.Close()
37
38 for _, s := range sers {
39 if s == nil {
40 continue
41 }
42 // Build the serial-specific prefix: 3-byte table prefix + 5-byte serial.
43 sbuf := new(bytes.Buffer)
44 if err = indexes.FullIdPubkeyEnc(
45 s, nil, nil, nil,
46 ).MarshalWrite(sbuf); chk.E(err) {
47 return
48 }
49 serialPrefix := sbuf.Bytes()
50
51 // Seek to the first key for this serial and verify it matches the prefix.
52 it.Seek(serialPrefix)
53 if it.ValidForPrefix(serialPrefix) {
54 item := it.Item()
55 key := item.Key()
56 ser, fid, p, ca := indexes.FullIdPubkeyVars()
57 if err = indexes.FullIdPubkeyDec(
58 ser, fid, p, ca,
59 ).UnmarshalRead(bytes.NewBuffer(key)); chk.E(err) {
60 return
61 }
62 idpkts := store.NewIdPkTs(
63 fid.Bytes(),
64 p.Bytes(),
65 int64(ca.Get()),
66 ser.Get(),
67 )
68 fidpks = append(fidpks, &idpkts)
69 }
70 }
71 return
72 },
73 ); chk.E(err) {
74 return
75 }
76 return
77 }
78