Fix a couple bugs.
1. Bug one - last_piece_id when only_files is present. 2. Bug two - do not ensure_file_length for files we don't need.
This commit is contained in:
parent
f739c99dc0
commit
3a64254971
4 changed files with 34 additions and 13 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -1380,7 +1380,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rqbit"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ pub struct ChunkTracker {
|
|||
have: BF,
|
||||
|
||||
lengths: Lengths,
|
||||
|
||||
priority_piece_ids: Vec<usize>,
|
||||
}
|
||||
|
||||
// TODO: this should be redone from "have" pieces, not from "needed" pieces.
|
||||
|
|
@ -55,11 +57,20 @@ pub enum ChunkMarkingResult {
|
|||
|
||||
impl ChunkTracker {
|
||||
pub fn new(needed_pieces: BF, have_pieces: BF, lengths: Lengths) -> Self {
|
||||
// TODO: ideally this needs to be a list based on needed files, e.g.
|
||||
// last needed piece for each file. But let's keep simple for now.
|
||||
let last_needed_piece_id = needed_pieces.iter_ones().rev().next();
|
||||
|
||||
// The last pieces first. Often important information is stored in the last piece.
|
||||
// E.g. if it's a video file, than the last piece often contains some index, or just
|
||||
// players look into it, and it's better be there.
|
||||
let priority_piece_ids = last_needed_piece_id.into_iter().collect();
|
||||
Self {
|
||||
chunk_status: compute_chunk_status(&lengths, &needed_pieces),
|
||||
needed_pieces,
|
||||
lengths,
|
||||
have: have_pieces,
|
||||
priority_piece_ids,
|
||||
}
|
||||
}
|
||||
pub fn get_needed_pieces(&self) -> &BF {
|
||||
|
|
@ -73,15 +84,15 @@ impl ChunkTracker {
|
|||
}
|
||||
|
||||
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())
|
||||
self.priority_piece_ids
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(move |piece_id| self.needed_pieces[*piece_id])
|
||||
.chain(
|
||||
self.needed_pieces
|
||||
.iter_ones()
|
||||
.filter(move |id| !self.priority_piece_ids.contains(id)),
|
||||
)
|
||||
}
|
||||
|
||||
// None if wrong chunk
|
||||
|
|
|
|||
|
|
@ -214,9 +214,19 @@ impl TorrentManager {
|
|||
);
|
||||
|
||||
spawner.spawn_block_in_place(|| {
|
||||
for (file, (name, length)) in
|
||||
files.iter().zip(info.iter_filenames_and_lengths().unwrap())
|
||||
for (idx, (file, (name, length))) in files
|
||||
.iter()
|
||||
.zip(info.iter_filenames_and_lengths().unwrap())
|
||||
.enumerate()
|
||||
{
|
||||
if options
|
||||
.only_files
|
||||
.as_ref()
|
||||
.map(|v| !v.contains(&idx))
|
||||
.unwrap_or(false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let now = Instant::now();
|
||||
if let Err(err) = ensure_file_length(&mut file.lock(), length) {
|
||||
warn!(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "rqbit"
|
||||
description = "A bittorent client"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
authors = ["Igor Katson <igor.katson@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue