mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-06-05 12:39:36 +02:00
sdk: wot xor filter has a proper .Contains() function.
This commit is contained in:
parent
1ccd9ba417
commit
f3ef256e65
62
sdk/wot.go
62
sdk/wot.go
@ -8,37 +8,73 @@ import (
|
|||||||
|
|
||||||
"github.com/FastFilter/xorfilter"
|
"github.com/FastFilter/xorfilter"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func PubKeyToShid(pubkey string) uint64 {
|
||||||
|
shid, _ := strconv.ParseUint(pubkey[32:48], 16, 64)
|
||||||
|
return shid
|
||||||
|
}
|
||||||
|
|
||||||
func (sys *System) GetWoT(ctx context.Context, pubkey string) (map[uint64]struct{}, error) {
|
func (sys *System) GetWoT(ctx context.Context, pubkey string) (map[uint64]struct{}, error) {
|
||||||
g, ctx := errgroup.WithContext(ctx)
|
g, ctx := errgroup.WithContext(ctx)
|
||||||
|
g.SetLimit(30)
|
||||||
|
|
||||||
res := make(chan uint64)
|
res := make(chan uint64, 100) // Add buffer to prevent blocking
|
||||||
|
result := make(map[uint64]struct{})
|
||||||
|
var resultMu sync.Mutex // Add mutex to protect map access
|
||||||
|
|
||||||
|
// Start consumer goroutine
|
||||||
|
done := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
defer close(done)
|
||||||
|
for shid := range res {
|
||||||
|
resultMu.Lock()
|
||||||
|
result[shid] = struct{}{}
|
||||||
|
resultMu.Unlock()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Process follow lists
|
||||||
for _, f := range sys.FetchFollowList(ctx, pubkey).Items {
|
for _, f := range sys.FetchFollowList(ctx, pubkey).Items {
|
||||||
|
f := f // Capture loop variable
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
for _, f2 := range sys.FetchFollowList(ctx, f.Pubkey).Items {
|
for _, f2 := range sys.FetchFollowList(ctx, f.Pubkey).Items {
|
||||||
shid, _ := strconv.ParseUint(f2.Pubkey[32:48], 16, 64)
|
select {
|
||||||
res <- shid
|
case res <- PubKeyToShid(f2.Pubkey):
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
result := make(map[uint64]struct{})
|
err := g.Wait()
|
||||||
go func() {
|
close(res) // Close channel after all goroutines are done
|
||||||
for shid := range res {
|
<-done // Wait for consumer to finish
|
||||||
result[shid] = struct{}{}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return result, g.Wait()
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sys *System) GetWoTFilter(ctx context.Context, pubkey string) (*xorfilter.Xor8, error) {
|
func (sys *System) GetWoTFilter(ctx context.Context, pubkey string) (WotXorFilter, error) {
|
||||||
m, err := sys.GetWoT(ctx, pubkey)
|
m, err := sys.GetWoT(ctx, pubkey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return WotXorFilter{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return xorfilter.Populate(slices.Collect(maps.Keys(m)))
|
xf, err := xorfilter.Populate(slices.Collect(maps.Keys(m)))
|
||||||
|
if err != nil {
|
||||||
|
return WotXorFilter{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return WotXorFilter{*xf}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type WotXorFilter struct {
|
||||||
|
xorfilter.Xor8
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wxf WotXorFilter) Contains(pubkey string) bool {
|
||||||
|
return wxf.Xor8.Contains(PubKeyToShid(pubkey))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user