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.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-08-31  |  18.1 KB  |  776 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (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 not not (self.choked):
  138.             raise AssertionError
  139.         if len(self.active_requests) == self.downloader.backlog:
  140.             return None
  141.         
  142.         if self.downloader.storage.is_endgame():
  143.             self.fix_download_endgame()
  144.             return None
  145.         
  146.         lost_interests = []
  147.         while len(self.active_requests) < self.downloader.backlog:
  148.             if indices is None:
  149.                 interest = self.downloader.picker.next(self._want, self.have.numfalse == 0)
  150.             else:
  151.                 interest = None
  152.                 for i in indices:
  153.                     if self.have[i] and self.downloader.storage.do_I_have_requests(i):
  154.                         interest = i
  155.                         break
  156.                         continue
  157.                 
  158.             if interest is None:
  159.                 break
  160.             
  161.             if not self.interested:
  162.                 self.interested = True
  163.                 self.connection.send_interested()
  164.             
  165.             self.example_interest = interest
  166.             (begin, length) = self.downloader.storage.new_request(interest)
  167.             self.downloader.picker.requested(interest, self.have.numfalse == 0)
  168.             self.active_requests.append((interest, begin, length))
  169.             self.connection.send_request(interest, begin, length)
  170.             if not self.downloader.storage.do_I_have_requests(interest):
  171.                 lost_interests.append(interest)
  172.                 continue
  173.         if not (self.active_requests) and self.interested:
  174.             self.interested = False
  175.             self.connection.send_not_interested()
  176.         
  177.         if lost_interests:
  178.             for d in self.downloader.downloads:
  179.                 if d.active_requests or not (d.interested):
  180.                     continue
  181.                 
  182.                 if d.example_interest is not None and self.downloader.storage.do_I_have_requests(d.example_interest):
  183.                     continue
  184.                 
  185.                 for lost in lost_interests:
  186.                     if d.have[lost]:
  187.                         break
  188.                         continue
  189.                 
  190.                 interest = self.downloader.picker.next(d._want, d.have.numfalse == 0)
  191.                 if interest is None:
  192.                     d.interested = False
  193.                     d.connection.send_not_interested()
  194.                     continue
  195.                 d.example_interest = interest
  196.             
  197.         
  198.         if self.downloader.storage.is_endgame():
  199.             self.downloader.all_requests = []
  200.             for d in self.downloader.downloads:
  201.                 self.downloader.all_requests.extend(d.active_requests)
  202.             
  203.             for d in self.downloader.downloads:
  204.                 d.fix_download_endgame()
  205.             
  206.         
  207.  
  208.     
  209.     def fix_download_endgame(self):
  210.         want = _[1]
  211.         if not (self.interested) and want:
  212.             self.interested = True
  213.             self.connection.send_interested()
  214.         
  215.         if self.choked:
  216.             return None
  217.         
  218.         shuffle(want)
  219.         del want[self.downloader.backlog - len(self.active_requests):]
  220.         self.active_requests.extend(want)
  221.         for piece, begin, length in want:
  222.             self.connection.send_request(piece, begin, length)
  223.         
  224.  
  225.     
  226.     def got_have(self, index):
  227.         if self.have[index]:
  228.             return None
  229.         
  230.         self.have[index] = True
  231.         self.downloader.picker.got_have(index)
  232.         if self.downloader.picker.am_I_complete() and self.have.numfalse == 0:
  233.             self.connection.close()
  234.             return None
  235.         
  236.         if self.downloader.storage.is_endgame():
  237.             self.fix_download_endgame()
  238.         elif self.downloader.storage.do_I_have_requests(index):
  239.             if not self.choked:
  240.                 self._request_more([
  241.                     index])
  242.             elif not self.interested:
  243.                 self.interested = True
  244.                 self.connection.send_interested()
  245.             
  246.         
  247.  
  248.     
  249.     def got_have_bitfield(self, have):
  250.         self.have = have
  251.         for i in xrange(len(self.have)):
  252.             if self.have[i]:
  253.                 self.downloader.picker.got_have(i)
  254.                 continue
  255.         
  256.         if self.downloader.picker.am_I_complete() and self.have.numfalse == 0:
  257.             self.connection.close()
  258.             return None
  259.         
  260.         if self.downloader.storage.is_endgame():
  261.             for piece, begin, length in self.downloader.all_requests:
  262.                 if self.have[piece]:
  263.                     self.interested = True
  264.                     self.connection.send_interested()
  265.                     return None
  266.                     continue
  267.             
  268.         
  269.         for i in xrange(len(self.have)):
  270.             if self.have[i] and self.downloader.storage.do_I_have_requests(i):
  271.                 self.interested = True
  272.                 self.connection.send_interested()
  273.                 return None
  274.                 continue
  275.         
  276.  
  277.     
  278.     def get_rate(self):
  279.         return self.measure.get_rate()
  280.  
  281.     
  282.     def is_snubbed(self):
  283.         return time() - self.last > self.downloader.snub_time
  284.  
  285.  
  286.  
  287. class Downloader:
  288.     
  289.     def __init__(self, storage, picker, backlog, max_rate_period, numpieces, downmeasure, snub_time, measurefunc = (lambda x: pass)):
  290.         self.storage = storage
  291.         self.picker = picker
  292.         self.backlog = backlog
  293.         self.max_rate_period = max_rate_period
  294.         self.downmeasure = downmeasure
  295.         self.numpieces = numpieces
  296.         self.snub_time = snub_time
  297.         self.measurefunc = measurefunc
  298.         self.downloads = []
  299.  
  300.     
  301.     def make_download(self, connection):
  302.         self.downloads.append(SingleDownload(self, connection))
  303.         return self.downloads[-1]
  304.  
  305.  
  306.  
  307. class DummyPicker:
  308.     
  309.     def __init__(self, num, r):
  310.         self.stuff = range(num)
  311.         self.r = r
  312.  
  313.     
  314.     def next(self, wantfunc, seed):
  315.         for i in self.stuff:
  316.             if wantfunc(i):
  317.                 return i
  318.                 continue
  319.         
  320.  
  321.     
  322.     def lost_have(self, pos):
  323.         self.r.append('lost have')
  324.  
  325.     
  326.     def got_have(self, pos):
  327.         self.r.append('got have')
  328.  
  329.     
  330.     def requested(self, pos, seed):
  331.         self.r.append('requested')
  332.  
  333.     
  334.     def complete(self, pos):
  335.         self.stuff.remove(pos)
  336.         self.r.append('complete')
  337.  
  338.     
  339.     def am_I_complete(self):
  340.         return False
  341.  
  342.     
  343.     def bump(self, i):
  344.         pass
  345.  
  346.  
  347.  
  348. class DummyStorage:
  349.     
  350.     def __init__(self, remaining, have_endgame = False, numpieces = 1):
  351.         self.remaining = remaining
  352.         self.active = [ [] for i in xrange(numpieces) ]
  353.         self.endgame = False
  354.         self.have_endgame = have_endgame
  355.  
  356.     
  357.     def do_I_have_requests(self, index):
  358.         return self.remaining[index] != []
  359.  
  360.     
  361.     def request_lost(self, index, begin, length):
  362.         x = (begin, length)
  363.         self.active[index].remove(x)
  364.         self.remaining[index].append(x)
  365.         self.remaining[index].sort()
  366.  
  367.     
  368.     def piece_came_in(self, index, begin, piece):
  369.         self.active[index].remove((begin, len(piece)))
  370.         return True
  371.  
  372.     
  373.     def do_I_have(self, index):
  374.         if self.remaining[index] == []:
  375.             pass
  376.         return self.active[index] == []
  377.  
  378.     
  379.     def new_request(self, index):
  380.         x = self.remaining[index].pop()
  381.         for i in self.remaining:
  382.             if i:
  383.                 break
  384.                 continue
  385.         else:
  386.             self.endgame = True
  387.         self.active[index].append(x)
  388.         self.active[index].sort()
  389.         return x
  390.  
  391.     
  392.     def is_endgame(self):
  393.         if self.have_endgame:
  394.             pass
  395.         return self.endgame
  396.  
  397.  
  398.  
  399. class DummyConnection:
  400.     
  401.     def __init__(self, events):
  402.         self.events = events
  403.  
  404.     
  405.     def send_interested(self):
  406.         self.events.append('interested')
  407.  
  408.     
  409.     def send_not_interested(self):
  410.         self.events.append('not interested')
  411.  
  412.     
  413.     def send_request(self, index, begin, length):
  414.         self.events.append(('request', index, begin, length))
  415.  
  416.     
  417.     def send_cancel(self, index, begin, length):
  418.         self.events.append(('cancel', index, begin, length))
  419.  
  420.  
  421.  
  422. def test_stops_at_backlog():
  423.     ds = DummyStorage([
  424.         [
  425.             (0, 2),
  426.             (2, 2),
  427.             (4, 2),
  428.             (6, 2)]])
  429.     events = []
  430.     d = Downloader(ds, DummyPicker(len(ds.remaining), events), 2, 15, 1, Measure(15), 10)
  431.     sd = d.make_download(DummyConnection(events))
  432.     if not events == []:
  433.         raise AssertionError
  434.     if not ds.remaining == [
  435.         [
  436.             (0, 2),
  437.             (2, 2),
  438.             (4, 2),
  439.             (6, 2)]]:
  440.         raise AssertionError
  441.     if not ds.active == [
  442.         []]:
  443.         raise AssertionError
  444.     sd.got_have_bitfield(Bitfield(1, chr(128)))
  445.     if not events == [
  446.         'got have',
  447.         'interested']:
  448.         raise AssertionError
  449.     del events[:]
  450.     if not ds.remaining == [
  451.         [
  452.             (0, 2),
  453.             (2, 2),
  454.             (4, 2),
  455.             (6, 2)]]:
  456.         raise AssertionError
  457.     if not ds.active == [
  458.         []]:
  459.         raise AssertionError
  460.     sd.got_unchoke()
  461.     if not events == [
  462.         'requested',
  463.         ('request', 0, 6, 2),
  464.         'requested',
  465.         ('request', 0, 4, 2)]:
  466.         raise AssertionError
  467.     del events[:]
  468.     if not ds.remaining == [
  469.         [
  470.             (0, 2),
  471.             (2, 2)]]:
  472.         raise AssertionError
  473.     if not ds.active == [
  474.         [
  475.             (4, 2),
  476.             (6, 2)]]:
  477.         raise AssertionError
  478.     sd.got_piece(0, 4, 'ab')
  479.     if not events == [
  480.         'requested',
  481.         ('request', 0, 2, 2)]:
  482.         raise AssertionError
  483.     del events[:]
  484.     if not ds.remaining == [
  485.         [
  486.             (0, 2)]]:
  487.         raise AssertionError
  488.     if not ds.active == [
  489.         [
  490.             (2, 2),
  491.             (6, 2)]]:
  492.         raise AssertionError
  493.  
  494.  
  495. def test_got_have_single():
  496.     ds = DummyStorage([
  497.         [
  498.             (0, 2)]])
  499.     events = []
  500.     d = Downloader(ds, DummyPicker(len(ds.remaining), events), 2, 15, 1, Measure(15), 10)
  501.     sd = d.make_download(DummyConnection(events))
  502.     if not events == []:
  503.         raise AssertionError
  504.     if not ds.remaining == [
  505.         [
  506.             (0, 2)]]:
  507.         raise AssertionError
  508.     if not ds.active == [
  509.         []]:
  510.         raise AssertionError
  511.     sd.got_unchoke()
  512.     if not events == []:
  513.         raise AssertionError
  514.     if not ds.remaining == [
  515.         [
  516.             (0, 2)]]:
  517.         raise AssertionError
  518.     if not ds.active == [
  519.         []]:
  520.         raise AssertionError
  521.     sd.got_have(0)
  522.     if not events == [
  523.         'got have',
  524.         'interested',
  525.         'requested',
  526.         ('request', 0, 0, 2)]:
  527.         raise AssertionError
  528.     del events[:]
  529.     if not ds.remaining == [
  530.         []]:
  531.         raise AssertionError
  532.     if not ds.active == [
  533.         [
  534.             (0, 2)]]:
  535.         raise AssertionError
  536.     sd.disconnected()
  537.     if not events == [
  538.         'lost have']:
  539.         raise AssertionError
  540.  
  541.  
  542. def test_choke_clears_active():
  543.     ds = DummyStorage([
  544.         [
  545.             (0, 2)]])
  546.     events = []
  547.     d = Downloader(ds, DummyPicker(len(ds.remaining), events), 2, 15, 1, Measure(15), 10)
  548.     sd1 = d.make_download(DummyConnection(events))
  549.     sd2 = d.make_download(DummyConnection(events))
  550.     if not events == []:
  551.         raise AssertionError
  552.     if not ds.remaining == [
  553.         [
  554.             (0, 2)]]:
  555.         raise AssertionError
  556.     if not ds.active == [
  557.         []]:
  558.         raise AssertionError
  559.     sd1.got_unchoke()
  560.     sd1.got_have(0)
  561.     if not events == [
  562.         'got have',
  563.         'interested',
  564.         'requested',
  565.         ('request', 0, 0, 2)]:
  566.         raise AssertionError
  567.     del events[:]
  568.     if not ds.remaining == [
  569.         []]:
  570.         raise AssertionError
  571.     if not ds.active == [
  572.         [
  573.             (0, 2)]]:
  574.         raise AssertionError
  575.     sd2.got_unchoke()
  576.     sd2.got_have(0)
  577.     if not events == [
  578.         'got have']:
  579.         raise AssertionError
  580.     del events[:]
  581.     if not ds.remaining == [
  582.         []]:
  583.         raise AssertionError
  584.     if not ds.active == [
  585.         [
  586.             (0, 2)]]:
  587.         raise AssertionError
  588.     sd1.got_choke()
  589.     if not events == [
  590.         'interested',
  591.         'requested',
  592.         ('request', 0, 0, 2),
  593.         'not interested']:
  594.         raise AssertionError
  595.     del events[:]
  596.     if not ds.remaining == [
  597.         []]:
  598.         raise AssertionError
  599.     if not ds.active == [
  600.         [
  601.             (0, 2)]]:
  602.         raise AssertionError
  603.     sd2.got_piece(0, 0, 'ab')
  604.     if not events == [
  605.         'complete',
  606.         'not interested']:
  607.         raise AssertionError
  608.     del events[:]
  609.     if not ds.remaining == [
  610.         []]:
  611.         raise AssertionError
  612.     if not ds.active == [
  613.         []]:
  614.         raise AssertionError
  615.  
  616.  
  617. def test_endgame():
  618.     ds = DummyStorage([
  619.         [
  620.             (0, 2)],
  621.         [
  622.             (0, 2)],
  623.         [
  624.             (0, 2)]], True, 3)
  625.     events = []
  626.     d = Downloader(ds, DummyPicker(len(ds.remaining), events), 10, 15, 3, Measure(15), 10)
  627.     ev1 = []
  628.     ev2 = []
  629.     ev3 = []
  630.     ev4 = []
  631.     sd1 = d.make_download(DummyConnection(ev1))
  632.     sd2 = d.make_download(DummyConnection(ev2))
  633.     sd3 = d.make_download(DummyConnection(ev3))
  634.     sd1.got_unchoke()
  635.     sd1.got_have(0)
  636.     if not ev1 == [
  637.         'interested',
  638.         ('request', 0, 0, 2)]:
  639.         raise AssertionError
  640.     del ev1[:]
  641.     sd2.got_unchoke()
  642.     sd2.got_have(0)
  643.     sd2.got_have(1)
  644.     if not ev2 == [
  645.         'interested',
  646.         ('request', 1, 0, 2)]:
  647.         raise AssertionError
  648.     del ev2[:]
  649.     sd3.got_unchoke()
  650.     sd3.got_have(0)
  651.     sd3.got_have(1)
  652.     sd3.got_have(2)
  653.     if not ev3 == [
  654.         'interested',
  655.         ('request', 2, 0, 2),
  656.         ('request', 0, 0, 2),
  657.         ('request', 1, 0, 2)] and ev3 == [
  658.         'interested',
  659.         ('request', 2, 0, 2),
  660.         ('request', 1, 0, 2),
  661.         ('request', 0, 0, 2)]:
  662.         raise AssertionError
  663.     del ev3[:]
  664.     if not ev2 == [
  665.         ('request', 0, 0, 2)]:
  666.         raise AssertionError
  667.     del ev2[:]
  668.     sd2.got_piece(0, 0, 'ab')
  669.     if not ev1 == [
  670.         ('cancel', 0, 0, 2),
  671.         'not interested']:
  672.         raise AssertionError
  673.     del ev1[:]
  674.     if not ev2 == []:
  675.         raise AssertionError
  676.     if not ev3 == [
  677.         ('cancel', 0, 0, 2)]:
  678.         raise AssertionError
  679.     del ev3[:]
  680.     sd3.got_choke()
  681.     if not ev1 == []:
  682.         raise AssertionError
  683.     if not ev2 == []:
  684.         raise AssertionError
  685.     if not ev3 == []:
  686.         raise AssertionError
  687.     sd3.got_unchoke()
  688.     if not ev3 == [
  689.         ('request', 2, 0, 2),
  690.         ('request', 1, 0, 2)] and ev3 == [
  691.         ('request', 1, 0, 2),
  692.         ('request', 2, 0, 2)]:
  693.         raise AssertionError
  694.     del ev3[:]
  695.     if not ev1 == []:
  696.         raise AssertionError
  697.     if not ev2 == []:
  698.         raise AssertionError
  699.     sd4 = d.make_download(DummyConnection(ev4))
  700.     sd4.got_have_bitfield([
  701.         True,
  702.         True,
  703.         True])
  704.     if not ev4 == [
  705.         'interested']:
  706.         raise AssertionError
  707.     del ev4[:]
  708.     sd4.got_unchoke()
  709.     if not ev4 == [
  710.         ('request', 2, 0, 2),
  711.         ('request', 1, 0, 2)] and ev4 == [
  712.         ('request', 1, 0, 2),
  713.         ('request', 2, 0, 2)]:
  714.         raise AssertionError
  715.     if not ev1 == []:
  716.         raise AssertionError
  717.     if not ev2 == []:
  718.         raise AssertionError
  719.     if not ev3 == []:
  720.         raise AssertionError
  721.  
  722.  
  723. def test_stops_at_backlog_endgame():
  724.     ds = DummyStorage([
  725.         [
  726.             (2, 2),
  727.             (0, 2)],
  728.         [
  729.             (2, 2),
  730.             (0, 2)],
  731.         [
  732.             (0, 2)]], True, 3)
  733.     events = []
  734.     d = Downloader(ds, DummyPicker(len(ds.remaining), events), 3, 15, 3, Measure(15), 10)
  735.     ev1 = []
  736.     ev2 = []
  737.     ev3 = []
  738.     sd1 = d.make_download(DummyConnection(ev1))
  739.     sd2 = d.make_download(DummyConnection(ev2))
  740.     sd3 = d.make_download(DummyConnection(ev3))
  741.     sd1.got_unchoke()
  742.     sd1.got_have(0)
  743.     if not ev1 == [
  744.         'interested',
  745.         ('request', 0, 0, 2),
  746.         ('request', 0, 2, 2)]:
  747.         raise AssertionError
  748.     del ev1[:]
  749.     sd2.got_unchoke()
  750.     sd2.got_have(0)
  751.     if not ev2 == []:
  752.         raise AssertionError
  753.     sd2.got_have(1)
  754.     if not ev2 == [
  755.         'interested',
  756.         ('request', 1, 0, 2),
  757.         ('request', 1, 2, 2)]:
  758.         raise AssertionError
  759.     del ev2[:]
  760.     sd3.got_unchoke()
  761.     sd3.got_have(2)
  762.     if not ev2 == [
  763.         ('request', 0, 0, 2)] and ev2 == [
  764.         ('request', 0, 2, 2)]:
  765.         raise AssertionError
  766.     n = ev2[0][2]
  767.     del ev2[:]
  768.     sd1.got_piece(0, n, 'ab')
  769.     if not ev1 == []:
  770.         raise AssertionError
  771.     if not ev2 == [
  772.         ('cancel', 0, n, 2),
  773.         ('request', 0, 2 - n, 2)]:
  774.         raise AssertionError
  775.  
  776.