Esempio n. 1
0
        public Results.ReconcileResult Reconcile(Results.ScanResult a, Results.ScanResult b)
        {
            var pathsA = new HashSet <string>(a.Keys);
            var pathsB = new HashSet <string>(b.Keys);

            var suspectedConflicts = new HashSet <string>(pathsA);

            suspectedConflicts.IntersectWith(pathsB);

            var unchangedFiles = new HashSet <string>();

            foreach (var entry in suspectedConflicts)
            {
                if (a[entry].Equals(b[entry]))
                {
                    unchangedFiles.Add(entry);
                }
            }

            var conflicts = new HashSet <string>(suspectedConflicts);

            conflicts.RemoveWhere(entry => unchangedFiles.Contains(entry));

            return(new Results.ReconcileResult(
                       this.GeneratePatch(b, a, pathsB, pathsA, unchangedFiles, conflicts),
                       this.GeneratePatch(a, b, pathsA, pathsB, unchangedFiles, conflicts)
                       ));
        }
Esempio n. 2
0
        private Results.PatchResult GeneratePatch(
            Results.ScanResult src, Results.ScanResult target,
            HashSet <string> srcPaths, HashSet <string> targetPaths,
            HashSet <string> unchanged, HashSet <string> conflicts)
        {
            var retVal = new Results.PatchResult();

            var additions = new HashSet <string>(srcPaths);
            int addCount  = additions.RemoveWhere(entry => targetPaths.Contains(entry));

            retVal[Results.ReconcileOperation.ADD] = new List <FileResult>(addCount);
            foreach (var entry in additions)
            {
                retVal[Results.ReconcileOperation.ADD].Add(src[entry]);
            }

            retVal[Results.ReconcileOperation.UNCHANGED] = new List <FileResult>(unchanged.Count);
            foreach (var entry in unchanged)
            {
                retVal[Results.ReconcileOperation.UNCHANGED].Add(src[entry]);
            }

            retVal[Results.ReconcileOperation.CONFLICT] = new List <FileResult>(conflicts.Count);
            foreach (var entry in conflicts)
            {
                retVal[Results.ReconcileOperation.CONFLICT].Add(target[entry]);
            }

            return(retVal);
        }
Esempio n. 3
0
        public Task <Results.ScanResult> ScanDirectory(string root)
        {
            var cutIndex = root.Length + 1;
            var files    = Directory.EnumerateFiles(root, "*", SearchOption.AllDirectories);

            // Return a task that runs this in a parallel foreach
            //  Because Parallel.ForEach doesn't return a task and is not awaitable,
            //  then we have to wrap it in this way.
            //  The resulting code is faster than having a List<Task> that is then sent to Task.WaitAll
            //  since Parallel.ForEach scales better.
            return(Task.Run(
                       () =>
            {
                var scanResult = new Results.ScanResult();
                Parallel.ForEach(files,
                                 (filepath) => {
                    var canonicalPath = filepath.Substring(cutIndex);
                    scanResult[canonicalPath] = this.HashFile(filepath, canonicalPath);
                });

                return scanResult;
            }
                       ));
        }