Prioritize last piece. Dont ask me why :)

This commit is contained in:
Igor Katson 2021-10-16 13:18:25 +01:00
parent 6bd518676d
commit 5de63af783
3 changed files with 17 additions and 2 deletions

View file

@ -72,6 +72,18 @@ impl ChunkTracker {
self.needed_pieces.set(index.get() as usize, false)
}
pub fn iter_needed_pieces(&self) -> impl Iterator<Item = usize> + '_ {
// Try the last piece first. Often important information is stored in the last piece.
// Then sequentially one by one. This is not super sophisticated but sometimes helps.
let last_piece_id = self.lengths.last_piece_id().get() as usize;
self.needed_pieces
.get(last_piece_id..)
.unwrap()
.iter_ones()
.map(move |n| n + last_piece_id)
.chain(self.needed_pieces.get(..last_piece_id).unwrap().iter_ones())
}
// None if wrong chunk
// true if did something
// false if didn't do anything

View file

@ -349,7 +349,7 @@ impl TorrentState {
fn get_next_needed_piece(&self, peer_handle: PeerHandle) -> Option<ValidPieceIndex> {
let g = self.locked.read();
let bf = g.peers.get_live(peer_handle)?.bitfield.as_ref()?;
for n in g.chunks.get_needed_pieces().iter_ones() {
for n in g.chunks.iter_needed_pieces() {
if bf.get(n).map(|v| *v) == Some(true) {
// in theory it should be safe without validation, but whatever.
return self.lengths.validate_piece_index(n as u32);
@ -375,7 +375,7 @@ impl TorrentState {
let n = {
let mut n_opt = None;
let bf = g.peers.get_live(peer_handle)?.bitfield.as_ref()?;
for n in g.chunks.get_needed_pieces().iter_ones() {
for n in g.chunks.iter_needed_pieces() {
if bf.get(n).map(|v| *v) == Some(true) {
n_opt = Some(n);
break;

View file

@ -118,6 +118,9 @@ impl Lengths {
pub const fn total_chunks(&self) -> u32 {
ceil_div_u64(self.total_length, self.chunk_length as u64) as u32
}
pub const fn last_piece_id(&self) -> ValidPieceIndex {
ValidPieceIndex(self.last_piece_id)
}
pub const fn total_pieces(&self) -> u32 {
self.last_piece_id + 1
}