Remove discards peer by its Key, if the peer was previously memoized. Returns true if the peer was removed, and false if it was not found. in the set.
(peer Peer)
| 105 | // Returns true if the peer was removed, and false if it was not found. |
| 106 | // in the set. |
| 107 | func (ps *PeerSet) Remove(peer Peer) bool { |
| 108 | ps.mtx.Lock() |
| 109 | defer ps.mtx.Unlock() |
| 110 | |
| 111 | item := ps.lookup[peer.ID()] |
| 112 | if item == nil { |
| 113 | // Removing the peer has failed so we set a flag to mark that a removal was attempted. |
| 114 | // This can happen when the peer add routine from the switch is running in |
| 115 | // parallel to the receive routine of MConn. |
| 116 | // There is an error within MConn but the switch has not actually added the peer to the peer set yet. |
| 117 | // Setting this flag will prevent a peer from being added to a node's peer set afterwards. |
| 118 | peer.SetRemovalFailed() |
| 119 | return false |
| 120 | } |
| 121 | |
| 122 | index := item.index |
| 123 | // Create a new copy of the list but with one less item. |
| 124 | // (we must copy because we'll be mutating the list). |
| 125 | newList := make([]Peer, len(ps.list)-1) |
| 126 | copy(newList, ps.list) |
| 127 | // If it's the last peer, that's an easy special case. |
| 128 | if index == len(ps.list)-1 { |
| 129 | ps.list = newList |
| 130 | delete(ps.lookup, peer.ID()) |
| 131 | return true |
| 132 | } |
| 133 | |
| 134 | // Replace the popped item with the last item in the old list. |
| 135 | lastPeer := ps.list[len(ps.list)-1] |
| 136 | lastPeerKey := lastPeer.ID() |
| 137 | lastPeerItem := ps.lookup[lastPeerKey] |
| 138 | newList[index] = lastPeer |
| 139 | lastPeerItem.index = index |
| 140 | ps.list = newList |
| 141 | delete(ps.lookup, peer.ID()) |
| 142 | return true |
| 143 | } |
| 144 | |
| 145 | // Size returns the number of unique items in the peerSet. |
| 146 | func (ps *PeerSet) Size() int { |