class QuartzTorrent::PieceMapper

Maps pieces to sections of files.

Public Class Methods

new(baseDirectory, torrinfo) click to toggle source

Create a new PieceMapper that will map to files inside ‘baseDirectory’. Parameter ‘torrinfo’ should be a Metainfo::Info object (the info part of the metainfo).

# File lib/quartz_torrent/filemanager.rb, line 48
def initialize(baseDirectory, torrinfo)
  @torrinfo = torrinfo
  @pieceSize = torrinfo.pieceLen
  @logger = LogManager.getLogger("piecemapper")

  @fileRegionMap = RegionMap.new
  offset = 0
  @logger.debug "Map (offset to path):"
  torrinfo.files.each do |file|
    offset += file.length
    path = baseDirectory + File::SEPARATOR + file.path
    @fileRegionMap.add offset-1, path
    @logger.debug "  #{offset-1}\t#{path}"
  end      
end

Public Instance Methods

findBlock(pieceIndex, offset, length) click to toggle source

Return a list of FileRegion objects. The FileRegion offsets specify in order which regions of files the piece covers.

# File lib/quartz_torrent/filemanager.rb, line 75
def findBlock(pieceIndex, offset, length)
  leftOffset = @pieceSize*pieceIndex + offset
  rightOffset = leftOffset + length-1

  findPart(leftOffset, rightOffset)
end
findPiece(pieceIndex) click to toggle source

Return a list of FileRegion objects. The FileRegion offsets specify in order which regions of files the piece covers.

# File lib/quartz_torrent/filemanager.rb, line 66
def findPiece(pieceIndex)
  leftOffset = @pieceSize*pieceIndex
  rightOffset = leftOffset + @pieceSize-1

  findPart(leftOffset, rightOffset)
end

Private Instance Methods

findPart(leftOffset, rightOffset) click to toggle source
# File lib/quartz_torrent/filemanager.rb, line 83
def findPart(leftOffset, rightOffset)
  # [index, value, left, right, offset]
  leftData = @fileRegionMap.find(leftOffset)
  rightData = @fileRegionMap.find(rightOffset)
  if rightData.nil?
    # Right end is past the end of the rightmost limit. Scale it back.
    rightData = @fileRegionMap.last
    rightData.push rightData[3]-rightData[2]
  end
  raise "Offset #{leftOffset} is out of range" if leftData.nil?
  leftIndex = leftData[0]
  rightIndex = rightData[0]
  if leftIndex == rightIndex
    return [FileRegion.new(leftData[1], leftData[4], rightData[4]-leftData[4]+1)]
  end

  result = []
  (leftIndex..rightIndex).each do |i|
    if i == leftIndex 
      result.push FileRegion.new(leftData[1], leftData[4], leftData[3]-leftData[4]-leftData[2]+1)
    elsif i == rightIndex    
      result.push FileRegion.new(rightData[1], 0, rightData[4]+1)
    else
      value, left, right = @fileRegionMap[i]
      result.push FileRegion.new(value, 0, right-left+1)
    end
  end
  result
end