public int CompareTo(IComparableFile otherFile, CancellationToken cancellationToken) { Debug.Assert(otherFile is ComparableFileHash, Resources.Error_ComparableFileHash_CompareTo_File_Comparer_type_mismatch); Debug.Assert(FileData.Size == ((ComparableFileHash)otherFile).FileData.Size, Resources.Error_ComparableFileHash_CompareTo_Fragment_Size_Mismatch); var otherFileHashComparer = (ComparableFileHash)otherFile; if (TotalFragments != otherFileHashComparer.TotalFragments) { return(CompleteMismatch); } for (var fragmentIndex = 0; fragmentIndex < TotalFragments; ++fragmentIndex) { var thisHash = GetFragmentHash(fragmentIndex); var otherHash = otherFileHashComparer.GetFragmentHash(fragmentIndex); // ReSharper disable once LoopCanBeConvertedToQuery for (var index = 0; index < thisHash.Length; ++index) { if (thisHash[index] != otherHash[index]) { return(CompleteMismatch); } } cancellationToken.ThrowIfCancellationRequested(); } return(CompleteMatch); }
private List <MatchResult> GetFileDuplicates(IComparableFile fileToFind, IEnumerable <IComparableFile> fileGroup, SearchContext context, CancellationToken cancellationToken) { var duplicates = new List <MatchResult>(); var matchThreshold = context.ComparerConfig.MatchThreshold.Value; var completeMatch = context.ComparerConfig.CompleteMatch.Value; var completeMismatch = context.ComparerConfig.CompleteMismatch.Value; foreach (var fileFromGroup in fileGroup) { if (ReferenceEquals(fileFromGroup, fileToFind)) { continue; //Skip self } int matchValue; try { if ((matchValue = fileToFind.CompareTo(fileFromGroup, cancellationToken)) < matchThreshold) { continue; } } catch (OperationCanceledException) { throw; } catch (FileSystemException ex) { OnFileSystemError(ex.FileFullName, ex.Message, ex); continue; } catch (Exception ex) { OnFileSystemError(fileFromGroup.FileData.FullName, ex.Message, ex); continue; } if (duplicates.Count == 0) { duplicates.Add(new MatchResult { ComparableFile = fileToFind, MatchValue = completeMatch, CompleteMatch = completeMatch, CompleteMismatch = completeMismatch }); } duplicates.Add(new MatchResult { ComparableFile = fileFromGroup, MatchValue = matchValue, CompleteMatch = completeMatch, CompleteMismatch = completeMismatch }); } return(duplicates); }
private static bool ContainsFile(IEnumerable <List <MatchResult> > filesWhereToLook, IComparableFile fileToFind) { // ReSharper disable once LoopCanBeConvertedToQuery foreach (var groupFiles in filesWhereToLook) { // ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator foreach (var file in groupFiles) { if (ReferenceEquals(fileToFind, file.ComparableFile)) { return(true); } } } return(false); }
private List <IComparableFile[]> FindSync( IReadOnlyCollection <FileData> srcFiles, ICandidatePredicate duplicateCandidatePredicate, IComparableFileFactory comparableFileFactory, CancellationToken cancellationToken) { //var stopwatch = Stopwatch.StartNew(); var duplicateCandidates = new List <IComparableFile[]>(256); var fileIndex = 0; var filesCount = srcFiles.Count; var candidatesTotalSize = 0L; var candidateFilesCount = 0; foreach (var currentFile in srcFiles) { try { bool IsCurrentFileAlreadyAdded(IComparableFile[] candidatesSet) { foreach (var candidateFile in candidatesSet) { if (ReferenceEquals(candidateFile.FileData, currentFile)) { return(true); } } return(false); } if (duplicateCandidates.AsParallel().Any(IsCurrentFileAlreadyAdded)) { continue; } var candidates = srcFiles .AsParallel() .WithCancellation(cancellationToken) .Where(file => duplicateCandidatePredicate.IsCandidate(file, currentFile)) .ToArray(); var candidatesLength = candidates.Length; if (candidatesLength < 2) { continue; } var candidatesGroup = new IComparableFile[candidatesLength]; for (var index = 0; index < candidatesLength; index++) { var candidateFileData = candidates[index]; candidatesGroup[index] = comparableFileFactory.Create(candidateFileData); candidatesTotalSize += candidateFileData.Size; } candidateFilesCount += candidatesLength; duplicateCandidates.Add(candidatesGroup); } catch (OperationCanceledException) { throw; } catch (Exception ex) { OnFileSystemError(currentFile.FullName, ex); } finally { OnScanningPath(currentFile.FullName, fileIndex++, filesCount, duplicateCandidates.Count, candidateFilesCount, candidatesTotalSize); } } //stopwatch.Stop(); //var elapsed = TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds); //System.Windows.MessageBox.Show($"Candidates search time: {elapsed:c}"); return(duplicateCandidates); }