mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-04-04 01:48:02 +02:00
sdk: use a prefix iterator on kvdb for storing relay urls associated with ids.
This commit is contained in:
parent
e1971d12c0
commit
4cf9631c28
@ -57,3 +57,28 @@ func (s *Store) Delete(key []byte) error {
|
||||
func (s *Store) Close() error {
|
||||
return s.db.Close()
|
||||
}
|
||||
|
||||
func (s *Store) Scan(prefix []byte, fn func(key []byte, value []byte) bool) error {
|
||||
return s.db.View(func(txn *badger.Txn) error {
|
||||
it := txn.NewIterator(badger.DefaultIteratorOptions)
|
||||
defer it.Close()
|
||||
|
||||
for it.Seek(prefix); it.ValidForPrefix(prefix); it.Next() {
|
||||
item := it.Item()
|
||||
err := item.Value(func(v []byte) error {
|
||||
k := item.Key()
|
||||
if !fn(k, v) {
|
||||
return badger.ErrStopIteration
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err == badger.ErrStopIteration {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
@ -13,4 +13,8 @@ type KVStore interface {
|
||||
|
||||
// Close releases any resources held by the store
|
||||
Close() error
|
||||
|
||||
// Scan iterates through all keys with the given prefix.
|
||||
// For each key-value pair, fn is called. If fn returns false, iteration stops.
|
||||
Scan(prefix []byte, fn func(key []byte, value []byte) bool) error
|
||||
}
|
||||
|
@ -90,3 +90,23 @@ func (s *Store) Close() error {
|
||||
s.env.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Store) Scan(prefix []byte, fn func(key []byte, value []byte) bool) error {
|
||||
return s.env.View(func(txn *lmdb.Txn) error {
|
||||
cursor, err := txn.OpenCursor(s.dbi)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cursor.Close()
|
||||
|
||||
for k, v, err := cursor.Get(prefix, nil, lmdb.SetRange); err == nil; k, v, err = cursor.Get(nil, nil, lmdb.Next) {
|
||||
if !bytes.HasPrefix(k, prefix) {
|
||||
break
|
||||
}
|
||||
if !fn(k, v) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
@ -56,3 +56,18 @@ func (s *Store) Close() error {
|
||||
s.data = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Store) Scan(prefix []byte, fn func(key []byte, value []byte) bool) error {
|
||||
s.RLock()
|
||||
defer s.RUnlock()
|
||||
|
||||
prefixStr := string(prefix)
|
||||
for k, v := range s.data {
|
||||
if strings.HasPrefix(k, prefixStr) {
|
||||
if !fn([]byte(k), v) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -139,6 +139,33 @@ func (sys *System) Close() {
|
||||
}
|
||||
}
|
||||
|
||||
// GetEventRelays returns all known relay URLs that have been seen to carry the given event.
|
||||
func (sys *System) GetEventRelays(eventID string) ([]string, error) {
|
||||
// decode the event ID hex into bytes
|
||||
idBytes, err := hex.DecodeString(eventID)
|
||||
if err != nil || len(idBytes) < 8 {
|
||||
return nil, fmt.Errorf("invalid event id")
|
||||
}
|
||||
|
||||
// create prefix for scanning: 'r' + first 8 bytes of event ID
|
||||
prefix := make([]byte, 9)
|
||||
prefix[0] = eventRelayPrefix
|
||||
copy(prefix[1:], idBytes[:8])
|
||||
|
||||
relays := make([]string, 0)
|
||||
err = sys.KVStore.Scan(prefix, func(key []byte, value []byte) bool {
|
||||
// extract relay URL from key (everything after prefix)
|
||||
relay := string(key[9:])
|
||||
relays = append(relays, relay)
|
||||
return true
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return relays, nil
|
||||
}
|
||||
|
||||
func WithHintsDB(hdb hints.HintsDB) SystemModifier {
|
||||
return func(sys *System) {
|
||||
sys.Hints = hdb
|
||||
|
@ -110,6 +110,17 @@ func (sys *System) TrackEventHints(ie nostr.RelayEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
const eventRelayPrefix = byte('r')
|
||||
|
||||
func makeEventRelayKey(eventID []byte, relay string) []byte {
|
||||
// Format: 'r' + first 8 bytes of event ID + relay URL
|
||||
key := make([]byte, 1+8+len(relay))
|
||||
key[0] = eventRelayPrefix
|
||||
copy(key[1:], eventID[:8])
|
||||
copy(key[9:], relay)
|
||||
return key
|
||||
}
|
||||
|
||||
func (sys *System) TrackEventRelays(ie nostr.RelayEvent) {
|
||||
// decode the event ID hex into bytes
|
||||
idBytes, err := hex.DecodeString(ie.ID)
|
||||
@ -117,11 +128,9 @@ func (sys *System) TrackEventRelays(ie nostr.RelayEvent) {
|
||||
return
|
||||
}
|
||||
|
||||
// store only first 8 bytes of event ID as key
|
||||
key := idBytes[:8]
|
||||
|
||||
// store the relay URL as value
|
||||
sys.KVStore.Set(key, []byte(ie.Relay.URL))
|
||||
// store with prefix + eventid + relay format
|
||||
key := makeEventRelayKey(idBytes, ie.Relay.URL)
|
||||
sys.KVStore.Set(key, nil) // value is not needed since relay is in key
|
||||
}
|
||||
|
||||
func (sys *System) TrackEventRelaysD(relay, id string) {
|
||||
@ -131,9 +140,7 @@ func (sys *System) TrackEventRelaysD(relay, id string) {
|
||||
return
|
||||
}
|
||||
|
||||
// store only first 8 bytes of event ID as key
|
||||
key := idBytes[:8]
|
||||
|
||||
// store the relay URL as value
|
||||
sys.KVStore.Set(key, []byte(relay))
|
||||
// store with prefix + eventid + relay format
|
||||
key := makeEventRelayKey(idBytes, relay)
|
||||
sys.KVStore.Set(key, nil) // value is not needed since relay is in key
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user