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 / Choker.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-08-31  |  10.0 KB  |  369 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.4)
  3.  
  4. from random import randrange
  5.  
  6. class Choker:
  7.     
  8.     def __init__(self, max_uploads, schedule, done = (lambda : False), min_uploads = None):
  9.         self.max_uploads = max_uploads
  10.         if min_uploads is None:
  11.             min_uploads = max_uploads
  12.         
  13.         self.min_uploads = min_uploads
  14.         self.schedule = schedule
  15.         self.connections = []
  16.         self.count = 0
  17.         self.done = done
  18.         schedule(self._round_robin, 10)
  19.  
  20.     
  21.     def _round_robin(self):
  22.         self.schedule(self._round_robin, 10)
  23.         self.count += 1
  24.         if self.count % 3 == 0:
  25.             for i in xrange(len(self.connections)):
  26.                 u = self.connections[i].get_upload()
  27.                 if u.is_choked() and u.is_interested():
  28.                     self.connections = self.connections[i:] + self.connections[:i]
  29.                     break
  30.                     continue
  31.                 self
  32.             
  33.         
  34.         self._rechoke()
  35.  
  36.     
  37.     def _snubbed(self, c):
  38.         if self.done():
  39.             return False
  40.         
  41.         return c.get_download().is_snubbed()
  42.  
  43.     
  44.     def _rate(self, c):
  45.         if self.done():
  46.             return c.get_upload().get_rate()
  47.         else:
  48.             return c.get_download().get_rate()
  49.  
  50.     
  51.     def _rechoke(self):
  52.         preferred = []
  53.         for c in self.connections:
  54.             if not self._snubbed(c) and c.get_upload().is_interested():
  55.                 preferred.append((-self._rate(c), c))
  56.                 continue
  57.         
  58.         preferred.sort()
  59.         del preferred[self.max_uploads - 1:]
  60.         preferred = [ x[1] for x in preferred ]
  61.         count = len(preferred)
  62.         hit = False
  63.         for c in self.connections:
  64.             u = c.get_upload()
  65.             if c in preferred:
  66.                 u.unchoke()
  67.                 continue
  68.             []
  69.             if count < self.min_uploads or not hit:
  70.                 u.unchoke()
  71.                 if u.is_interested():
  72.                     count += 1
  73.                     hit = True
  74.                 
  75.             u.is_interested()
  76.             u.choke()
  77.         
  78.  
  79.     
  80.     def connection_made(self, connection, p = None):
  81.         if p is None:
  82.             p = randrange(-2, len(self.connections) + 1)
  83.         
  84.         self.connections.insert(max(p, 0), connection)
  85.         self._rechoke()
  86.  
  87.     
  88.     def connection_lost(self, connection):
  89.         self.connections.remove(connection)
  90.         if connection.get_upload().is_interested() and not connection.get_upload().is_choked():
  91.             self._rechoke()
  92.         
  93.  
  94.     
  95.     def interested(self, connection):
  96.         if not connection.get_upload().is_choked():
  97.             self._rechoke()
  98.         
  99.  
  100.     
  101.     def not_interested(self, connection):
  102.         if not connection.get_upload().is_choked():
  103.             self._rechoke()
  104.         
  105.  
  106.     
  107.     def change_max_uploads(self, newval):
  108.         
  109.         def foo(self = self, newval = newval):
  110.             self._change_max_uploads(newval)
  111.  
  112.         self.schedule(foo, 0)
  113.  
  114.     
  115.     def _change_max_uploads(self, newval):
  116.         self.max_uploads = newval
  117.         self._rechoke()
  118.  
  119.  
  120.  
  121. class DummyScheduler:
  122.     
  123.     def __init__(self):
  124.         self.s = []
  125.  
  126.     
  127.     def __call__(self, func, delay):
  128.         self.s.append((func, delay))
  129.  
  130.  
  131.  
  132. class DummyConnection:
  133.     
  134.     def __init__(self, v = 0):
  135.         self.u = DummyUploader()
  136.         self.d = DummyDownloader(self)
  137.         self.v = v
  138.  
  139.     
  140.     def get_upload(self):
  141.         return self.u
  142.  
  143.     
  144.     def get_download(self):
  145.         return self.d
  146.  
  147.  
  148.  
  149. class DummyDownloader:
  150.     
  151.     def __init__(self, c):
  152.         self.s = False
  153.         self.c = c
  154.  
  155.     
  156.     def is_snubbed(self):
  157.         return self.s
  158.  
  159.     
  160.     def get_rate(self):
  161.         return self.c.v
  162.  
  163.  
  164.  
  165. class DummyUploader:
  166.     
  167.     def __init__(self):
  168.         self.i = False
  169.         self.c = True
  170.  
  171.     
  172.     def choke(self):
  173.         if not self.c:
  174.             self.c = True
  175.         
  176.  
  177.     
  178.     def unchoke(self):
  179.         if self.c:
  180.             self.c = False
  181.         
  182.  
  183.     
  184.     def is_choked(self):
  185.         return self.c
  186.  
  187.     
  188.     def is_interested(self):
  189.         return self.i
  190.  
  191.  
  192.  
  193. def test_round_robin_with_no_downloads():
  194.     s = DummyScheduler()
  195.     Choker(2, s)
  196.     s.s[0][0]()
  197.     del s.s[0]
  198.     s.s[0][0]()
  199.     del s.s[0]
  200.     s.s[0][0]()
  201.     del s.s[0]
  202.     s.s[0][0]()
  203.     del s.s[0]
  204.  
  205.  
  206. def test_resort():
  207.     s = DummyScheduler()
  208.     choker = Choker(1, s)
  209.     c1 = DummyConnection()
  210.     c2 = DummyConnection(1)
  211.     c3 = DummyConnection(2)
  212.     c4 = DummyConnection(3)
  213.     c2.u.i = True
  214.     c3.u.i = True
  215.     choker.connection_made(c1)
  216.     choker.connection_made(c2, 1)
  217.     choker.connection_made(c3, 1)
  218.     c2.v = 2
  219.     c3.v = 1
  220.     choker.connection_made(c4, 1)
  221.     choker.connection_lost(c4)
  222.     s.s[0][0]()
  223.  
  224.  
  225. def test_interest():
  226.     s = DummyScheduler()
  227.     choker = Choker(1, s)
  228.     c1 = DummyConnection()
  229.     c2 = DummyConnection(1)
  230.     c3 = DummyConnection(2)
  231.     c2.u.i = True
  232.     c3.u.i = True
  233.     choker.connection_made(c1)
  234.     choker.connection_made(c2, 1)
  235.     choker.connection_made(c3, 1)
  236.     c3.u.i = False
  237.     choker.not_interested(c3)
  238.     c3.u.i = True
  239.     choker.interested(c3)
  240.     choker.connection_lost(c3)
  241.  
  242.  
  243. def test_robin_interest():
  244.     s = DummyScheduler()
  245.     choker = Choker(1, s)
  246.     c1 = DummyConnection(0)
  247.     c2 = DummyConnection(1)
  248.     c1.u.i = True
  249.     choker.connection_made(c2)
  250.     choker.connection_made(c1, 0)
  251.     c1.u.i = False
  252.     choker.not_interested(c1)
  253.     c1.u.i = True
  254.     choker.interested(c1)
  255.     choker.connection_lost(c1)
  256.  
  257.  
  258. def test_skip_not_interested():
  259.     s = DummyScheduler()
  260.     choker = Choker(1, s)
  261.     c1 = DummyConnection(0)
  262.     c2 = DummyConnection(1)
  263.     c3 = DummyConnection(2)
  264.     c1.u.i = True
  265.     c3.u.i = True
  266.     choker.connection_made(c2)
  267.     choker.connection_made(c1, 0)
  268.     choker.connection_made(c3, 2)
  269.     f = s.s[0][0]
  270.     f()
  271.     f()
  272.     f()
  273.  
  274.  
  275. def test_connection_lost_no_interrupt():
  276.     s = DummyScheduler()
  277.     choker = Choker(1, s)
  278.     c1 = DummyConnection(0)
  279.     c2 = DummyConnection(1)
  280.     c3 = DummyConnection(2)
  281.     c1.u.i = True
  282.     c2.u.i = True
  283.     c3.u.i = True
  284.     choker.connection_made(c1)
  285.     choker.connection_made(c2, 1)
  286.     choker.connection_made(c3, 2)
  287.     f = s.s[0][0]
  288.     f()
  289.     f()
  290.     f()
  291.     f()
  292.     f()
  293.     choker.connection_lost(c3)
  294.     f()
  295.     choker.connection_lost(c2)
  296.  
  297.  
  298. def test_connection_made_no_interrupt():
  299.     s = DummyScheduler()
  300.     choker = Choker(1, s)
  301.     c1 = DummyConnection(0)
  302.     c2 = DummyConnection(1)
  303.     c3 = DummyConnection(2)
  304.     c1.u.i = True
  305.     c2.u.i = True
  306.     c3.u.i = True
  307.     choker.connection_made(c1)
  308.     choker.connection_made(c2, 1)
  309.     f = s.s[0][0]
  310.     f()
  311.     f()
  312.     choker.connection_made(c3, 1)
  313.     f()
  314.  
  315.  
  316. def test_round_robin():
  317.     s = DummyScheduler()
  318.     choker = Choker(1, s)
  319.     c1 = DummyConnection(0)
  320.     c2 = DummyConnection(1)
  321.     c1.u.i = True
  322.     c2.u.i = True
  323.     choker.connection_made(c1)
  324.     choker.connection_made(c2, 1)
  325.     f = s.s[0][0]
  326.     f()
  327.     f()
  328.     f()
  329.     f()
  330.     f()
  331.     f()
  332.  
  333.  
  334. def test_multi():
  335.     s = DummyScheduler()
  336.     choker = Choker(4, s)
  337.     c1 = DummyConnection(0)
  338.     c2 = DummyConnection(0)
  339.     c3 = DummyConnection(0)
  340.     c4 = DummyConnection(8)
  341.     c5 = DummyConnection(0)
  342.     c6 = DummyConnection(0)
  343.     c7 = DummyConnection(6)
  344.     c8 = DummyConnection(0)
  345.     c9 = DummyConnection(9)
  346.     c10 = DummyConnection(7)
  347.     c11 = DummyConnection(10)
  348.     choker.connection_made(c1, 0)
  349.     choker.connection_made(c2, 1)
  350.     choker.connection_made(c3, 2)
  351.     choker.connection_made(c4, 3)
  352.     choker.connection_made(c5, 4)
  353.     choker.connection_made(c6, 5)
  354.     choker.connection_made(c7, 6)
  355.     choker.connection_made(c8, 7)
  356.     choker.connection_made(c9, 8)
  357.     choker.connection_made(c10, 9)
  358.     choker.connection_made(c11, 10)
  359.     c2.u.i = True
  360.     c4.u.i = True
  361.     c6.u.i = True
  362.     c8.u.i = True
  363.     c10.u.i = True
  364.     c2.d.s = True
  365.     c6.d.s = True
  366.     c8.d.s = True
  367.     s.s[0][0]()
  368.  
  369.