improve scanning speed

This commit is contained in:
Lncvrt committed 2026-04-14 23:08:12 -07:00
1 parent 10caf9d56e
commit f98706ed85
2 files changed
+61 -48

No files matched your search

+45 -39
View File
@@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize};
use sysinfo::Disks;
use tauri::{WebviewUrl, WebviewWindowBuilder};
use tauri::{Emitter, WebviewUrl, WebviewWindowBuilder};
use tauri_plugin_shell::ShellExt;
#[cfg(target_os = "macos")]
@@ -53,7 +53,7 @@ async fn get_file_info_from_dirs(
app: tauri::AppHandle,
path: String,
min_ratio: String,
) -> Result<DirScanResult, String> {
) -> Result<(), String> {
let cmd = app
.shell()
.sidecar("pdu")
@@ -70,59 +70,65 @@ async fn get_file_info_from_dirs(
let output = cmd.output().await.map_err(|e| e.to_string())?;
if !output.status.success() {
return Err(format!(
"pdu failed: {}",
String::from_utf8_lossy(&output.stderr)
));
return Err(String::from_utf8_lossy(&output.stderr).to_string());
}
let stdout = String::from_utf8_lossy(&output.stdout);
let json: serde_json::Value =
serde_json::from_str(&stdout).map_err(|e| format!("JSON parse failed: {}", e))?;
let json: serde_json::Value = serde_json::from_str(&stdout).map_err(|e| e.to_string())?;
let mut items = Vec::new();
if let Some(tree) = json.get("tree") {
extract_files(tree, "", &mut items);
let mut batch: Vec<FileInfo> = Vec::new();
stream_extract(tree, "", &mut batch, &app);
}
let total_size = items.iter().map(|i| i.size).sum();
Ok(DirScanResult {
items,
total_size,
error: None,
})
Ok(())
}
fn extract_files(node: &serde_json::Value, parent_path: &str, items: &mut Vec<FileInfo>) {
if let Some(name) = node.get("name").and_then(|v| v.as_str()) {
let size = node.get("size").and_then(|v| v.as_u64()).unwrap_or(0);
let children = node.get("children").and_then(|v| v.as_array());
fn stream_extract(
node: &serde_json::Value,
parent_path: &str,
batch: &mut Vec<FileInfo>,
app: &tauri::AppHandle,
) {
let name = match node.get("name").and_then(|v| v.as_str()) {
Some(n) => n,
None => return,
};
let is_dir = children.as_ref().map(|c| !c.is_empty()).unwrap_or(false);
let size = node.get("size").and_then(|v| v.as_u64()).unwrap_or(0);
let children = node.get("children").and_then(|v| v.as_array());
let path = if parent_path.is_empty() {
name.to_string()
} else {
format!("{}/{}", parent_path, name)
};
let path = if parent_path.is_empty() {
name.to_string()
} else {
format!("{}/{}", parent_path, name)
};
items.push(FileInfo {
name: name.to_string(),
path: path.clone(),
size,
is_dir,
});
let is_dir = children.is_some();
if let Some(children_array) = children {
if !children_array.is_empty() {
for child in children_array {
extract_files(child, &path, items);
}
}
batch.push(FileInfo {
name: name.to_string(),
path: path.clone(),
size,
is_dir,
});
if batch.len() >= 200 {
let _ = app.emit("scan-batch", batch.clone());
batch.clear();
}
if let Some(children) = children {
for child in children {
stream_extract(child, &path, batch, app);
}
}
if parent_path.is_empty() && !batch.is_empty() {
let _ = app.emit("scan-batch", batch.clone());
}
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]