Storage queries run in the background with cancellation and covering indexes so switching views no longer freezes the UI. Co-authored-by: Cursor <cursoragent@cursor.com>
83 lines
2.9 KiB
C#
83 lines
2.9 KiB
C#
namespace Explorer.Domain;
|
|
|
|
public static class VolumeIdentityMatcher
|
|
{
|
|
public sealed record MatchResult(Source? Source, MatchStrength Strength, bool Ambiguous);
|
|
|
|
public enum MatchStrength
|
|
{
|
|
None,
|
|
Weak,
|
|
SerialCapacity,
|
|
Guid
|
|
}
|
|
|
|
public static MatchResult Match(VolumeFingerprint fingerprint, IReadOnlyList<Source> known)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(fingerprint.VolumeGuid))
|
|
{
|
|
var guidHits = known
|
|
.Where(s => !string.IsNullOrEmpty(s.VolumeGuid)
|
|
&& string.Equals(s.VolumeGuid, fingerprint.VolumeGuid, StringComparison.OrdinalIgnoreCase))
|
|
.ToList();
|
|
if (guidHits.Count == 1)
|
|
{
|
|
return new MatchResult(guidHits[0], MatchStrength.Guid, false);
|
|
}
|
|
|
|
if (guidHits.Count > 1)
|
|
{
|
|
return new MatchResult(guidHits[0], MatchStrength.Guid, true);
|
|
}
|
|
}
|
|
|
|
if (fingerprint.VolumeSerial is > 0)
|
|
{
|
|
var serialHits = known.Where(s =>
|
|
s.VolumeSerial == fingerprint.VolumeSerial
|
|
&& string.Equals(s.Filesystem, fingerprint.Filesystem, StringComparison.OrdinalIgnoreCase)
|
|
&& s.CapacityBytes == fingerprint.CapacityBytes)
|
|
.ToList();
|
|
if (serialHits.Count == 1)
|
|
{
|
|
return new MatchResult(serialHits[0], MatchStrength.SerialCapacity, false);
|
|
}
|
|
|
|
if (serialHits.Count == 0 && !string.IsNullOrEmpty(fingerprint.Label))
|
|
{
|
|
serialHits = known.Where(s =>
|
|
s.VolumeSerial == fingerprint.VolumeSerial
|
|
&& string.Equals(s.Label, fingerprint.Label, StringComparison.OrdinalIgnoreCase)
|
|
&& s.CapacityBytes == fingerprint.CapacityBytes)
|
|
.ToList();
|
|
}
|
|
|
|
if (serialHits.Count == 1)
|
|
{
|
|
return new MatchResult(serialHits[0], MatchStrength.Weak, false);
|
|
}
|
|
|
|
if (serialHits.Count > 1)
|
|
{
|
|
return new MatchResult(serialHits[0], MatchStrength.Weak, true);
|
|
}
|
|
}
|
|
|
|
if (fingerprint.Kind is SourceKind.Smb or SourceKind.Nfs)
|
|
{
|
|
var unc = PathRules.CanonicalUncRoot(fingerprint.RootPath);
|
|
var uncHits = known.Where(s =>
|
|
s.Kind == fingerprint.Kind
|
|
&& s.LastRootPath is not null
|
|
&& string.Equals(PathRules.CanonicalUncRoot(s.LastRootPath), unc, StringComparison.OrdinalIgnoreCase))
|
|
.ToList();
|
|
if (uncHits.Count == 1)
|
|
{
|
|
return new MatchResult(uncHits[0], MatchStrength.SerialCapacity, false);
|
|
}
|
|
}
|
|
|
|
return new MatchResult(null, MatchStrength.None, false);
|
|
}
|
|
}
|