Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
G
go-ipfs
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
jihao
go-ipfs
Commits
3448b4c1
提交
3448b4c1
authored
2月 05, 2015
作者:
Juan Batiz-Benet
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #746 from jbenet/kbucket-race
routing/kbucket: fix data race
上级
0de13b07
e92a33f4
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
53 行增加
和
51 行删除
+53
-51
bucket.go
routing/kbucket/bucket.go
+16
-12
table.go
routing/kbucket/table.go
+34
-32
table_test.go
routing/kbucket/table_test.go
+3
-7
没有找到文件。
routing/kbucket/bucket.go
浏览文件 @
3448b4c1
...
...
@@ -30,20 +30,20 @@ func (b *Bucket) Peers() []peer.ID {
return
ps
}
func
(
b
*
Bucket
)
find
(
id
peer
.
ID
)
*
list
.
Element
{
func
(
b
*
Bucket
)
Has
(
id
peer
.
ID
)
bool
{
b
.
lk
.
RLock
()
defer
b
.
lk
.
RUnlock
()
for
e
:=
b
.
list
.
Front
();
e
!=
nil
;
e
=
e
.
Next
()
{
if
e
.
Value
.
(
peer
.
ID
)
==
id
{
return
e
return
tru
e
}
}
return
nil
return
false
}
func
(
b
*
Bucket
)
r
emove
(
id
peer
.
ID
)
{
b
.
lk
.
R
Lock
()
defer
b
.
lk
.
R
Unlock
()
func
(
b
*
Bucket
)
R
emove
(
id
peer
.
ID
)
{
b
.
lk
.
Lock
()
defer
b
.
lk
.
Unlock
()
for
e
:=
b
.
list
.
Front
();
e
!=
nil
;
e
=
e
.
Next
()
{
if
e
.
Value
.
(
peer
.
ID
)
==
id
{
b
.
list
.
Remove
(
e
)
...
...
@@ -51,19 +51,23 @@ func (b *Bucket) remove(id peer.ID) {
}
}
func
(
b
*
Bucket
)
moveToFront
(
e
*
list
.
Element
)
{
func
(
b
*
Bucket
)
MoveToFront
(
id
peer
.
ID
)
{
b
.
lk
.
Lock
()
b
.
list
.
MoveToFront
(
e
)
b
.
lk
.
Unlock
()
defer
b
.
lk
.
Unlock
()
for
e
:=
b
.
list
.
Front
();
e
!=
nil
;
e
=
e
.
Next
()
{
if
e
.
Value
.
(
peer
.
ID
)
==
id
{
b
.
list
.
MoveToFront
(
e
)
}
}
}
func
(
b
*
Bucket
)
p
ushFront
(
p
peer
.
ID
)
{
func
(
b
*
Bucket
)
P
ushFront
(
p
peer
.
ID
)
{
b
.
lk
.
Lock
()
b
.
list
.
PushFront
(
p
)
b
.
lk
.
Unlock
()
}
func
(
b
*
Bucket
)
p
opBack
()
peer
.
ID
{
func
(
b
*
Bucket
)
P
opBack
()
peer
.
ID
{
b
.
lk
.
Lock
()
defer
b
.
lk
.
Unlock
()
last
:=
b
.
list
.
Back
()
...
...
@@ -71,7 +75,7 @@ func (b *Bucket) popBack() peer.ID {
return
last
.
Value
.
(
peer
.
ID
)
}
func
(
b
*
Bucket
)
l
en
()
int
{
func
(
b
*
Bucket
)
L
en
()
int
{
b
.
lk
.
RLock
()
defer
b
.
lk
.
RUnlock
()
return
b
.
list
.
Len
()
...
...
routing/kbucket/table.go
浏览文件 @
3448b4c1
...
...
@@ -46,7 +46,7 @@ func NewRoutingTable(bucketsize int, localID ID, latency time.Duration, m peer.M
// 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
.
ID
)
peer
.
ID
{
func
(
rt
*
RoutingTable
)
Update
(
p
peer
.
ID
)
{
rt
.
tabLock
.
Lock
()
defer
rt
.
tabLock
.
Unlock
()
peerID
:=
ConvertPeerID
(
p
)
...
...
@@ -58,33 +58,35 @@ func (rt *RoutingTable) Update(p peer.ID) peer.ID {
}
bucket
:=
rt
.
Buckets
[
bucketID
]
e
:=
bucket
.
find
(
p
)
if
e
==
nil
{
// New peer, add to bucket
if
rt
.
metrics
.
LatencyEWMA
(
p
)
>
rt
.
maxLatency
{
// Connection doesnt meet requirements, skip!
return
""
}
bucket
.
pushFront
(
p
)
// Are we past the max bucket size?
if
bucket
.
len
()
>
rt
.
bucketsize
{
// If this bucket is the rightmost bucket, and its full
// we need to split it and create a new bucket
if
bucketID
==
len
(
rt
.
Buckets
)
-
1
{
return
rt
.
nextBucket
()
}
else
{
// If the bucket cant split kick out least active node
return
bucket
.
popBack
()
}
if
bucket
.
Has
(
p
)
{
// 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
(
p
)
return
}
if
rt
.
metrics
.
LatencyEWMA
(
p
)
>
rt
.
maxLatency
{
// Connection doesnt meet requirements, skip!
return
}
// New peer, add to bucket
bucket
.
PushFront
(
p
)
// Are we past the max bucket size?
if
bucket
.
Len
()
>
rt
.
bucketsize
{
// If this bucket is the rightmost bucket, and its full
// we need to split it and create a new bucket
if
bucketID
==
len
(
rt
.
Buckets
)
-
1
{
rt
.
nextBucket
()
return
}
else
{
// If the bucket cant split kick out least active node
bucket
.
PopBack
()
return
}
return
""
}
// 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
""
}
// Remove deletes a peer from the routing table. This is to be used
...
...
@@ -101,20 +103,20 @@ func (rt *RoutingTable) Remove(p peer.ID) {
}
bucket
:=
rt
.
Buckets
[
bucketID
]
bucket
.
r
emove
(
p
)
bucket
.
R
emove
(
p
)
}
func
(
rt
*
RoutingTable
)
nextBucket
()
peer
.
ID
{
bucket
:=
rt
.
Buckets
[
len
(
rt
.
Buckets
)
-
1
]
newBucket
:=
bucket
.
Split
(
len
(
rt
.
Buckets
)
-
1
,
rt
.
local
)
rt
.
Buckets
=
append
(
rt
.
Buckets
,
newBucket
)
if
newBucket
.
l
en
()
>
rt
.
bucketsize
{
if
newBucket
.
L
en
()
>
rt
.
bucketsize
{
return
rt
.
nextBucket
()
}
// If all elements were on left side of split...
if
bucket
.
l
en
()
>
rt
.
bucketsize
{
return
bucket
.
p
opBack
()
if
bucket
.
L
en
()
>
rt
.
bucketsize
{
return
bucket
.
P
opBack
()
}
return
""
}
...
...
@@ -153,7 +155,7 @@ func (rt *RoutingTable) NearestPeers(id ID, count int) []peer.ID {
bucket
=
rt
.
Buckets
[
cpl
]
var
peerArr
peerSorterArr
if
bucket
.
l
en
()
==
0
{
if
bucket
.
L
en
()
==
0
{
// In the case of an unusual split, one bucket may be empty.
// if this happens, search both surrounding buckets for nearest peer
if
cpl
>
0
{
...
...
@@ -184,7 +186,7 @@ func (rt *RoutingTable) NearestPeers(id ID, count int) []peer.ID {
func
(
rt
*
RoutingTable
)
Size
()
int
{
var
tot
int
for
_
,
buck
:=
range
rt
.
Buckets
{
tot
+=
buck
.
l
en
()
tot
+=
buck
.
L
en
()
}
return
tot
}
...
...
routing/kbucket/table_test.go
浏览文件 @
3448b4c1
...
...
@@ -17,15 +17,14 @@ func TestBucket(t *testing.T) {
peers
:=
make
([]
peer
.
ID
,
100
)
for
i
:=
0
;
i
<
100
;
i
++
{
peers
[
i
]
=
tu
.
RandPeerIDFatal
(
t
)
b
.
p
ushFront
(
peers
[
i
])
b
.
P
ushFront
(
peers
[
i
])
}
local
:=
tu
.
RandPeerIDFatal
(
t
)
localID
:=
ConvertPeerID
(
local
)
i
:=
rand
.
Intn
(
len
(
peers
))
e
:=
b
.
find
(
peers
[
i
])
if
e
==
nil
{
if
!
b
.
Has
(
peers
[
i
])
{
t
.
Errorf
(
"Failed to find peer: %v"
,
peers
[
i
])
}
...
...
@@ -62,10 +61,7 @@ func TestTableUpdate(t *testing.T) {
// Testing Update
for
i
:=
0
;
i
<
10000
;
i
++
{
p
:=
rt
.
Update
(
peers
[
rand
.
Intn
(
len
(
peers
))])
if
p
!=
""
{
//t.Log("evicted peer.")
}
rt
.
Update
(
peers
[
rand
.
Intn
(
len
(
peers
))])
}
for
i
:=
0
;
i
<
100
;
i
++
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论