From 7306db8c2f3740fcce73f7931f40aef00eaa76c6 Mon Sep 17 00:00:00 2001 From: spinline Date: Sun, 8 Feb 2026 16:17:30 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20torrent=20diff=20algoritmas=C4=B1=20hash?= =?UTF-8?q?=20tabanl=C4=B1=20hale=20getirilerek=20s=C4=B1ralama=20ba=C4=9F?= =?UTF-8?q?=C4=B1ml=C4=B1l=C4=B1=C4=9F=C4=B1=20kald=C4=B1r=C4=B1ld=C4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/diff.rs | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/backend/src/diff.rs b/backend/src/diff.rs index 607048b..c39787a 100644 --- a/backend/src/diff.rs +++ b/backend/src/diff.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use shared::{AppEvent, NotificationLevel, SystemNotification, Torrent, TorrentUpdate}; #[derive(Debug)] @@ -8,24 +9,32 @@ pub enum DiffResult { } pub fn diff_torrents(old: &[Torrent], new: &[Torrent]) -> DiffResult { - // 1. Structural Check (Length or Order changed) + // 1. Structural Check: Eğer torrent sayısı değişmişse (yeni eklenen veya silinen), + // şimdilik basitlik adına FullUpdate gönderiyoruz. if old.len() != new.len() { return DiffResult::FullUpdate; } - for (i, t) in new.iter().enumerate() { - if old[i].hash != t.hash { + // 2. Hash Set Karşılaştırması: + // Sıralama değişmiş olabilir ama torrentler aynı mı? + let old_map: HashMap<&str, &Torrent> = old.iter().map(|t| (t.hash.as_str(), t)).collect(); + + // Eğer yeni listedeki bir hash eski listede yoksa, yapı değişmiş demektir. + for new_t in new { + if !old_map.contains_key(new_t.hash.as_str()) { return DiffResult::FullUpdate; } } - // 2. Field Updates + // 3. Alan Güncellemeleri (Partial Updates) + // Buraya geldiğimizde biliyoruz ki old ve new listelerindeki torrentler (hash olarak) aynı, + // sadece sıraları farklı olabilir veya içindeki veriler güncellenmiş olabilir. let mut events = Vec::new(); - for (i, new_t) in new.iter().enumerate() { - let old_t = &old[i]; + for new_t in new { + // old_map'ten ilgili torrente hash ile ulaşalım (sıradan bağımsız) + let old_t = old_map.get(new_t.hash.as_str()).unwrap(); - // Initialize with all None let mut update = TorrentUpdate { hash: new_t.hash.clone(), name: None, @@ -42,7 +51,7 @@ pub fn diff_torrents(old: &[Torrent], new: &[Torrent]) -> DiffResult { let mut has_changes = false; - // Compare fields + // Alanları karşılaştır if old_t.name != new_t.name { update.name = Some(new_t.name.clone()); has_changes = true; @@ -63,7 +72,7 @@ pub fn diff_torrents(old: &[Torrent], new: &[Torrent]) -> DiffResult { update.percent_complete = Some(new_t.percent_complete); has_changes = true; - // Check for torrent completion: reached 100% + // Torrent tamamlanma kontrolü if old_t.percent_complete < 100.0 && new_t.percent_complete >= 100.0 { tracing::info!("Torrent completed: {} ({})", new_t.name, new_t.hash); events.push(AppEvent::Notification(SystemNotification { @@ -83,8 +92,7 @@ pub fn diff_torrents(old: &[Torrent], new: &[Torrent]) -> DiffResult { if old_t.status != new_t.status { update.status = Some(new_t.status.clone()); has_changes = true; - - // Log status changes for debugging + tracing::debug!( "Torrent status changed: {} ({}) {:?} -> {:?}", new_t.name, new_t.hash, old_t.status, new_t.status @@ -110,4 +118,4 @@ pub fn diff_torrents(old: &[Torrent], new: &[Torrent]) -> DiffResult { tracing::debug!("Generated {} partial updates", events.len()); DiffResult::Partial(events) } -} +} \ No newline at end of file