From b0705062557ec5d497cf02d4ece27b0b37da8ce5 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Fri, 2 Jun 2023 14:42:47 -0400 Subject: [PATCH 1/2] tsort: Switch to BTreeHash and BTreeSet Using HashMap and HashSet give a valid topological sort, but the output will change randomly at each run. BTree based structures will guarantee that the output is always ordered in the same way. This also makes the ouptut similar to the output of the C version of the tools, on which some applications rely. --- src/uu/tsort/src/tsort.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/uu/tsort/src/tsort.rs b/src/uu/tsort/src/tsort.rs index a70f32dfd..6e11a7f58 100644 --- a/src/uu/tsort/src/tsort.rs +++ b/src/uu/tsort/src/tsort.rs @@ -6,7 +6,7 @@ // * For the full copyright and license information, please view the LICENSE // * file that was distributed with this source code. use clap::{crate_version, Arg, Command}; -use std::collections::{HashMap, HashSet}; +use std::collections::{BTreeMap, BTreeSet}; use std::fs::File; use std::io::{stdin, BufRead, BufReader, Read}; use std::path::Path; @@ -103,8 +103,8 @@ pub fn uu_app() -> Command { // but using integer may improve performance. #[derive(Default)] struct Graph { - in_edges: HashMap>, - out_edges: HashMap>, + in_edges: BTreeMap>, + out_edges: BTreeMap>, result: Vec, } @@ -122,7 +122,7 @@ impl Graph { } fn init_node(&mut self, n: &str) { - self.in_edges.insert(n.to_string(), HashSet::new()); + self.in_edges.insert(n.to_string(), BTreeSet::new()); self.out_edges.insert(n.to_string(), vec![]); } From 43a8d62b903d254af282cc70a4f52be55e302f63 Mon Sep 17 00:00:00 2001 From: Detlev Casanova Date: Mon, 5 Jun 2023 11:00:47 -0400 Subject: [PATCH 2/2] tsort: Add test for ordered floating nodes Signed-off-by: Detlev Casanova --- tests/by-util/test_tsort.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/by-util/test_tsort.rs b/tests/by-util/test_tsort.rs index 8b01e2a2d..62a74c31d 100644 --- a/tests/by-util/test_tsort.rs +++ b/tests/by-util/test_tsort.rs @@ -20,6 +20,14 @@ fn test_sort_self_loop() { .stdout_only("first\nsecond\n"); } +#[test] +fn test_sort_floating_nodes() { + new_ucmd!() + .pipe_in("d d\nc c\na a\nb b") + .succeeds() + .stdout_only("a\nb\nc\nd\n"); +} + #[test] fn test_no_such_file() { new_ucmd!()