Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
dms3
go-dms3
Commits
35a4086e
Commit
35a4086e
authored
Aug 03, 2014
by
Jeromy
Committed by
Juan Batiz-Benet
Aug 07, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rough kbucket implementation, tests and cleanup to follow
parent
31dc65b9
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
170 additions
and
8 deletions
+170
-8
peer/peer.go
peer/peer.go
+2
-2
routing/dht/routing.go
routing/dht/routing.go
+2
-2
routing/dht/table.go
routing/dht/table.go
+166
-4
No files found.
peer/peer.go
View file @
35a4086e
...
...
@@ -12,8 +12,8 @@ import (
type
ID
mh
.
Multihash
// Utililty function for comparing two peer ID's
func
(
id
*
ID
)
Equal
(
other
*
ID
)
bool
{
return
bytes
.
Equal
(
*
id
,
*
other
)
func
(
id
ID
)
Equal
(
other
ID
)
bool
{
return
bytes
.
Equal
(
id
,
other
)
}
// Map maps Key (string) : *Peer (slices are not comparable).
...
...
routing/dht/routing.go
View file @
35a4086e
...
...
@@ -21,7 +21,7 @@ func GenerateMessageID() uint64 {
// PutValue adds value corresponding to given Key.
func
(
s
*
IpfsDHT
)
PutValue
(
key
u
.
Key
,
value
[]
byte
)
error
{
var
p
*
peer
.
Peer
p
=
s
.
routes
.
Nearest
Node
(
key
)
p
=
s
.
routes
.
Nearest
Peer
(
convertKey
(
key
)
)
pmes_type
:=
DHTMessage_PUT_VALUE
str_key
:=
string
(
key
)
...
...
@@ -44,7 +44,7 @@ func (s *IpfsDHT) PutValue(key u.Key, value []byte) error {
// GetValue searches for the value corresponding to given Key.
func
(
s
*
IpfsDHT
)
GetValue
(
key
u
.
Key
,
timeout
time
.
Duration
)
([]
byte
,
error
)
{
var
p
*
peer
.
Peer
p
=
s
.
routes
.
Nearest
Node
(
key
)
p
=
s
.
routes
.
Nearest
Peer
(
convertKey
(
key
)
)
str_key
:=
string
(
key
)
mes_type
:=
DHTMessage_GET_VALUE
...
...
routing/dht/table.go
View file @
35a4086e
...
...
@@ -3,6 +3,9 @@ package dht
import
(
"bytes"
"container/list"
"sort"
"crypto/sha256"
peer
"github.com/jbenet/go-ipfs/peer"
u
"github.com/jbenet/go-ipfs/util"
...
...
@@ -16,18 +19,177 @@ import (
type
ID
[]
byte
// Bucket holds a list of peers.
type
Bucket
[]
*
list
.
List
type
Bucket
list
.
List
func
(
b
*
Bucket
)
Find
(
id
peer
.
ID
)
*
list
.
Element
{
bucket_list
:=
(
*
list
.
List
)(
b
)
for
e
:=
bucket_list
.
Front
();
e
!=
nil
;
e
=
e
.
Next
()
{
if
e
.
Value
.
(
*
peer
.
Peer
)
.
ID
.
Equal
(
id
)
{
return
e
}
}
return
nil
}
func
(
b
*
Bucket
)
MoveToFront
(
e
*
list
.
Element
)
{
bucket_list
:=
(
*
list
.
List
)(
b
)
bucket_list
.
MoveToFront
(
e
)
}
func
(
b
*
Bucket
)
PushFront
(
p
*
peer
.
Peer
)
{
bucket_list
:=
(
*
list
.
List
)(
b
)
bucket_list
.
PushFront
(
p
)
}
func
(
b
*
Bucket
)
PopBack
()
*
peer
.
Peer
{
bucket_list
:=
(
*
list
.
List
)(
b
)
last
:=
bucket_list
.
Back
()
bucket_list
.
Remove
(
last
)
return
last
.
Value
.
(
*
peer
.
Peer
)
}
func
(
b
*
Bucket
)
Len
()
int
{
bucket_list
:=
(
*
list
.
List
)(
b
)
return
bucket_list
.
Len
()
}
func
(
b
*
Bucket
)
Split
(
cpl
int
,
target
ID
)
*
Bucket
{
bucket_list
:=
(
*
list
.
List
)(
b
)
out
:=
list
.
New
()
e
:=
bucket_list
.
Front
()
for
e
!=
nil
{
peer_id
:=
convertPeerID
(
e
.
Value
.
(
*
peer
.
Peer
)
.
ID
)
peer_cpl
:=
xor
(
peer_id
,
target
)
.
commonPrefixLen
()
if
peer_cpl
>
cpl
{
cur
:=
e
out
.
PushBack
(
e
.
Value
)
e
=
e
.
Next
()
bucket_list
.
Remove
(
cur
)
continue
}
}
return
(
*
Bucket
)(
out
)
}
// RoutingTable defines the routing table.
type
RoutingTable
struct
{
// ID of the local peer
local
ID
// kBuckets define all the fingers to other nodes.
Buckets
[]
Bucket
Buckets
[]
*
Bucket
bucketsize
int
}
func
convertPeerID
(
id
peer
.
ID
)
ID
{
hash
:=
sha256
.
Sum256
(
id
)
return
hash
[
:
]
}
func
convertKey
(
id
u
.
Key
)
ID
{
hash
:=
sha256
.
Sum256
([]
byte
(
id
))
return
hash
[
:
]
}
// Update adds or moves the given peer to the front of its respective bucket
// If a peer gets removed from a bucket, it is returned
func
(
rt
*
RoutingTable
)
Update
(
p
*
peer
.
Peer
)
*
peer
.
Peer
{
peer_id
:=
convertPeerID
(
p
.
ID
)
cpl
:=
xor
(
peer_id
,
rt
.
local
)
.
commonPrefixLen
()
b_id
:=
cpl
if
b_id
>=
len
(
rt
.
Buckets
)
{
b_id
=
len
(
rt
.
Buckets
)
-
1
}
bucket
:=
rt
.
Buckets
[
b_id
]
e
:=
bucket
.
Find
(
p
.
ID
)
if
e
==
nil
{
// New peer, add to bucket
bucket
.
PushFront
(
p
)
// Are we past the max bucket size?
if
bucket
.
Len
()
>
rt
.
bucketsize
{
if
b_id
==
len
(
rt
.
Buckets
)
-
1
{
new_bucket
:=
bucket
.
Split
(
b_id
,
rt
.
local
)
rt
.
Buckets
=
append
(
rt
.
Buckets
,
new_bucket
)
// If all elements were on left side of split...
if
bucket
.
Len
()
>
rt
.
bucketsize
{
return
bucket
.
PopBack
()
}
}
else
{
// If the bucket cant split kick out least active node
return
bucket
.
PopBack
()
}
}
return
nil
}
else
{
// If the peer is already in the table, move it to the front.
// This signifies that it it "more active" and the less active nodes
// Will as a result tend towards the back of the list
bucket
.
MoveToFront
(
e
)
return
nil
}
}
// A helper struct to sort peers by their distance to the local node
type
peerDistance
struct
{
p
*
peer
.
Peer
distance
ID
}
type
peerSorterArr
[]
*
peerDistance
func
(
p
peerSorterArr
)
Len
()
int
{
return
len
(
p
)}
func
(
p
peerSorterArr
)
Swap
(
a
,
b
int
)
{
p
[
a
],
p
[
b
]
=
p
[
b
],
p
[
a
]}
func
(
p
peerSorterArr
)
Less
(
a
,
b
int
)
bool
{
return
p
[
a
]
.
distance
.
Less
(
p
[
b
])
}
//
func
(
rt
*
RoutingTable
)
NearestPeer
(
id
ID
)
*
peer
.
Peer
{
peers
:=
rt
.
NearestPeers
(
id
,
1
)
return
peers
[
0
]
}
//TODO: make this accept an ID, requires method of converting keys to IDs
func
(
rt
*
RoutingTable
)
NearestNode
(
key
u
.
Key
)
*
peer
.
Peer
{
panic
(
"Function not implemented."
)
func
(
rt
*
RoutingTable
)
NearestPeers
(
id
ID
,
count
int
)
[]
*
peer
.
Peer
{
cpl
:=
xor
(
id
,
rt
.
local
)
.
commonPrefixLen
()
// Get bucket at cpl index or last bucket
var
bucket
*
Bucket
if
cpl
>=
len
(
rt
.
Buckets
)
{
bucket
=
rt
.
Buckets
[
len
(
rt
.
Buckets
)
-
1
]
}
else
{
bucket
=
rt
.
Buckets
[
cpl
]
}
if
bucket
.
Len
()
==
0
{
// This can happen, very rarely.
panic
(
"Case not yet implemented."
)
}
var
peerArr
peerSorterArr
plist
:=
(
*
list
.
List
)(
bucket
)
for
e
:=
plist
.
Front
();
e
!=
nil
;
e
=
e
.
Next
()
{
p
:=
e
.
Value
.
(
*
peer
.
Peer
)
p_id
:=
convertPeerID
(
p
.
ID
)
pd
:=
peerDistance
{
p
:
p
,
distance
:
xor
(
rt
.
local
,
p_id
),
}
peerArr
=
append
(
peerArr
,
&
pd
)
}
sort
.
Sort
(
peerArr
)
var
out
[]
*
peer
.
Peer
for
i
:=
0
;
i
<
count
&&
i
<
peerArr
.
Len
();
i
++
{
out
=
append
(
out
,
peerArr
[
i
]
.
p
)
}
return
out
}
func
(
id
ID
)
Equal
(
other
ID
)
bool
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment