From d559db65b5ca446e0bb58716a674ff5ab9640721 Mon Sep 17 00:00:00 2001 From: Ara Sadoyan Date: Wed, 12 Mar 2025 13:09:55 +0100 Subject: [PATCH] Compare dashmaps --- src/utils/compare.rs | 74 +++++++++++++++++++++++++++++------------- src/utils/discovery.rs | 10 +++++- 2 files changed, 60 insertions(+), 24 deletions(-) diff --git a/src/utils/compare.rs b/src/utils/compare.rs index d2abbfd..6b94704 100644 --- a/src/utils/compare.rs +++ b/src/utils/compare.rs @@ -1,29 +1,7 @@ use crate::utils::tools::*; +use std::collections::HashSet; use tokio::sync::RwLockReadGuard; -/* -#[allow(dead_code)] -pub fn dashmaps(map1: &RwLockWriteGuard, map2: &UpstreamMap) -> bool { - if map1.len() != map2.len() { - return false; - } - for entry1 in map1.iter() { - let key = entry1.key(); - let (vec1, _) = entry1.value(); - - if let Some(entry2) = map2.get(key) { - let (vec2, _) = entry2.value(); - if vec1 != vec2 { - return false; - } - } else { - return false; - } - } - true -} -*/ - #[allow(dead_code)] pub fn dm(map1: &RwLockReadGuard, map2: &UpstreamMap) -> bool { if map1.len() != map2.len() { @@ -44,3 +22,53 @@ pub fn dm(map1: &RwLockReadGuard, map2: &UpstreamMap) -> bool { } true } +// #[allow(dead_code)] +pub fn dam(map1: &UpstresmDashMap, map2: &UpstresmDashMap) -> bool { + // Step 1: Check if both maps have the same keys + let keys1: HashSet<_> = map1.iter().map(|entry| entry.key().clone()).collect(); + let keys2: HashSet<_> = map2.iter().map(|entry| entry.key().clone()).collect(); + if keys1 != keys2 { + return false; + } + + // Step 2: Check if the inner maps have the same keys + for entry1 in map1.iter() { + let hostname = entry1.key(); + let inner_map1 = entry1.value(); + + let Some(inner_map2) = map2.get(hostname) else { + return false; // Key exists in map1 but not in map2 + }; + + let inner_keys1: HashSet<_> = inner_map1.iter().map(|e| e.key().clone()).collect(); + let inner_keys2: HashSet<_> = inner_map2.iter().map(|e| e.key().clone()).collect(); + if inner_keys1 != inner_keys2 { + return false; + } + + // Step 3: Compare values (ignore order) + for path_entry in inner_map1.iter() { + let path = path_entry.key(); + let (vec1, _counter1) = path_entry.value(); + + let Some(entry2) = inner_map2.get(path) else { + return false; // Path exists in map1 but not in map2 + }; + let (vec2, _counter2) = entry2.value(); // ✅ Correctly extract values + + // Compare AtomicUsize values + // if counter1.load(Ordering::Relaxed) != counter2.load(Ordering::Relaxed) { + // return false; + // } + + // Convert Vec to HashSet to compare unordered values + let set1: HashSet<_> = vec1.iter().collect(); + let set2: HashSet<_> = vec2.iter().collect(); + if set1 != set2 { + return false; + } + } + } + + true +} diff --git a/src/utils/discovery.rs b/src/utils/discovery.rs index f716b2b..b4200de 100644 --- a/src/utils/discovery.rs +++ b/src/utils/discovery.rs @@ -153,6 +153,7 @@ pub fn build_upstreams(d: &str, kind: &str) -> UpstreamMap { pub fn build_upstreams2(d: &str, kind: &str) -> UpstresmDashMap { let upstreams: UpstresmDashMap = DashMap::new(); + let hopar: UpstresmDashMap = DashMap::new(); let mut contents = d.to_string(); match kind { "filepath" => { @@ -209,7 +210,14 @@ pub fn build_upstreams2(d: &str, kind: &str) -> UpstresmDashMap { .or_insert_with(|| (Vec::new(), AtomicUsize::new(0))) .0 .push((ip.to_string(), port, ssl, proto.to_string())); + let entry = hopar.entry(hostname.to_string()).or_insert_with(DashMap::new); + entry + .entry(path.to_string()) + .or_insert_with(|| (Vec::new(), AtomicUsize::new(0))) + .0 + .push((ip.to_string(), port, ssl, proto.to_string())); } - + // println!("\n\nResult ===> {} <===\n\n", dam(&hopar, &upstreams)); + // println!("{:?}", hopar); upstreams }