You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
2.0 KiB
78 lines
2.0 KiB
//go:build !(js && wasm) |
|
|
|
package database |
|
|
|
import ( |
|
"bytes" |
|
|
|
"github.com/dgraph-io/badger/v4" |
|
"lol.mleku.dev/chk" |
|
"next.orly.dev/pkg/database/indexes" |
|
"next.orly.dev/pkg/database/indexes/types" |
|
"next.orly.dev/pkg/interfaces/store" |
|
) |
|
|
|
// GetFullIdPubkeyBySerials seeks directly to each serial's prefix in the |
|
// FullIdPubkey index. The input sers slice is expected to be sorted in |
|
// ascending order, allowing efficient forward-only iteration via a single |
|
// Badger iterator. |
|
func (d *D) GetFullIdPubkeyBySerials(sers []*types.Uint40) ( |
|
fidpks []*store.IdPkTs, err error, |
|
) { |
|
// Pre-allocate slice with exact capacity to reduce reallocations |
|
fidpks = make([]*store.IdPkTs, 0, len(sers)) |
|
if len(sers) == 0 { |
|
return |
|
} |
|
if err = d.View( |
|
func(txn *badger.Txn) (err error) { |
|
// Scope the iterator to the FullIdPubkey table using its 3-byte prefix. |
|
buf := new(bytes.Buffer) |
|
if err = indexes.NewPrefix(indexes.FullIdPubkey).MarshalWrite(buf); chk.E(err) { |
|
return |
|
} |
|
tablePrefix := buf.Bytes() |
|
it := txn.NewIterator(badger.IteratorOptions{Prefix: tablePrefix}) |
|
defer it.Close() |
|
|
|
for _, s := range sers { |
|
if s == nil { |
|
continue |
|
} |
|
// Build the serial-specific prefix: 3-byte table prefix + 5-byte serial. |
|
sbuf := new(bytes.Buffer) |
|
if err = indexes.FullIdPubkeyEnc( |
|
s, nil, nil, nil, |
|
).MarshalWrite(sbuf); chk.E(err) { |
|
return |
|
} |
|
serialPrefix := sbuf.Bytes() |
|
|
|
// Seek to the first key for this serial and verify it matches the prefix. |
|
it.Seek(serialPrefix) |
|
if it.ValidForPrefix(serialPrefix) { |
|
item := it.Item() |
|
key := item.Key() |
|
ser, fid, p, ca := indexes.FullIdPubkeyVars() |
|
if err = indexes.FullIdPubkeyDec( |
|
ser, fid, p, ca, |
|
).UnmarshalRead(bytes.NewBuffer(key)); chk.E(err) { |
|
return |
|
} |
|
fidpks = append( |
|
fidpks, &store.IdPkTs{ |
|
Id: fid.Bytes(), |
|
Pub: p.Bytes(), |
|
Ts: int64(ca.Get()), |
|
Ser: ser.Get(), |
|
}, |
|
) |
|
} |
|
} |
|
return |
|
}, |
|
); chk.E(err) { |
|
return |
|
} |
|
return |
|
}
|
|
|