Merge pull request #2194 from miDeb/sort-stable-merge

sort: make merging stable
This commit is contained in:
Sylvestre Ledru 2021-05-12 08:38:48 +02:00 committed by GitHub
commit 6635301f32
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 48 additions and 1 deletions

View file

@ -705,6 +705,7 @@ struct MergeableFile<'a> {
lines: Box<dyn Iterator<Item = Line> + 'a>, lines: Box<dyn Iterator<Item = Line> + 'a>,
current_line: Line, current_line: Line,
settings: &'a GlobalSettings, settings: &'a GlobalSettings,
file_index: usize,
} }
// BinaryHeap depends on `Ord`. Note that we want to pop smallest items // BinaryHeap depends on `Ord`. Note that we want to pop smallest items
@ -712,7 +713,14 @@ struct MergeableFile<'a> {
// trick it into the right order by calling reverse() here. // trick it into the right order by calling reverse() here.
impl<'a> Ord for MergeableFile<'a> { impl<'a> Ord for MergeableFile<'a> {
fn cmp(&self, other: &MergeableFile) -> Ordering { 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()
} }
} }
@ -748,6 +756,7 @@ impl<'a> FileMerger<'a> {
lines, lines,
current_line: next_line, current_line: next_line,
settings: &self.settings, settings: &self.settings,
file_index: self.heap.len(),
}; };
self.heap.push(mergeable_file); self.heap.push(mergeable_file);
} }

View file

@ -51,6 +51,18 @@ fn test_smaller_than_specified_segment() {
.stdout_is_fixture("ext_sort.expected"); .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] #[test]
fn test_extsort_zero_terminated() { fn test_extsort_zero_terminated() {
new_ucmd!() new_ucmd!()
@ -566,6 +578,18 @@ fn test_merge_unique() {
.stdout_only_fixture("merge_ints_interleaved.expected"); .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] #[test]
fn test_merge_reversed() { fn test_merge_reversed() {
new_ucmd!() 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