Add file priorities.

This commit is contained in:
Igor Katson 2024-04-13 16:05:02 +03:00
parent c291e42bb5
commit e03600c463
4 changed files with 57 additions and 28 deletions

View file

@ -31,6 +31,20 @@ pub(crate) fn dummy_file() -> anyhow::Result<std::fs::File> {
.with_context(|| format!("error opening {}", DEVNULL))
}
// Iterate file pieces in the following order: first, last, everything else from start to end.
fn iter_piece_priorities(range: std::ops::Range<usize>) -> impl Iterator<Item = usize> {
// First and last of each file first, then the rest of pieces in that file.
let r = range;
use std::iter::once;
let first = once(r.start);
let last = once(r.start + r.len().overflowing_sub(1).0); // it's ok if it repeats, doesn't matter
let mid = r.clone().skip(1).take(r.len().overflowing_sub(2).0);
// The take(r.len()) is to not yield start/end pieces in case of 0 and 1 lengths.
first.chain(last).chain(mid).take(r.len())
}
impl OpenedFile {
pub fn new(
f: File,
@ -94,4 +108,24 @@ impl OpenedFile {
self.have.fetch_add(size, Ordering::Relaxed);
size
}
pub fn iter_piece_priorities(&self) -> impl Iterator<Item = usize> {
iter_piece_priorities(self.piece_range_usize())
}
}
#[cfg(test)]
mod tests {
use crate::opened_file::iter_piece_priorities;
#[test]
fn test_iter_piece_priorities() {
let it = |r: std::ops::Range<usize>| -> Vec<usize> { iter_piece_priorities(r).collect() };
assert_eq!(it(0..0), Vec::<usize>::new());
assert_eq!(it(0..1), vec![0]);
assert_eq!(it(0..2), vec![0, 1]);
assert_eq!(it(0..3), vec![0, 2, 1]);
assert_eq!(it(0..4), vec![0, 3, 1, 2]);
}
}