home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / python2.4 / site-packages / BitTorrent / Downloader.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-08-31  |  14.9 KB  |  547 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.4)
  3.  
  4. from CurrentRateMeasure import Measure
  5. from random import shuffle
  6. from time import time
  7. from bitfield import Bitfield
  8.  
  9. class SingleDownload:
  10.     
  11.     def __init__(self, downloader, connection):
  12.         self.downloader = downloader
  13.         self.connection = connection
  14.         self.choked = True
  15.         self.interested = False
  16.         self.active_requests = []
  17.         self.measure = Measure(downloader.max_rate_period)
  18.         self.have = Bitfield(downloader.numpieces)
  19.         self.last = 0
  20.         self.example_interest = None
  21.  
  22.     
  23.     def disconnected(self):
  24.         self.downloader.downloads.remove(self)
  25.         for i in xrange(len(self.have)):
  26.             if self.have[i]:
  27.                 self.downloader.picker.lost_have(i)
  28.                 continue
  29.         
  30.         self._letgo()
  31.  
  32.     
  33.     def _letgo(self):
  34.         if not self.active_requests:
  35.             return None
  36.         
  37.         if self.downloader.storage.is_endgame():
  38.             self.active_requests = []
  39.             return None
  40.         
  41.         lost = []
  42.         for index, begin, length in self.active_requests:
  43.             self.downloader.storage.request_lost(index, begin, length)
  44.             if index not in lost:
  45.                 lost.append(index)
  46.                 continue
  47.         
  48.         self.active_requests = []
  49.         ds = _[1]
  50.         shuffle(ds)
  51.         for d in ds:
  52.             d._request_more(lost)
  53.         
  54.         for d in self.downloader.downloads:
  55.             if d.choked and not (d.interested):
  56.                 for l in lost:
  57.                     if d.have[l] and self.downloader.storage.do_I_have_requests(l):
  58.                         d.interested = True
  59.                         d.connection.send_interested()
  60.                         break
  61.                         continue
  62.                     []
  63.                 
  64.             []
  65.         
  66.  
  67.     
  68.     def got_choke(self):
  69.         if not self.choked:
  70.             self.choked = True
  71.             self._letgo()
  72.         
  73.  
  74.     
  75.     def got_unchoke(self):
  76.         if self.choked:
  77.             self.choked = False
  78.             if self.interested:
  79.                 self._request_more()
  80.             
  81.         
  82.  
  83.     
  84.     def is_choked(self):
  85.         return self.choked
  86.  
  87.     
  88.     def is_interested(self):
  89.         return self.interested
  90.  
  91.     
  92.     def got_piece(self, index, begin, piece):
  93.         
  94.         try:
  95.             self.active_requests.remove((index, begin, len(piece)))
  96.         except ValueError:
  97.             return False
  98.  
  99.         if self.downloader.storage.is_endgame():
  100.             self.downloader.all_requests.remove((index, begin, len(piece)))
  101.         
  102.         self.last = time()
  103.         self.measure.update_rate(len(piece))
  104.         self.downloader.measurefunc(len(piece))
  105.         self.downloader.downmeasure.update_rate(len(piece))
  106.         if self.downloader.storage.do_I_have(index):
  107.             self.downloader.picker.complete(index)
  108.         
  109.         if self.downloader.storage.is_endgame():
  110.             for d in self.downloader.downloads:
  111.                 if d is not self and d.interested:
  112.                     if d.choked:
  113.                         d.fix_download_endgame()
  114.                     else:
  115.                         
  116.                         try:
  117.                             d.active_requests.remove((index, begin, len(piece)))
  118.                         except ValueError:
  119.                             continue
  120.  
  121.                         d.connection.send_cancel(index, begin, len(piece))
  122.                         d.fix_download_endgame()
  123.                 d.choked
  124.             
  125.         
  126.         self._request_more()
  127.         return self.downloader.storage.do_I_have(index)
  128.  
  129.     
  130.     def _want(self, index):
  131.         if self.have[index]:
  132.             pass
  133.         return self.downloader.storage.do_I_have_requests(index)
  134.  
  135.     
  136.     def _request_more(self, indices = None):
  137.         if len(self.active_requests) == self.downloader.backlog:
  138.             return None
  139.         
  140.         if self.downloader.storage.is_endgame():
  141.             self.fix_download_endgame()
  142.             return None
  143.         
  144.         lost_interests = []
  145.         while len(self.active_requests) < self.downloader.backlog:
  146.             if indices is None:
  147.                 interest = self.downloader.picker.next(self._want, self.have.numfalse == 0)
  148.             else:
  149.                 interest = None
  150.                 for i in indices:
  151.                     if self.have[i] and self.downloader.storage.do_I_have_requests(i):
  152.                         interest = i
  153.                         break
  154.                         continue
  155.                 
  156.             if interest is None:
  157.                 break
  158.             
  159.             if not self.interested:
  160.                 self.interested = True
  161.                 self.connection.send_interested()
  162.             
  163.             self.example_interest = interest
  164.             (begin, length) = self.downloader.storage.new_request(interest)
  165.             self.downloader.picker.requested(interest, self.have.numfalse == 0)
  166.             self.active_requests.append((interest, begin, length))
  167.             self.connection.send_request(interest, begin, length)
  168.             if not self.downloader.storage.do_I_have_requests(interest):
  169.                 lost_interests.append(interest)
  170.                 continue
  171.         if not (self.active_requests) and self.interested:
  172.             self.interested = False
  173.             self.connection.send_not_interested()
  174.         
  175.         if lost_interests:
  176.             for d in self.downloader.downloads:
  177.                 if d.active_requests or not (d.interested):
  178.                     continue
  179.                 
  180.                 if d.example_interest is not None and self.downloader.storage.do_I_have_requests(d.example_interest):
  181.                     continue
  182.                 
  183.                 for lost in lost_interests:
  184.                     if d.have[lost]:
  185.                         break
  186.                         continue
  187.                 
  188.                 interest = self.downloader.picker.next(d._want, d.have.numfalse == 0)
  189.                 if interest is None:
  190.                     d.interested = False
  191.                     d.connection.send_not_interested()
  192.                     continue
  193.                 d.example_interest = interest
  194.             
  195.         
  196.         if self.downloader.storage.is_endgame():
  197.             self.downloader.all_requests = []
  198.             for d in self.downloader.downloads:
  199.                 self.downloader.all_requests.extend(d.active_requests)
  200.             
  201.             for d in self.downloader.downloads:
  202.                 d.fix_download_endgame()
  203.             
  204.         
  205.  
  206.     
  207.     def fix_download_endgame(self):
  208.         want = _[1]
  209.         if not (self.interested) and want:
  210.             self.interested = True
  211.             self.connection.send_interested()
  212.         
  213.         if self.choked:
  214.             return None
  215.         
  216.         shuffle(want)
  217.         del want[self.downloader.backlog - len(self.active_requests):]
  218.         self.active_requests.extend(want)
  219.         for piece, begin, length in want:
  220.             self.connection.send_request(piece, begin, length)
  221.         
  222.  
  223.     
  224.     def got_have(self, index):
  225.         if self.have[index]:
  226.             return None
  227.         
  228.         self.have[index] = True
  229.         self.downloader.picker.got_have(index)
  230.         if self.downloader.picker.am_I_complete() and self.have.numfalse == 0:
  231.             self.connection.close()
  232.             return None
  233.         
  234.         if self.downloader.storage.is_endgame():
  235.             self.fix_download_endgame()
  236.         elif self.downloader.storage.do_I_have_requests(index):
  237.             if not self.choked:
  238.                 self._request_more([
  239.                     index])
  240.             elif not self.interested:
  241.                 self.interested = True
  242.                 self.connection.send_interested()
  243.             
  244.         
  245.  
  246.     
  247.     def got_have_bitfield(self, have):
  248.         self.have = have
  249.         for i in xrange(len(self.have)):
  250.             if self.have[i]:
  251.                 self.downloader.picker.got_have(i)
  252.                 continue
  253.         
  254.         if self.downloader.picker.am_I_complete() and self.have.numfalse == 0:
  255.             self.connection.close()
  256.             return None
  257.         
  258.         if self.downloader.storage.is_endgame():
  259.             for piece, begin, length in self.downloader.all_requests:
  260.                 if self.have[piece]:
  261.                     self.interested = True
  262.                     self.connection.send_interested()
  263.                     return None
  264.                     continue
  265.             
  266.         
  267.         for i in xrange(len(self.have)):
  268.             if self.have[i] and self.downloader.storage.do_I_have_requests(i):
  269.                 self.interested = True
  270.                 self.connection.send_interested()
  271.                 return None
  272.                 continue
  273.         
  274.  
  275.     
  276.     def get_rate(self):
  277.         return self.measure.get_rate()
  278.  
  279.     
  280.     def is_snubbed(self):
  281.         return time() - self.last > self.downloader.snub_time
  282.  
  283.  
  284.  
  285. class Downloader:
  286.     
  287.     def __init__(self, storage, picker, backlog, max_rate_period, numpieces, downmeasure, snub_time, measurefunc = (lambda x: pass)):
  288.         self.storage = storage
  289.         self.picker = picker
  290.         self.backlog = backlog
  291.         self.max_rate_period = max_rate_period
  292.         self.downmeasure = downmeasure
  293.         self.numpieces = numpieces
  294.         self.snub_time = snub_time
  295.         self.measurefunc = measurefunc
  296.         self.downloads = []
  297.  
  298.     
  299.     def make_download(self, connection):
  300.         self.downloads.append(SingleDownload(self, connection))
  301.         return self.downloads[-1]
  302.  
  303.  
  304.  
  305. class DummyPicker:
  306.     
  307.     def __init__(self, num, r):
  308.         self.stuff = range(num)
  309.         self.r = r
  310.  
  311.     
  312.     def next(self, wantfunc, seed):
  313.         for i in self.stuff:
  314.             if wantfunc(i):
  315.                 return i
  316.                 continue
  317.         
  318.  
  319.     
  320.     def lost_have(self, pos):
  321.         self.r.append('lost have')
  322.  
  323.     
  324.     def got_have(self, pos):
  325.         self.r.append('got have')
  326.  
  327.     
  328.     def requested(self, pos, seed):
  329.         self.r.append('requested')
  330.  
  331.     
  332.     def complete(self, pos):
  333.         self.stuff.remove(pos)
  334.         self.r.append('complete')
  335.  
  336.     
  337.     def am_I_complete(self):
  338.         return False
  339.  
  340.     
  341.     def bump(self, i):
  342.         pass
  343.  
  344.  
  345.  
  346. class DummyStorage:
  347.     
  348.     def __init__(self, remaining, have_endgame = False, numpieces = 1):
  349.         self.remaining = remaining
  350.         self.active = [ [] for i in xrange(numpieces) ]
  351.         self.endgame = False
  352.         self.have_endgame = have_endgame
  353.  
  354.     
  355.     def do_I_have_requests(self, index):
  356.         return self.remaining[index] != []
  357.  
  358.     
  359.     def request_lost(self, index, begin, length):
  360.         x = (begin, length)
  361.         self.active[index].remove(x)
  362.         self.remaining[index].append(x)
  363.         self.remaining[index].sort()
  364.  
  365.     
  366.     def piece_came_in(self, index, begin, piece):
  367.         self.active[index].remove((begin, len(piece)))
  368.         return True
  369.  
  370.     
  371.     def do_I_have(self, index):
  372.         if self.remaining[index] == []:
  373.             pass
  374.         return self.active[index] == []
  375.  
  376.     
  377.     def new_request(self, index):
  378.         x = self.remaining[index].pop()
  379.         for i in self.remaining:
  380.             if i:
  381.                 break
  382.                 continue
  383.         else:
  384.             self.endgame = True
  385.         self.active[index].append(x)
  386.         self.active[index].sort()
  387.         return x
  388.  
  389.     
  390.     def is_endgame(self):
  391.         if self.have_endgame:
  392.             pass
  393.         return self.endgame
  394.  
  395.  
  396.  
  397. class DummyConnection:
  398.     
  399.     def __init__(self, events):
  400.         self.events = events
  401.  
  402.     
  403.     def send_interested(self):
  404.         self.events.append('interested')
  405.  
  406.     
  407.     def send_not_interested(self):
  408.         self.events.append('not interested')
  409.  
  410.     
  411.     def send_request(self, index, begin, length):
  412.         self.events.append(('request', index, begin, length))
  413.  
  414.     
  415.     def send_cancel(self, index, begin, length):
  416.         self.events.append(('cancel', index, begin, length))
  417.  
  418.  
  419.  
  420. def test_stops_at_backlog():
  421.     ds = DummyStorage([
  422.         [
  423.             (0, 2),
  424.             (2, 2),
  425.             (4, 2),
  426.             (6, 2)]])
  427.     events = []
  428.     d = Downloader(ds, DummyPicker(len(ds.remaining), events), 2, 15, 1, Measure(15), 10)
  429.     sd = d.make_download(DummyConnection(events))
  430.     sd.got_have_bitfield(Bitfield(1, chr(128)))
  431.     del events[:]
  432.     sd.got_unchoke()
  433.     del events[:]
  434.     sd.got_piece(0, 4, 'ab')
  435.     del events[:]
  436.  
  437.  
  438. def test_got_have_single():
  439.     ds = DummyStorage([
  440.         [
  441.             (0, 2)]])
  442.     events = []
  443.     d = Downloader(ds, DummyPicker(len(ds.remaining), events), 2, 15, 1, Measure(15), 10)
  444.     sd = d.make_download(DummyConnection(events))
  445.     sd.got_unchoke()
  446.     sd.got_have(0)
  447.     del events[:]
  448.     sd.disconnected()
  449.  
  450.  
  451. def test_choke_clears_active():
  452.     ds = DummyStorage([
  453.         [
  454.             (0, 2)]])
  455.     events = []
  456.     d = Downloader(ds, DummyPicker(len(ds.remaining), events), 2, 15, 1, Measure(15), 10)
  457.     sd1 = d.make_download(DummyConnection(events))
  458.     sd2 = d.make_download(DummyConnection(events))
  459.     sd1.got_unchoke()
  460.     sd1.got_have(0)
  461.     del events[:]
  462.     sd2.got_unchoke()
  463.     sd2.got_have(0)
  464.     del events[:]
  465.     sd1.got_choke()
  466.     del events[:]
  467.     sd2.got_piece(0, 0, 'ab')
  468.     del events[:]
  469.  
  470.  
  471. def test_endgame():
  472.     ds = DummyStorage([
  473.         [
  474.             (0, 2)],
  475.         [
  476.             (0, 2)],
  477.         [
  478.             (0, 2)]], True, 3)
  479.     events = []
  480.     d = Downloader(ds, DummyPicker(len(ds.remaining), events), 10, 15, 3, Measure(15), 10)
  481.     ev1 = []
  482.     ev2 = []
  483.     ev3 = []
  484.     ev4 = []
  485.     sd1 = d.make_download(DummyConnection(ev1))
  486.     sd2 = d.make_download(DummyConnection(ev2))
  487.     sd3 = d.make_download(DummyConnection(ev3))
  488.     sd1.got_unchoke()
  489.     sd1.got_have(0)
  490.     del ev1[:]
  491.     sd2.got_unchoke()
  492.     sd2.got_have(0)
  493.     sd2.got_have(1)
  494.     del ev2[:]
  495.     sd3.got_unchoke()
  496.     sd3.got_have(0)
  497.     sd3.got_have(1)
  498.     sd3.got_have(2)
  499.     del ev3[:]
  500.     del ev2[:]
  501.     sd2.got_piece(0, 0, 'ab')
  502.     del ev1[:]
  503.     del ev3[:]
  504.     sd3.got_choke()
  505.     sd3.got_unchoke()
  506.     del ev3[:]
  507.     sd4 = d.make_download(DummyConnection(ev4))
  508.     sd4.got_have_bitfield([
  509.         True,
  510.         True,
  511.         True])
  512.     del ev4[:]
  513.     sd4.got_unchoke()
  514.  
  515.  
  516. def test_stops_at_backlog_endgame():
  517.     ds = DummyStorage([
  518.         [
  519.             (2, 2),
  520.             (0, 2)],
  521.         [
  522.             (2, 2),
  523.             (0, 2)],
  524.         [
  525.             (0, 2)]], True, 3)
  526.     events = []
  527.     d = Downloader(ds, DummyPicker(len(ds.remaining), events), 3, 15, 3, Measure(15), 10)
  528.     ev1 = []
  529.     ev2 = []
  530.     ev3 = []
  531.     sd1 = d.make_download(DummyConnection(ev1))
  532.     sd2 = d.make_download(DummyConnection(ev2))
  533.     sd3 = d.make_download(DummyConnection(ev3))
  534.     sd1.got_unchoke()
  535.     sd1.got_have(0)
  536.     del ev1[:]
  537.     sd2.got_unchoke()
  538.     sd2.got_have(0)
  539.     sd2.got_have(1)
  540.     del ev2[:]
  541.     sd3.got_unchoke()
  542.     sd3.got_have(2)
  543.     n = ev2[0][2]
  544.     del ev2[:]
  545.     sd1.got_piece(0, n, 'ab')
  546.  
  547.