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) {

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

}

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

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

}

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

  1. for i, n := range p.neighbors {
  2. if n.node.id == peer.node.id {
  3. copy(p.neighbors[i:], p.neighbors[i+1:])
  4. p.neighbors[len(p.neighbors)-1] = nil
  5. p.neighbors = p.neighbors[:len(p.neighbors)-1]
  6. break
  7. }
  8. }

}

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

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

}

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?