feat(snrouting): pick remote based on XOR distance metric
Brian Tiger Chow committed
Feb 12, 2015 at 09:51 UTC
fbad943cd9cea13235f28b881160e368d74ae6c2
1 file changed
+19
-10
routing/supernode/proxy/standard.go
+19
-10
@@ -1,15 +1,15 @@
1
package proxy
2
3
import (
4
- "math/rand"
5
-
4
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
5
ggio "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/io"
6
host "github.com/jbenet/go-ipfs/p2p/host"
7
inet "github.com/jbenet/go-ipfs/p2p/net"
8
peer "github.com/jbenet/go-ipfs/p2p/peer"
9
dhtpb "github.com/jbenet/go-ipfs/routing/dht/pb"
10
+ kbucket "github.com/jbenet/go-ipfs/routing/kbucket"
11
eventlog "github.com/jbenet/go-ipfs/thirdparty/eventlog"
12
+ "github.com/jbenet/go-ipfs/util"
13
errors "github.com/jbenet/go-ipfs/util/debugerror"
14
)
15
@@ -25,17 +25,23 @@ type Proxy interface {
25
}
26
27
type standard struct {
28
- Host host.Host
29
- Remotes []peer.PeerInfo
28
+ Host host.Host
29
+
30
+ remoteInfos []peer.PeerInfo // addr required for bootstrapping
31
+ remoteIDs []peer.ID // []ID is required for each req. here, cached for performance.
32
}
33
34
func Standard(h host.Host, remotes []peer.PeerInfo) Proxy {
33
- return &standard{h, remotes}
35
+ var ids []peer.ID
36
+ for _, remote := range remotes {
37
+ ids = append(ids, remote.ID)
38
+ }
39
+ return &standard{h, remotes, ids}
40
}
41
42
func (px *standard) Bootstrap(ctx context.Context) error {
43
var cxns []peer.PeerInfo
38
- for _, info := range px.Remotes {
44
+ for _, info := range px.remoteInfos {
45
if err := px.Host.Connect(ctx, info); err != nil {
46
continue
47
}
@@ -60,8 +66,7 @@ func (p *standard) HandleStream(s inet.Stream) {
66
// error.
67
func (px *standard) SendMessage(ctx context.Context, m *dhtpb.Message) error {
68
var err error
63
- for _, i := range rand.Perm(len(px.Remotes)) {
64
- remote := px.Remotes[i].ID
69
+ for _, remote := range sortedByKey(px.remoteIDs, m.GetKey()) {
70
if err = px.sendMessage(ctx, m, remote); err != nil { // careful don't re-declare err!
71
continue
72
}
@@ -98,8 +103,7 @@ func (px *standard) sendMessage(ctx context.Context, m *dhtpb.Message, remote pe
103
// error.
104
func (px *standard) SendRequest(ctx context.Context, m *dhtpb.Message) (*dhtpb.Message, error) {
105
var err error
101
- for _, i := range rand.Perm(len(px.Remotes)) {
102
- remote := px.Remotes[i].ID
106
+ for _, remote := range sortedByKey(px.remoteIDs, m.GetKey()) {
107
var reply *dhtpb.Message
108
reply, err = px.sendRequest(ctx, m, remote) // careful don't redeclare err!
109
if err != nil {
@@ -145,3 +149,8 @@ func (px *standard) sendRequest(ctx context.Context, m *dhtpb.Message, remote pe
149
e.Append(eventlog.Pair("uuid", eventlog.Uuid("foo")))
150
return response, nil
151
}
152
+
153
+func sortedByKey(peers []peer.ID, key string) []peer.ID {
154
+ target := kbucket.ConvertKey(util.Key(key))
155
+ return kbucket.SortClosestPeers(peers, target)
156
+}