From fbad943cd9cea13235f28b881160e368d74ae6c2 Mon Sep 17 00:00:00 2001 From: Brian Tiger Chow <brian.holderchow@gmail.com> Date: Thu, 12 Feb 2015 09:51:56 -0800 Subject: [PATCH] feat(snrouting): pick remote based on XOR distance metric --- routing/supernode/proxy/standard.go | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/routing/supernode/proxy/standard.go b/routing/supernode/proxy/standard.go index cb458acc2..3e4e2291c 100644 --- a/routing/supernode/proxy/standard.go +++ b/routing/supernode/proxy/standard.go @@ -1,15 +1,15 @@ package proxy import ( - "math/rand" - context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context" ggio "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/io" host "github.com/jbenet/go-ipfs/p2p/host" inet "github.com/jbenet/go-ipfs/p2p/net" peer "github.com/jbenet/go-ipfs/p2p/peer" dhtpb "github.com/jbenet/go-ipfs/routing/dht/pb" + kbucket "github.com/jbenet/go-ipfs/routing/kbucket" eventlog "github.com/jbenet/go-ipfs/thirdparty/eventlog" + "github.com/jbenet/go-ipfs/util" errors "github.com/jbenet/go-ipfs/util/debugerror" ) @@ -25,17 +25,23 @@ type Proxy interface { } type standard struct { - Host host.Host - Remotes []peer.PeerInfo + Host host.Host + + remoteInfos []peer.PeerInfo // addr required for bootstrapping + remoteIDs []peer.ID // []ID is required for each req. here, cached for performance. } func Standard(h host.Host, remotes []peer.PeerInfo) Proxy { - return &standard{h, remotes} + var ids []peer.ID + for _, remote := range remotes { + ids = append(ids, remote.ID) + } + return &standard{h, remotes, ids} } func (px *standard) Bootstrap(ctx context.Context) error { var cxns []peer.PeerInfo - for _, info := range px.Remotes { + for _, info := range px.remoteInfos { if err := px.Host.Connect(ctx, info); err != nil { continue } @@ -60,8 +66,7 @@ func (p *standard) HandleStream(s inet.Stream) { // error. func (px *standard) SendMessage(ctx context.Context, m *dhtpb.Message) error { var err error - for _, i := range rand.Perm(len(px.Remotes)) { - remote := px.Remotes[i].ID + for _, remote := range sortedByKey(px.remoteIDs, m.GetKey()) { if err = px.sendMessage(ctx, m, remote); err != nil { // careful don't re-declare err! continue } @@ -98,8 +103,7 @@ func (px *standard) sendMessage(ctx context.Context, m *dhtpb.Message, remote pe // error. func (px *standard) SendRequest(ctx context.Context, m *dhtpb.Message) (*dhtpb.Message, error) { var err error - for _, i := range rand.Perm(len(px.Remotes)) { - remote := px.Remotes[i].ID + for _, remote := range sortedByKey(px.remoteIDs, m.GetKey()) { var reply *dhtpb.Message reply, err = px.sendRequest(ctx, m, remote) // careful don't redeclare err! if err != nil { @@ -145,3 +149,8 @@ func (px *standard) sendRequest(ctx context.Context, m *dhtpb.Message, remote pe e.Append(eventlog.Pair("uuid", eventlog.Uuid("foo"))) return response, nil } + +func sortedByKey(peers []peer.ID, key string) []peer.ID { + target := kbucket.ConvertKey(util.Key(key)) + return kbucket.SortClosestPeers(peers, target) +} -- GitLab