Merge pull request #141 from pymq/fix_update_addrbook_loop

Fix perfomance issue in updating addr book
This commit is contained in:
Steven Allen 2021-07-20 17:35:56 -07:00 committed by GitHub
commit f7f22569f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -7,14 +7,13 @@ import (
"sync" "sync"
"time" "time"
"github.com/libp2p/go-libp2p-core/record"
ds "github.com/ipfs/go-datastore" ds "github.com/ipfs/go-datastore"
"github.com/ipfs/go-datastore/query" "github.com/ipfs/go-datastore/query"
logging "github.com/ipfs/go-log" logging "github.com/ipfs/go-log"
"github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peer"
pstore "github.com/libp2p/go-libp2p-core/peerstore" pstore "github.com/libp2p/go-libp2p-core/peerstore"
"github.com/libp2p/go-libp2p-core/record"
pb "github.com/libp2p/go-libp2p-peerstore/pb" pb "github.com/libp2p/go-libp2p-peerstore/pb"
"github.com/libp2p/go-libp2p-peerstore/pstoremem" "github.com/libp2p/go-libp2p-peerstore/pstoremem"
@ -453,6 +452,10 @@ func (ab *dsAddrBook) ClearAddrs(p peer.ID) {
} }
func (ab *dsAddrBook) setAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration, mode ttlWriteMode, signed bool) (err error) { func (ab *dsAddrBook) setAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration, mode ttlWriteMode, signed bool) (err error) {
if len(addrs) == 0 {
return nil
}
pr, err := ab.loadRecord(p, true, false) pr, err := ab.loadRecord(p, true, false)
if err != nil { if err != nil {
return fmt.Errorf("failed to load peerstore entry for peer %v while setting addrs, err: %v", p, err) return fmt.Errorf("failed to load peerstore entry for peer %v while setting addrs, err: %v", p, err)
@ -467,36 +470,37 @@ func (ab *dsAddrBook) setAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duratio
// } // }
newExp := time.Now().Add(ttl).Unix() newExp := time.Now().Add(ttl).Unix()
// TODO this is very inefficient O(m*n); we could build a map to use as an addrsMap := make(map[string]*pb.AddrBookRecord_AddrEntry, len(pr.Addrs))
// index, and test against it. That would turn it into O(m+n). This code for _, addr := range pr.Addrs {
// will be refactored entirely anyway, and it's not being used by users addrsMap[string(addr.Addr.Bytes())] = addr
// (that we know of); so OK to keep it for now. }
updateExisting := func(entryList []*pb.AddrBookRecord_AddrEntry, incoming ma.Multiaddr) *pb.AddrBookRecord_AddrEntry {
for _, have := range entryList { updateExisting := func(incoming ma.Multiaddr) *pb.AddrBookRecord_AddrEntry {
if incoming.Equal(have.Addr) { existingEntry := addrsMap[string(incoming.Bytes())]
switch mode { if existingEntry == nil {
case ttlOverride: return nil
have.Ttl = int64(ttl)
have.Expiry = newExp
case ttlExtend:
if int64(ttl) > have.Ttl {
have.Ttl = int64(ttl)
}
if newExp > have.Expiry {
have.Expiry = newExp
}
default:
panic("BUG: unimplemented ttl mode")
}
return have
}
} }
return nil
switch mode {
case ttlOverride:
existingEntry.Ttl = int64(ttl)
existingEntry.Expiry = newExp
case ttlExtend:
if int64(ttl) > existingEntry.Ttl {
existingEntry.Ttl = int64(ttl)
}
if newExp > existingEntry.Expiry {
existingEntry.Expiry = newExp
}
default:
panic("BUG: unimplemented ttl mode")
}
return existingEntry
} }
var entries []*pb.AddrBookRecord_AddrEntry var entries []*pb.AddrBookRecord_AddrEntry
for _, incoming := range addrs { for _, incoming := range addrs {
existingEntry := updateExisting(pr.Addrs, incoming) existingEntry := updateExisting(incoming)
if existingEntry == nil { if existingEntry == nil {
// if signed { // if signed {