38 lines
1.9 KiB
Diff
38 lines
1.9 KiB
Diff
# UNDF: UNDF-2026-000000277
|
|
--- a/src/schema/topology.rs
|
|
+++ b/src/schema/topology.rs
|
|
@@ -210,17 +210,25 @@ impl<T: PartialOrd + Eq + Hash + Clone> FromIterator<T> for TopologicalSort<T>
|
|
impl<T: PartialOrd + Eq + Hash + Clone + Ord> FromIterator<T> for TopologicalSort<T> {
|
|
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> TopologicalSort<T> {
|
|
let mut top = TopologicalSort::new();
|
|
- let mut seen = Vec::<T>::default();
|
|
+ // Use a BTreeSet so that ordering relationships can be inferred via
|
|
+ // range queries (O(log N + K)) instead of a full scan (O(N)) per item,
|
|
+ // reducing the overall complexity from O(N²) to O(N log N).
|
|
+ let mut seen = std::collections::BTreeSet::<T>::default();
|
|
for item in iter {
|
|
let _ = top.insert(item.clone());
|
|
- for seen_item in seen.iter().cloned() {
|
|
- match seen_item.partial_cmp(&item) {
|
|
- Some(Ordering::Less) => {
|
|
- top.add_dependency(seen_item, item.clone());
|
|
- }
|
|
- Some(Ordering::Greater) => {
|
|
- top.add_dependency(item.clone(), seen_item);
|
|
- }
|
|
- _ => (),
|
|
- }
|
|
+ // All previously seen items that are strictly Less: they precede item.
|
|
+ for seen_item in seen.range(..item.clone()).cloned().collect::<Vec<_>>() {
|
|
+ top.add_dependency(seen_item, item.clone());
|
|
+ }
|
|
+ // All previously seen items that are strictly Greater: item precedes them.
|
|
+ for seen_item in seen
|
|
+ .range((std::ops::Bound::Excluded(item.clone()), std::ops::Bound::Unbounded))
|
|
+ .cloned()
|
|
+ .collect::<Vec<_>>()
|
|
+ {
|
|
+ top.add_dependency(item.clone(), seen_item);
|
|
}
|
|
seen.insert(item);
|
|
}
|