Pending ladder: a hash-named release of several pieces gets a lone target
The edge gave an unnamed release a "lone" probe target only when it had exactly one file, so a release of several random-named pieces (Bob's, 1.55M rows in five groups) reached the pending store with no target at all: never claimed, never named by a twin, its class never learned. candidates_of now takes the first random-named file when there is no par2, archive or 7z volume. The batch store writes a finished release without a target as exhausted instead of waiting, and leaves it out of its class's waiting count. LOG.md (140). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
66980829dc
commit
294f2d73ba
3 files changed
+77
-10
No files matched your search
+31
-2
@@ -1608,8 +1608,13 @@ fn candidates_of(key: &str, files: &[Vec<Seg>], upload: usize) -> Vec<Candidate>
|
||||
if let Some((_, f)) = tail {
|
||||
out.push(Candidate { release_key: key.to_string(), upload, kind: "7z-tail", message_id: f.last().unwrap().message_id.clone(), file: f[0].file.name.clone(), bytes: f.last().unwrap().bytes });
|
||||
}
|
||||
if out.is_empty() && files.len() == 1 && is_random_file(&files[0][0].file.name) {
|
||||
out.push(c("lone", &files[0][0]));
|
||||
// No set and no archive: the first random-named file's first segment, for its yEnc name or a twin by content
|
||||
// (hash_twins.ts). Any count of files: a hash-named release of several pieces (Bob's, LOG.md (140)) had no
|
||||
// target at all, so the ladder never probed it, never named it and never learned its class.
|
||||
if out.is_empty() {
|
||||
if let Some(f) = files.iter().find(|f| is_random_file(&f[0].file.name)) {
|
||||
out.push(c("lone", &f[0]));
|
||||
}
|
||||
}
|
||||
out.truncate(4);
|
||||
out
|
||||
@@ -1738,6 +1743,30 @@ mod tests {
|
||||
assert_eq!(ix.pending(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_multi_file_random_release_gets_a_lone_target() {
|
||||
let mut priorities = FxHashMap::default();
|
||||
priorities.insert(GROUP.to_string(), 1);
|
||||
let mut ix = RangeIndexer::new(GROUP, 1, 10_000, 1, Rules::defaults(priorities), 5);
|
||||
// Three hash-named pieces of one hash-named upload, five segments each (more than a per-article post): no
|
||||
// archive, no par2, no 7z volume.
|
||||
let mut lines = Vec::new();
|
||||
for (i, name) in ["9e7fc2741cdd450287aff2733ca4c193", "c5ebdd5487f5b132c76e8d5c2572e560", "8114c42c9694380c8b25857e8b3331c3"].iter().enumerate() {
|
||||
for part in 0..5 {
|
||||
lines.push(line(100 + (i * 5 + part) as i64, &format!(r#"b3a75d234aa73891e78a70fc1f5496b1 [{}/3] - "{name}" yEnc ({}/5)"#, i + 1, part + 1), (i * 5 + part) as i64));
|
||||
}
|
||||
}
|
||||
ix.add_text(&lines.join("\n"), 10_001);
|
||||
ix.finish();
|
||||
let batch = ix.take();
|
||||
assert_eq!(batch.releases.len(), 1, "counts {:?}", batch.counts);
|
||||
let r = &batch.releases[0];
|
||||
assert!(!r.readable && r.files == 3 && r.segments == 15, "readable {} files {} segments {}", r.readable, r.files, r.segments);
|
||||
let kinds: Vec<_> = batch.candidates.iter().map(|c| (c.kind, c.file.as_str())).collect();
|
||||
assert_eq!(kinds, vec![("lone", "9e7fc2741cdd450287aff2733ca4c193")]);
|
||||
assert_eq!(batch.candidates[0].message_id, "u100@test");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn album_templates_and_names() {
|
||||
assert_eq!(album_template("1481439079025_014.jpg.data").as_deref(), Some("#_#.jpg.data"));
|
||||
|
||||
Reference in new issue
Block a user