class QuartzTorrent::PeerHolder

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

Public Class Methods

new() click to toggle source
# File lib/quartz_torrent/peerholder.rb, line 7
def initialize
  @peersById = {}
  @peersByAddr = {}
  @peersByInfoHash = {}
  @log = LogManager.getLogger("peerholder")
end

Public Instance Methods

add(peer) click to toggle source

Add a peer to the PeerHolder.

# 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
all() click to toggle source

Return the list of all peers.

# File lib/quartz_torrent/peerholder.rb, line 92
def all
  @peersByAddr.values
end
delete(peer) click to toggle source

Delete the specified peer from the PeerHolder.

# 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) click to toggle source

Find a peer by its IP address and port.

# File lib/quartz_torrent/peerholder.rb, line 20
def findByAddr(ip, port)
  @peersByAddr[ip + port.to_s]
end
findById(peerId) click to toggle source

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

# File lib/quartz_torrent/peerholder.rb, line 15
def findById(peerId)
  @peersById[peerId]
end
findByInfoHash(infoHash) click to toggle source

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

# File lib/quartz_torrent/peerholder.rb, line 25
def findByInfoHash(infoHash)
  l = @peersByInfoHash[infoHash]
  l = [] if ! l
  l
end
idSet(peer) click to toggle source

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

# 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) click to toggle source
# 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
size() click to toggle source

Return the number of peers in the holder.

# File lib/quartz_torrent/peerholder.rb, line 97
def size
  @peersByAddr.size
end
to_s(infoHash = nil) click to toggle source

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

# 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

Private Instance Methods

byAddrKey(peer) click to toggle source
# File lib/quartz_torrent/peerholder.rb, line 128
def byAddrKey(peer)
  peer.trackerPeer.ip + peer.trackerPeer.port.to_s
end