ZBLOG

package main import ( "bytes" "crypto/sha1" ) const ( BucketSize = 3 IdSize = 20 PeerCount = 100 // 每个节点中包含的Peer数量 BucketNum = 160 // 每个DHT结构体中桶的数量 ) type Node struct { id [IdSize]byte data string } type Bucket

func (p *Peer) GetValue(key []byte) ([]byte, bool) {

hashedKey := sha1.Sum(key)
if !bytes.Equal(hashedKey[:], p.node.id[:]) { // 如果当前节点不是key对应的节点,则继续查找更接近目标id的其他节点。
	targetId := sha1.Sum(key)
	closestPeers := make([]Peer, 0, PeerCount2)
	closestPeers = append(closestPeers, p.neighbors...)
	closestPeers = p.dht.findClosestPeers(targetId, PeerCount-len(p.neighbors), closestPeers)
	for _, peer := range closestPeers {
		value, ok := peer.GetValue(key) // 递归调用GetValue函数,在最近的num个节点中查找键值对。
		if ok {
			return value, true
		}
	}
	return nil, false // 所有最近的num个节点都没有找到该键值对,返回false。
}
if value, ok := p.values[string(key)]; ok { // 如果当前节点包含该键值对,则返回其对应的value和true。
	return value, true
}
return nil, false // 当前节点中不存在该键值对,返回false。

}

// 将自身添加到距离目标id更近的某个Peer的邻居列表中,并将该Peer添加到自己的邻居列表中。 func (p *Peer) addNeighbor(peer *Peer) {

if len(p.neighbors) < 2 { // 如果邻居数量小于2,则直接添加到邻居列表中并返回。
	p.neighbors = append(p.neighbors, peer)
	return
}
if p.neighbors[0].node.id == peer.node.id || p.neighbors[1].node.id == peer.node.id { // 如果该节点已经是当前节点的邻居,则直接返回。
	return
}
targetId := peer.node.id
selfDist := distance(selfNodeId, targetId)
neighborDist1 := distance(p.neighbors[0].node.id, targetId)
neighborDist2 := distance(p.neighbors[1].node.id, targetId)
if selfDist < neighborDist1 && selfDist < neighborDist2 { // 如果当前节点离目标id更近,则将其添加到peer的邻居列表中,并将peer添加到自己的邻居列表中。
	peer.addNeighbor(p)
	p.neighbors = append(p.neighbors[:], peer)
} else if neighborDist1 < neighborDist2 { // 否则,选择距离目标id更近的邻居节点,将其替换为新节点。
	p.neighbors[0] = peer
} else {
	p.neighbors[1] = peer
}

}

// 将指定Peer从邻居列表中移除。 func (p *Peer) removeNeighbor(peer *Peer) {

for i, n := range p.neighbors {
	if n.node.id == peer.node.id {
		copy(p.neighbors[i:], p.neighbors[i+1:])
		p.neighbors[len(p.neighbors)-1] = nil
		p.neighbors = p.neighbors[:len(p.neighbors)-1]
		break
	}
}

}

// 找到包含指定ID的桶,并从其中删除指定ID的节点。如果找不到对应的桶或者未找到对应的节点,则返回false。 func (dht *DHT) removeNode(id [IdSize]byte) bool {

bucketPos := distance(selfNodeId, id)
bucket := dht.getBucket(bucketPos)
if bucket.RemoveNode(id) { // 如果当前节点所在的桶中存在指定ID的节点,则直接删除并返回true。
	return true
}
closestPeers := make([]*Peer, 0, PeerCount2)
for _, n := range bucket.nodes { // 否则,将该桶中所有距离目标id更近的节点添加到closestPeers列表中。
	if bytes.Equal(n.id[:], selfNodeId[:]) {
		continue
	}
	closestPeers = append(closestPeers, &Peer{
		dht:       dht,
		node:      n,
		values:    make(map[string][]byte),
		neighbors: nil,
	})
}
targetId := id
closestPeers = dht.findClosestPeers(targetId, PeerCount-len(closestPeers), closestPeers)
for _, peer := range closestPeers { // 遍历closestPeers列表,递归调用removeNode函数,在最近的num个节点中查找并删除对应的节点。
	if peer.removeNode(id) {
		return true
	}
}
return false // 所有最近的num个节点都没有找到对应的节点,则返回false。

}

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=4194

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?