[pve-devel] [PATCH installer 3/7] tui: simplify duplicate disk checking logic

Christoph Heiss c.heiss at proxmox.com
Thu Jul 13 11:49:27 CEST 2023


This reduces the logic from O(n^2) to O(n), which is always a good
thing.

Signed-off-by: Christoph Heiss <c.heiss at proxmox.com>
---
 proxmox-tui-installer/src/views/bootdisk.rs | 39 ++++++++++++---------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/proxmox-tui-installer/src/views/bootdisk.rs b/proxmox-tui-installer/src/views/bootdisk.rs
index 6ef814f..b0557a6 100644
--- a/proxmox-tui-installer/src/views/bootdisk.rs
+++ b/proxmox-tui-installer/src/views/bootdisk.rs
@@ -1,4 +1,4 @@
-use std::{cell::RefCell, marker::PhantomData, rc::Rc};
+use std::{cell::RefCell, collections::HashSet, marker::PhantomData, rc::Rc};
 
 use cursive::{
     view::{Nameable, Resizable, ViewWrapper},
@@ -536,21 +536,11 @@ fn advanced_options_view(disks: &[Disk], options: Rc<RefCell<BootdiskOptions>>)
                 })
                 .flatten();
 
-            if let Some(disks) = options.as_ref().map(|opts| &opts.disks) {
-                if disks.len() > 1 {
-                    for i in 0..(disks.len() - 1) {
-                        let check_disk = &disks[i];
-                        for disk in &disks[(i + 1)..] {
-                            if disk.index == check_disk.index {
-                                siv.add_layer(Dialog::info(format!(
-                                    "cannot select same disk ({}) twice",
-                                    disk.path
-                                )));
-                                return;
-                            }
-                        }
-                    }
-                }
+            if let Err(duplicate) = check_for_duplicate_disks(&options.disks) {
+                siv.add_layer(Dialog::info(format!(
+                    "Cannot select same disk twice: {duplicate}"
+                )));
+                return;
             }
 
             siv.pop_layer();
@@ -562,3 +552,20 @@ fn advanced_options_view(disks: &[Disk], options: Rc<RefCell<BootdiskOptions>>)
     .with_name("advanced-bootdisk-options-dialog")
     .max_size((120, 40))
 }
+
+/// Checks a list of disks for duplicate entries, using their index as key.
+///
+/// # Arguments
+///
+/// * `disks` - A list of disks to check for duplicates.
+fn check_for_duplicate_disks(disks: &[Disk]) -> Result<(), &Disk> {
+    let mut set = HashSet::new();
+
+    for disk in disks {
+        if !set.insert(&disk.index) {
+            return Err(disk);
+        }
+    }
+
+    Ok(())
+}
-- 
2.41.0






More information about the pve-devel mailing list