private async Task CheckAndUpdateAsync()

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;
        }