in HashCalculator/Views/PermutateHash.xaml.cs [247:312]
private async Task<bool> CheckAndUpdateAsync(CancellationToken ct)
{
if (Hashes.Items.Count == 0)
return false;
int[] singlePermutation = new int[Hashes.Items.Count];
for (int i = 0; i < Hashes.Items.Count; i++)
singlePermutation[i] = i;
IEnumerable<IEnumerable<int>> permutations;
if (DontChangeHashOrder.IsChecked.Value)
{
permutations = new List<IEnumerable<int>>(1);
List<IEnumerable<int>> single = permutations as List<IEnumerable<int>>;
single.Add(singlePermutation);
}
else
{
permutations = PermutationHelper.GetPermutations<int>(singlePermutation, singlePermutation.Length);
}
// split the permuations into chunks that we run sequenctially to avoid out of memory exception when trying to
// run too many permutations in parallel
var chunks = PermutationHelper.Split<IEnumerable<int>>(permutations, 1024);
bool foundMatch = false;
List<string> results = new List<string>();
// check localities (0..4) and Locality Indicator (locality as bitfield) (1, 2, 4, 8, 16)
int[] startValues = new int[] { 0, 1, 2, 3, 4, 8, 16 };
foreach (int startValue in startValues)
{
foreach (var chunk in chunks)
{
IEnumerable<Task<List<string>>> computePermutatioQuery =
from permutation in chunk select CheckAndUpdateAsync((string)ListOfAlgorithms.SelectedItem, startValue, Hashes.Items.Cast<string>().ToArray<string>(), permutation.ToArray<int>(), ExpectedResultHash.Text.Trim());
List<Task<List<string>>> computePermutation = computePermutatioQuery.ToList();
while (computePermutation.Count > 0)
{
Task<List<string>> finishedPermutation = await Task.WhenAny(computePermutation);
computePermutation.Remove(finishedPermutation);
results = await finishedPermutation;
foundMatch = results.Count > 0;
if (foundMatch || ct.IsCancellationRequested)
{
// cancel the rest
cts.Cancel();
break;
}
}
if (foundMatch || ct.IsCancellationRequested)
break;
}
if (foundMatch || ct.IsCancellationRequested)
break;
}
if (foundMatch)
{
foreach (string result in results)
{
ResultHashes.Items.Add(result);
}
}
return foundMatch;
}