mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-11-03 05:45:04 -05:00
Search every source across paired devices
Library-wide search now fans out over peer replicas alongside the local volume indexes, so one query answers for every device's sources from memory. Path-scoped search on another device's path resolves the covering replica the same way directory listings do. Library-wide hits also carry the owning device's slug; they previously went out with an empty slug, which made results unaddressable even locally.
This commit is contained in:
1 parent
3ac1f0af78
commit
50fdbad59d
2 files changed
+73
-3
No files matched your search
@@ -19,10 +19,12 @@ use std::path::PathBuf;
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Search one partition of the volume index, scoped to a path within it.
|
||||
/// A scope on another device is served from that device's replica.
|
||||
pub async fn search_ephemeral_index(
|
||||
query: &str,
|
||||
path_scope: &SdPath,
|
||||
filters: &SearchFilters,
|
||||
context: &std::sync::Arc<crate::context::CoreContext>,
|
||||
cache: &EphemeralIndexCache,
|
||||
file_type_registry: &FileTypeRegistry,
|
||||
) -> Result<Vec<FileSearchResult>, QueryError> {
|
||||
@@ -34,6 +36,33 @@ pub async fn search_ephemeral_index(
|
||||
return Ok(Vec::new());
|
||||
};
|
||||
|
||||
if *device_slug != crate::device::get_current_device_slug() {
|
||||
let shares = crate::service::mounts::peer::remote_shares().await;
|
||||
let Some(share) = shares.iter().find(|share| {
|
||||
local_path.starts_with(&share.info.root)
|
||||
&& context
|
||||
.device_manager
|
||||
.get_device_slug(share.device_id)
|
||||
.is_some_and(|slug| slug == *device_slug)
|
||||
}) else {
|
||||
return Ok(Vec::new());
|
||||
};
|
||||
|
||||
let matching_paths = {
|
||||
let index = share.index.read().await;
|
||||
matches_in(&index, query, Some(local_path))
|
||||
};
|
||||
return collect_results(
|
||||
&share.index,
|
||||
matching_paths,
|
||||
query,
|
||||
device_slug,
|
||||
filters,
|
||||
file_type_registry,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
// A registered source that has not been touched this session restores from
|
||||
// its snapshot here, including detached drives, whose indexes serve
|
||||
// read-only.
|
||||
@@ -60,14 +89,17 @@ pub async fn search_ephemeral_index(
|
||||
}
|
||||
|
||||
/// Search every partition, which is what a library-wide search is now that
|
||||
/// every attached drive is mapped.
|
||||
/// every attached drive is mapped — including paired devices' sources,
|
||||
/// whose replicated indexes answer from memory just like the local ones.
|
||||
pub async fn search_every_index(
|
||||
query: &str,
|
||||
filters: &SearchFilters,
|
||||
context: &std::sync::Arc<crate::context::CoreContext>,
|
||||
cache: &EphemeralIndexCache,
|
||||
file_type_registry: &FileTypeRegistry,
|
||||
) -> Result<Vec<FileSearchResult>, QueryError> {
|
||||
let mut results = Vec::new();
|
||||
let local_slug = crate::device::get_current_device_slug();
|
||||
|
||||
for index_arc in cache.all_indexes() {
|
||||
let matching_paths = {
|
||||
@@ -80,7 +112,37 @@ pub async fn search_every_index(
|
||||
&index_arc,
|
||||
matching_paths,
|
||||
query,
|
||||
"",
|
||||
&local_slug,
|
||||
filters,
|
||||
file_type_registry,
|
||||
)
|
||||
.await?,
|
||||
);
|
||||
}
|
||||
|
||||
for share in crate::service::mounts::peer::remote_shares().await {
|
||||
// A hit is addressed by its owning device's slug, which is what
|
||||
// routes a listing or preview of it back through the replica.
|
||||
let Some(slug) = context.device_manager.get_device_slug(share.device_id) else {
|
||||
tracing::debug!(
|
||||
"replica of {} has no slug for device {}; skipping in search",
|
||||
share.info.root.display(),
|
||||
share.device_id
|
||||
);
|
||||
continue;
|
||||
};
|
||||
|
||||
let matching_paths = {
|
||||
let index = share.index.read().await;
|
||||
matches_in(&index, query, None)
|
||||
};
|
||||
|
||||
results.extend(
|
||||
collect_results(
|
||||
&share.index,
|
||||
matching_paths,
|
||||
query,
|
||||
&slug,
|
||||
filters,
|
||||
file_type_registry,
|
||||
)
|
||||
|
||||
@@ -91,13 +91,21 @@ impl FileSearchQuery {
|
||||
&self.input.query,
|
||||
path,
|
||||
&self.input.filters,
|
||||
&context,
|
||||
cache,
|
||||
registry,
|
||||
)
|
||||
.await?
|
||||
}
|
||||
SearchScope::Library => {
|
||||
search_every_index(&self.input.query, &self.input.filters, cache, registry).await?
|
||||
search_every_index(
|
||||
&self.input.query,
|
||||
&self.input.filters,
|
||||
&context,
|
||||
cache,
|
||||
registry,
|
||||
)
|
||||
.await?
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user