diff --git a/lib/common/rust/api/unp4k_api.dart b/lib/common/rust/api/unp4k_api.dart index 35f6365..12ab0b7 100644 --- a/lib/common/rust/api/unp4k_api.dart +++ b/lib/common/rust/api/unp4k_api.dart @@ -63,13 +63,8 @@ Future dcbRecordToXmlByIndex({required BigInt index}) => RustLib.instance.api.crateApiUnp4KApiDcbRecordToXmlByIndex(index: index); /// 全文搜索 DCB 记录 -Future> dcbSearchAll({ - required String query, - required BigInt maxResults, -}) => RustLib.instance.api.crateApiUnp4KApiDcbSearchAll( - query: query, - maxResults: maxResults, -); +Future> dcbSearchAll({required String query}) => + RustLib.instance.api.crateApiUnp4KApiDcbSearchAll(query: query); /// 导出 DCB 到磁盘 /// merge: true = 合并为单个 XML,false = 分离为多个 XML 文件 diff --git a/lib/common/rust/frb_generated.dart b/lib/common/rust/frb_generated.dart index 4951ae0..77745bb 100644 --- a/lib/common/rust/frb_generated.dart +++ b/lib/common/rust/frb_generated.dart @@ -116,7 +116,6 @@ abstract class RustLibApi extends BaseApi { Future> crateApiUnp4KApiDcbSearchAll({ required String query, - required BigInt maxResults, }); Future> crateApiHttpApiDnsLookupIps({required String host}); @@ -693,35 +692,26 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { @override Future> crateApiUnp4KApiDcbSearchAll({ required String query, - required BigInt maxResults, }) { return handler.executeNormal( NormalTask( callFfi: (port_) { var arg0 = cst_encode_String(query); - var arg1 = cst_encode_usize(maxResults); - return wire.wire__crate__api__unp4k_api__dcb_search_all( - port_, - arg0, - arg1, - ); + return wire.wire__crate__api__unp4k_api__dcb_search_all(port_, arg0); }, codec: DcoCodec( decodeSuccessData: dco_decode_list_dcb_search_result, decodeErrorData: dco_decode_AnyhowException, ), constMeta: kCrateApiUnp4KApiDcbSearchAllConstMeta, - argValues: [query, maxResults], + argValues: [query], apiImpl: this, ), ); } TaskConstMeta get kCrateApiUnp4KApiDcbSearchAllConstMeta => - const TaskConstMeta( - debugName: "dcb_search_all", - argNames: ["query", "maxResults"], - ); + const TaskConstMeta(debugName: "dcb_search_all", argNames: ["query"]); @override Future> crateApiHttpApiDnsLookupIps({required String host}) { diff --git a/lib/common/rust/frb_generated.io.dart b/lib/common/rust/frb_generated.io.dart index 74ba715..b38ab1a 100644 --- a/lib/common/rust/frb_generated.io.dart +++ b/lib/common/rust/frb_generated.io.dart @@ -1450,13 +1450,8 @@ class RustLibWire implements BaseWire { void wire__crate__api__unp4k_api__dcb_search_all( int port_, ffi.Pointer query, - int max_results, ) { - return _wire__crate__api__unp4k_api__dcb_search_all( - port_, - query, - max_results, - ); + return _wire__crate__api__unp4k_api__dcb_search_all(port_, query); } late final _wire__crate__api__unp4k_api__dcb_search_allPtr = @@ -1465,7 +1460,6 @@ class RustLibWire implements BaseWire { ffi.Void Function( ffi.Int64, ffi.Pointer, - ffi.UintPtr, ) > >( @@ -1474,7 +1468,7 @@ class RustLibWire implements BaseWire { late final _wire__crate__api__unp4k_api__dcb_search_all = _wire__crate__api__unp4k_api__dcb_search_allPtr .asFunction< - void Function(int, ffi.Pointer, int) + void Function(int, ffi.Pointer) >(); void wire__crate__api__http_api__dns_lookup_ips( diff --git a/lib/provider/dcb_viewer.dart b/lib/provider/dcb_viewer.dart index 4b3fb1e..b61503e 100644 --- a/lib/provider/dcb_viewer.dart +++ b/lib/provider/dcb_viewer.dart @@ -261,7 +261,7 @@ class DcbViewerModel extends _$DcbViewerModel { state = state.copyWith(isSearching: true, fullTextSearchQuery: query, viewMode: DcbViewMode.searchResults); try { - final apiResults = await unp4k_api.dcbSearchAll(query: query, maxResults: BigInt.from(1000000)); + final apiResults = await unp4k_api.dcbSearchAll(query: query); // 转换为本地数据类型 final results = apiResults.map((r) { diff --git a/lib/provider/dcb_viewer.g.dart b/lib/provider/dcb_viewer.g.dart index 02b8eea..a5d3e03 100644 --- a/lib/provider/dcb_viewer.g.dart +++ b/lib/provider/dcb_viewer.g.dart @@ -41,7 +41,7 @@ final class DcbViewerModelProvider } } -String _$dcbViewerModelHash() => r'94c3542282f64917efadbe14a0ee4967220bec77'; +String _$dcbViewerModelHash() => r'f0af2a7b4451f746288e2c9565a418af80f58835'; abstract class _$DcbViewerModel extends $Notifier { DcbViewerState build(); diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 1d9232b..56d3df8 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -4916,6 +4916,7 @@ dependencies = [ "once_cell", "ort", "parking_lot", + "rayon", "reqwest", "scopeguard", "serde", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index d6d3e2f..2e03f9c 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -34,6 +34,7 @@ serde = { version = "1.0.228", features = ["derive"] } unp4k_rs = { git = "https://github.com/StarCitizenToolBox/unp4k_rs", rev = "29430002d6f3a8d87feabac26c03ae0311c81263" } #unp4k_rs = { path = "../../unp4k_rs" } uuid = { version = "1.19.0", features = ["v4"] } +rayon = "1.10" parking_lot = "0.12.5" crossbeam-channel = "0.5.15" librqbit = { git = "https://github.com/StarCitizenToolBox/rqbit", rev = "f8c0b0927904e1d8b0e28e708bd69fd8069d413a" } diff --git a/rust/src/api/unp4k_api.rs b/rust/src/api/unp4k_api.rs index 6935ba3..3863c00 100644 --- a/rust/src/api/unp4k_api.rs +++ b/rust/src/api/unp4k_api.rs @@ -1,5 +1,6 @@ use anyhow::{anyhow, Result}; use flutter_rust_bridge::frb; +use rayon::prelude::*; use std::collections::HashMap; use std::path::PathBuf; use std::sync::{Arc, Mutex}; @@ -329,7 +330,7 @@ pub struct DcbSearchMatch { } /// 全文搜索 DCB 记录 -pub async fn dcb_search_all(query: String, max_results: usize) -> Result> { +pub async fn dcb_search_all(query: String) -> Result> { tokio::task::spawn_blocking(move || { let reader = GLOBAL_DCB_READER.lock().unwrap(); let df = reader @@ -337,48 +338,58 @@ pub async fn dcb_search_all(query: String, max_results: usize) -> Result= max_results { - break; - } + // 收集所有记录路径和索引 + let records: Vec<(String, usize)> = df + .path_to_record() + .iter() + .map(|(path, &index)| (path.clone(), index)) + .collect(); - // 先检查路径是否匹配 - let path_matches = path.to_lowercase().contains(&query_lower); + // 使用 rayon 并发搜索 + let mut results: Vec = records + .par_iter() + .filter_map(|(path, index)| { + // 先检查路径是否匹配 + let path_matches = path.to_lowercase().contains(&query_lower); - // 尝试获取 XML 并搜索内容 - if let Ok(xml) = df.record_to_xml_by_index(index, true) { - let mut matches = Vec::new(); + // 尝试获取 XML 并搜索内容 + if let Ok(xml) = df.record_to_xml_by_index(*index, true) { + let mut matches = Vec::new(); - for (line_num, line) in xml.lines().enumerate() { - if line.to_lowercase().contains(&query_lower) { - let line_content = if line.len() > 200 { - format!("{}...", &line[..200]) - } else { - line.to_string() - }; - matches.push(DcbSearchMatch { - line_number: line_num + 1, - line_content, - }); + for (line_num, line) in xml.lines().enumerate() { + if line.to_lowercase().contains(&query_lower) { + let line_content = if line.len() > 200 { + format!("{}...", &line[..200]) + } else { + line.to_string() + }; + matches.push(DcbSearchMatch { + line_number: line_num + 1, + line_content, + }); - // 每条记录最多保留 5 个匹配 - if matches.len() >= 5 { - break; + // 每条记录最多保留 5 个匹配 + if matches.len() >= 5 { + break; + } } } - } - if path_matches || !matches.is_empty() { - results.push(DcbSearchResult { - path: path.clone(), - index, - matches, - }); + if path_matches || !matches.is_empty() { + return Some(DcbSearchResult { + path: path.clone(), + index: *index, + matches, + }); + } } - } - } + None + }) + .collect(); + + // 按路径排序以保持结果稳定性 + results.sort_by(|a, b| a.path.cmp(&b.path)); Ok(results) }) diff --git a/rust/src/frb_generated.rs b/rust/src/frb_generated.rs index 3f15a95..bafc977 100644 --- a/rust/src/frb_generated.rs +++ b/rust/src/frb_generated.rs @@ -332,7 +332,6 @@ fn wire__crate__api__unp4k_api__dcb_record_to_xml_by_index_impl( fn wire__crate__api__unp4k_api__dcb_search_all_impl( port_: flutter_rust_bridge::for_generated::MessagePort, query: impl CstDecode, - max_results: impl CstDecode, ) { FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::( flutter_rust_bridge::for_generated::TaskInfo { @@ -342,13 +341,10 @@ fn wire__crate__api__unp4k_api__dcb_search_all_impl( }, move || { let api_query = query.cst_decode(); - let api_max_results = max_results.cst_decode(); move |context| async move { transform_result_dco::<_, _, flutter_rust_bridge::for_generated::anyhow::Error>( (move || async move { - let output_ok = - crate::api::unp4k_api::dcb_search_all(api_query, api_max_results) - .await?; + let output_ok = crate::api::unp4k_api::dcb_search_all(api_query).await?; Ok(output_ok) })() .await, @@ -4649,9 +4645,8 @@ mod io { pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__unp4k_api__dcb_search_all( port_: i64, query: *mut wire_cst_list_prim_u_8_strict, - max_results: usize, ) { - wire__crate__api__unp4k_api__dcb_search_all_impl(port_, query, max_results) + wire__crate__api__unp4k_api__dcb_search_all_impl(port_, query) } #[unsafe(no_mangle)]