Skip to content

Instantly share code, notes, and snippets.

@josejuan
Created February 11, 2014 09:12
Show Gist options
  • Save josejuan/8931585 to your computer and use it in GitHub Desktop.
Save josejuan/8931585 to your computer and use it in GitHub Desktop.
static IEnumerable<Tuple<string, string>> enumDirectoryHashes(string root) {
var q = new BlockingCollection<Tuple<string, string>>();
Func<SyncLink, IEnumerable<string>, bool> branchs = null;
Func<SyncLink, string, bool> node = (s, path) => {
if(File.Exists(path)) {
var hash = GetMD5HashFromFile(path); // éste se hace también en paralelo
s.End(() => q.Add(Tuple.Create(path, hash)), // sólo la escritura del resultado es sincrónica
() => false);
} else
branchs(s,
Directory.EnumerateFiles(path, "*.*", SearchOption.TopDirectoryOnly).Concat(
Directory.EnumerateDirectories(path, "*.*", SearchOption.TopDirectoryOnly))
.OrderBy(k => k)
);
return false; // podríamos calcular algún total sobre el árbol
};
branchs = (s, paths) => {
if(!paths.Any())
return s.End(() => { }, () => false); // nada que hacer
var head = paths.First();
var tail = paths.Skip(1);
if(!tail.Any())
return node(s, head);
// paralelización n-aria (como decía, basta ir añadiendo nodos
// para convertir un árbol binario en otro n-ario)
return s.Fork(() => { },
ss => node(ss, tail.First()),
ss => branchs(ss, tail.Skip(1)),
(a, b) => false);
};
new Thread(() => {
SyncLink.Run(s => node(s, root));
q.CompleteAdding();
}).Start();
return q.GetConsumingEnumerable();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment