1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 03:27:44 +00:00

sort: make merging stable

When merging files we need to prioritize files that occur earlier in the
command line arguments with -m.

This also makes the extsort merge step (and thus extsort itself) stable again.
This commit is contained in:
Michael Debertol 2021-05-08 23:06:17 +02:00
parent 2ff9cc6570
commit e0ebf907a4
7 changed files with 48 additions and 1 deletions

View file

@ -686,6 +686,7 @@ struct MergeableFile<'a> {
lines: Box<dyn Iterator<Item = Line> + 'a>,
current_line: Line,
settings: &'a GlobalSettings,
file_index: usize,
}
// BinaryHeap depends on `Ord`. Note that we want to pop smallest items
@ -693,7 +694,14 @@ struct MergeableFile<'a> {
// trick it into the right order by calling reverse() here.
impl<'a> Ord for MergeableFile<'a> {
fn cmp(&self, other: &MergeableFile) -> Ordering {
compare_by(&self.current_line, &other.current_line, self.settings).reverse()
let comparison = compare_by(&self.current_line, &other.current_line, self.settings);
if comparison == Ordering::Equal {
// If lines are equal, the earlier file takes precedence.
self.file_index.cmp(&other.file_index)
} else {
comparison
}
.reverse()
}
}
@ -729,6 +737,7 @@ impl<'a> FileMerger<'a> {
lines,
current_line: next_line,
settings: &self.settings,
file_index: self.heap.len(),
};
self.heap.push(mergeable_file);
}

View file

@ -51,6 +51,18 @@ fn test_smaller_than_specified_segment() {
.stdout_is_fixture("ext_sort.expected");
}
#[test]
fn test_ext_sort_stable() {
new_ucmd!()
.arg("-n")
.arg("--stable")
.arg("-S")
.arg("0M")
.arg("ext_stable.txt")
.succeeds()
.stdout_only_fixture("ext_stable.expected");
}
#[test]
fn test_extsort_zero_terminated() {
new_ucmd!()
@ -566,6 +578,18 @@ fn test_merge_unique() {
.stdout_only_fixture("merge_ints_interleaved.expected");
}
#[test]
fn test_merge_stable() {
new_ucmd!()
.arg("-m")
.arg("--stable")
.arg("-n")
.arg("merge_stable_1.txt")
.arg("merge_stable_2.txt")
.succeeds()
.stdout_only_fixture("merge_stable.expected");
}
#[test]
fn test_merge_reversed() {
new_ucmd!()

View file

@ -0,0 +1,4 @@
0a
0a
0b
0b

4
tests/fixtures/sort/ext_stable.txt vendored Normal file
View file

@ -0,0 +1,4 @@
0a
0a
0b
0b

View file

@ -0,0 +1,3 @@
0a
0c
0b

View file

@ -0,0 +1,2 @@
0a
0c

View file

@ -0,0 +1 @@
0b