diff --git a/crates/librqbit/src/chunk_tracker.rs b/crates/librqbit/src/chunk_tracker.rs index 9e0893b..0e52a95 100644 --- a/crates/librqbit/src/chunk_tracker.rs +++ b/crates/librqbit/src/chunk_tracker.rs @@ -34,9 +34,9 @@ pub struct ChunkTracker { // E.g. we might have more pieces, but the client asks to download only some files // partially. fn compute_chunk_status(lengths: &Lengths, needed_pieces: &BF) -> anyhow::Result { - if needed_pieces.len() != lengths.total_pieces() as usize { + if needed_pieces.len() < lengths.total_pieces() as usize { anyhow::bail!( - "bug: needed_pieces.len() != lengths.total_pieces(); {} != {}", + "bug: needed_pieces.len() < lengths.total_pieces(); {} < {}", needed_pieces.len(), lengths.total_pieces() ); @@ -295,5 +295,43 @@ mod tests { assert_eq!(chunks[5], true); assert_eq!(chunks[6], false); } + + { + // A more reasonable case. + let piece_length = CHUNK_SIZE * 2; + let l = Lengths::new(piece_length as u64 * 2 + 1, piece_length).unwrap(); + + assert_eq!(l.total_pieces(), 3); + assert_eq!(l.default_chunks_per_piece(), 2); + assert_eq!(l.total_chunks(), 5); + + { + let mut needed_pieces = + BF::from_boxed_slice(vec![0u8; l.piece_bitfield_bytes()].into_boxed_slice()); + needed_pieces.set(1, true); + + let chunks = compute_chunk_status(&l, &needed_pieces).unwrap(); + dbg!(&chunks); + assert_eq!(chunks[0], true); + assert_eq!(chunks[1], true); + assert_eq!(chunks[2], false); + assert_eq!(chunks[3], false); + assert_eq!(chunks[4], true); + } + + { + let mut needed_pieces = + BF::from_boxed_slice(vec![0u8; l.piece_bitfield_bytes()].into_boxed_slice()); + needed_pieces.set(2, true); + + let chunks = compute_chunk_status(&l, &needed_pieces).unwrap(); + dbg!(&chunks); + assert_eq!(chunks[0], true); + assert_eq!(chunks[1], true); + assert_eq!(chunks[2], true); + assert_eq!(chunks[3], true); + assert_eq!(chunks[4], false); + } + } } }