Class: QuartzTorrent::PeerHolder

Inherits:
Object
  • Object
show all
Defined in:
lib/quartz_torrent/peerholder.rb

Overview

A container class for holding torrent peers. Allows lookup by different properties.

Instance Method Summary collapse

Constructor Details

#initializePeerHolder

Returns a new instance of PeerHolder.



7
8
9
10
11
12
# File 'lib/quartz_torrent/peerholder.rb', line 7

def initialize
  @peersById = {}
  @peersByAddr = {}
  @peersByInfoHash = {}
  @log = LogManager.getLogger("peerholder")
end

Instance Method Details

#add(peer) ⇒ Object

Add a peer to the PeerHolder.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/quartz_torrent/peerholder.rb', line 32

def add(peer)
  raise "Peer must have it's infoHash set." if ! peer.infoHash

  # Do not add if peer is already present by address
  if @peersByAddr.has_key?(byAddrKey(peer))
    @log.debug "Not adding peer #{peer} since it already exists by #{@peersById.has_key?(peer.trackerPeer.id) ? "id" : "addr"}."
    return
  end

  if peer.trackerPeer.id
    @peersById.pushToList(peer.trackerPeer.id, peer)
    
    # If id is null, this is probably a peer received from the tracker that has no ID.
  end

  @peersByAddr[byAddrKey(peer)] = peer

  @peersByInfoHash.pushToList(peer.infoHash, peer)
end

#allObject

Return the list of all peers.



92
93
94
# File 'lib/quartz_torrent/peerholder.rb', line 92

def all
  @peersByAddr.values
end

#delete(peer) ⇒ Object

Delete the specified peer from the PeerHolder.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/quartz_torrent/peerholder.rb', line 61

def delete(peer)
  @peersByAddr.delete byAddrKey(peer)

  list = @peersByInfoHash[peer.infoHash]
  if list
    list.collect! do |p|
      if !p.eql?(peer)
        peer
      else
        nil
      end
    end
    list.compact!
  end

  if peer.trackerPeer.id
    list = @peersById[peer.trackerPeer.id]
    if list
      list.collect! do |p|
        if !p.eql?(peer)
          peer
        else
          nil
        end
      end
      list.compact!
    end
  end
end

#findByAddr(ip, port) ⇒ Object

Find a peer by its IP address and port.



20
21
22
# File 'lib/quartz_torrent/peerholder.rb', line 20

def findByAddr(ip, port)
  @peersByAddr[ip + port.to_s]
end

#findById(peerId) ⇒ Object

Find a peer by its trackerpeer’s peerid. This is the id returned by the tracker, and may be nil.



15
16
17
# File 'lib/quartz_torrent/peerholder.rb', line 15

def findById(peerId)
  @peersById[peerId]
end

#findByInfoHash(infoHash) ⇒ Object

Find all peers related to the torrent with the passed infoHash.



25
26
27
28
29
# File 'lib/quartz_torrent/peerholder.rb', line 25

def findByInfoHash(infoHash)
  l = @peersByInfoHash[infoHash]
  l = [] if ! l
  l
end

#idSet(peer) ⇒ Object

Set the id for a peer. This peer, which previously had no id, has finished handshaking and now has an ID.



53
54
55
56
57
58
# File 'lib/quartz_torrent/peerholder.rb', line 53

def idSet(peer)
  @peersById.each do |e| 
    return if e.eql?(peer)
  end
  @peersById.pushToList(peer.trackerPeer.id, peer)
end

#makeFlags(peer) ⇒ Object



103
104
105
106
107
108
109
110
111
# File 'lib/quartz_torrent/peerholder.rb', line 103

def makeFlags(peer)
  s = "["
  s << "c" if peer.amChoked
  s << "i" if peer.peerInterested
  s << "C" if peer.peerChoked
  s << "I" if peer.amInterested
  s << "]"
  s
end

#sizeObject

Return the number of peers in the holder.



97
98
99
# File 'lib/quartz_torrent/peerholder.rb', line 97

def size
  @peersByAddr.size
end

#to_s(infoHash = nil) ⇒ Object

Output a string representation of the PeerHolder, for debugging purposes.



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/quartz_torrent/peerholder.rb', line 102

def to_s(infoHash = nil)
  def makeFlags(peer)
    s = "["
    s << "c" if peer.amChoked
    s << "i" if peer.peerInterested
    s << "C" if peer.peerChoked
    s << "I" if peer.amInterested
    s << "]"
    s
  end    

  if infoHash
    s = "Peers: \n"
    peers = @peersByInfoHash[infoHash]
    if peers
      peers.each do |peer|
        s << "  #{peer.to_s} #{makeFlags(peer)}\n"
      end
    end
  else
    "PeerHolder"
  end
  s 
end