📄 storagewrapper.py
字号:
self.inactive_requests[index] = l x = 0 self.amount_left_with_partials -= self._piecelen(index) self.download_history[index] = {} request_size = self.config['download_slice_size'] for x in xrange(0, self._piecelen(index), request_size): partlen = min(request_size, length - x) if x in parts: l.append((x, partlen)) self.amount_left_with_partials += partlen else: self.amount_inactive -= partlen self.download_history[index][x] = None self.stat_dirty[index] = 1 def _initalloc(self, pos, piece): assert self.rplaces[pos] < 0 assert self.places[piece] == NO_PLACE p = self.piece_size * pos length = self._piecelen(pos) if self.rplaces[pos] == UNALLOCATED: self.storage.allocated(p, length) self.places[piece] = pos self.rplaces[pos] = piece # "if self.rplaces[pos] != ALLOCATED:" to skip extra mark writes mark = self.partial_mark + tobinary(piece) mark += chr(0xff) * (self.config['download_slice_size'] - len(mark)) mark *= (length - 1) // len(mark) + 1 self.storage.write(p, buffer(mark, 0, length)) def _move_piece(self, oldpos, newpos): assert self.rplaces[newpos] < 0 assert self.rplaces[oldpos] >= 0 data = self.storage.read(self.piece_size * oldpos, self._piecelen(newpos)) self.storage.write(self.piece_size * newpos, data) if self.rplaces[newpos] == UNALLOCATED: self.storage.allocated(self.piece_size * newpos, len(data)) piece = self.rplaces[oldpos] self.places[piece] = newpos self.rplaces[oldpos] = ALLOCATED self.rplaces[newpos] = piece if not self.have[piece]: return data = data[:self._piecelen(piece)] if sha(data).digest() != self.hashes[piece]: raise BTFailure('data corrupted on disk - ' 'maybe you have two copies running?') def _get_free_place(self): while self.rplaces[self.holepos] >= 0: self.holepos += 1 return self.holepos def get_amount_left(self): return self.amount_left def do_I_have_anything(self): return self.amount_left < self.total_length def _make_inactive(self, index): length = self._piecelen(index) l = [] x = 0 request_size = self.config['download_slice_size'] while x + request_size < length: l.append((x, request_size)) x += request_size l.append((x, length - x)) self.inactive_requests[index] = l def _load_fastresume(self, resumefile, typecode): if resumefile is not None: try: r = array(typecode) r.fromfile(resumefile, self.numpieces) return r except Exception, e: self.errorfunc(WARNING, "Couldn't read fastresume data: " + str(e)) return None def write_fastresume(self, resumefile): for i in xrange(self.numpieces): if self.rplaces[i] >= 0 and not self.have[self.rplaces[i]]: self.rplaces[i] = FASTRESUME_PARTIAL self.rplaces.tofile(resumefile) def get_have_list(self): return self.have.tostring() def do_I_have(self, index): return self.have[index] def do_I_have_requests(self, index): return not not self.inactive_requests[index] def new_request(self, index): # returns (begin, length) if self.inactive_requests[index] == 1: self._make_inactive(index) self.numactive[index] += 1 self.stat_active[index] = 1 if index not in self.stat_dirty: self.stat_new[index] = 1 rs = self.inactive_requests[index] r = min(rs) rs.remove(r) self.amount_inactive -= r[1] if self.amount_inactive == 0: self.endgame = True return r def piece_came_in(self, index, begin, piece, source = None): if self.places[index] < 0: if self.rplaces[index] == ALLOCATED: self._initalloc(index, index) else: n = self._get_free_place() if self.places[n] >= 0: oldpos = self.places[n] self._move_piece(oldpos, n) n = oldpos if self.rplaces[index] < 0 or index == n: self._initalloc(n, index) else: self._move_piece(index, n) self._initalloc(index, index) if index in self.failed_pieces: old = self.storage.read(self.places[index] * self.piece_size + begin, len(piece)) if old != piece: self.failed_pieces[index][self.download_history[index][begin]]\ = None self.download_history.setdefault(index, {}) self.download_history[index][begin] = source self.storage.write(self.places[index] * self.piece_size + begin, piece) self.stat_dirty[index] = 1 self.numactive[index] -= 1 if self.numactive[index] == 0: del self.stat_active[index] if index in self.stat_new: del self.stat_new[index] if not self.inactive_requests[index] and not self.numactive[index]: del self.stat_dirty[index] if sha(self.storage.read(self.piece_size * self.places[index], self._piecelen(index))).digest() == self.hashes[index]: self.have[index] = True self.storage.downloaded(index * self.piece_size, self._piecelen(index)) self.inactive_requests[index] = None self.waschecked[index] = True self.amount_left -= self._piecelen(index) self.stat_numdownloaded += 1 for d in self.download_history[index].itervalues(): if d is not None: d.good(index) del self.download_history[index] if index in self.failed_pieces: for d in self.failed_pieces[index]: if d is not None: d.bad(index) del self.failed_pieces[index] if self.amount_left == 0: self.finished() else: self.data_flunked(self._piecelen(index), index) self.inactive_requests[index] = 1 self.amount_inactive += self._piecelen(index) self.stat_numflunked += 1 self.failed_pieces[index] = {} allsenders = {} for d in self.download_history[index].itervalues(): allsenders[d] = None if len(allsenders) == 1: culprit = allsenders.keys()[0] if culprit is not None: culprit.bad(index, bump = True) del self.failed_pieces[index] # found the culprit already return False return True def request_lost(self, index, begin, length): self.inactive_requests[index].append((begin, length)) self.amount_inactive += length self.numactive[index] -= 1 if not self.numactive[index] and index in self.stat_active: del self.stat_active[index] if index in self.stat_new: del self.stat_new[index] def get_piece(self, index, begin, length): if not self.have[index]: return None if not self.waschecked[index]: if sha(self.storage.read(self.piece_size * self.places[index], self._piecelen(index))).digest() != self.hashes[index]: raise BTFailure, 'told file complete on start-up, but piece failed hash check' self.waschecked[index] = True if begin + length > self._piecelen(index): return None return self.storage.read(self.piece_size * self.places[index] + begin, length)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -