예제 #1
0
        /// <summary>
        /// Handles the event of the computer memory being filled with loaded prime numbers.
        /// </summary>
        /// <param name="result">The loading result container.</param>
        /// <param name="lastResultFile">The last result file.</param>
        /// <returns>The loading result container.</returns>
        private static ExistingPrimesLoadingResult handleMemoryOverflow(ExistingPrimesLoadingResult result, string lastResultFile)
        {
            result.MemoryLimitReached = true;

            //There was a number when the result files were generated.
            //That number was the next in line to be checked if it was a prime number.
            //Find that number again.
            var lastPrime = File
                            .ReadLines(lastResultFile)
                            .Select(l => BigInteger.Parse(l))
                            .LastOrDefault();
            var nextNumberToCheck = lastPrime + 1;

            //The next number to check we calculated from the last prime in the last file should be bigger or equal
            //to the corresponding number in the result container, otherwise somethings are wrong with the result files.
            if (nextNumberToCheck < result.NextNumberToCheck)
            {
                var message = "Calculation indicates corrupted result files. Make sure all result files exists and that the prime numbers within are sorted ascending.";
                throw new InvalidOperationException(message);
            }

            result.NextNumberToCheck = nextNumberToCheck;

            return(result);
        }
예제 #2
0
        /// <summary>
        /// Fetches prime numbers from existing result files.
        /// </summary>
        /// <param name="indexedResultFiles">All the result files accompanied with their index.</param>
        /// <returns>Container holding information about the loaded prime numbers.</returns>
        private ExistingPrimesLoadingResult fetchPrimes(SortedDictionary <int, string> indexedResultFiles)
        {
            var result = new ExistingPrimesLoadingResult();

            var resultFiles = indexedResultFiles
                              .Select(f => f.Value)
                              .ToList();
            var lastResultFile = resultFiles.LastOrDefault(f => File.ReadLines(f).Any());

            for (int i = 0; i < resultFiles.Count; i++)
            {
                var loadingArgs = new PrimesLoadingFromFile(i, resultFiles.Count);
                OnLoadingPrimesFromFile?.Invoke(this, loadingArgs);

                var subPrimes = File
                                .ReadLines(resultFiles[i])
                                .Select(l => BigInteger.Parse(l));

                //Verify that the file contained any prime numbers.
                if (subPrimes.Any())
                {
                    //Calculate the next number to check if it's a prime number.
                    result.NextNumberToCheck = subPrimes.Last() + 1;
                }
                else
                {
                    //TODO: Test this use case.
                    return(result);
                }

                //Store the loaded primes.
                result = storeSubPrimesInMemory(result, subPrimes, lastResultFile);

                //There's no use in loading any more primes if the memory is full.
                if (result.MemoryLimitReached)
                {
                    return(result);
                }

                //Check if the user cancelled the execution.
                if (userPressedEscape())
                {
                    result.ExecutionWasAborted = true;
                    return(result);
                }
            }

            return(result);
        }
예제 #3
0
        /// <summary>
        /// Adds the loaded sub primes to the container holding all the loaded prime numbers.
        /// </summary>
        /// <param name="result">The loading result container.</param>
        /// <param name="subPrimes">The prime numbers to add to the container.</param>
        /// <param name="lastResultFile">The last result file.</param>
        /// <returns>The loading result container.</returns>
        private static ExistingPrimesLoadingResult storeSubPrimesInMemory(ExistingPrimesLoadingResult result, IEnumerable <BigInteger> subPrimes, string lastResultFile)
        {
            try
            {
                result.CachedPrimes.AddRange(subPrimes);
            }
            catch (OutOfMemoryException ex)
            {
                if (Tools.MemoryIsFilledWithPrimes(ex))
                {
                    return(handleMemoryOverflow(result, lastResultFile));
                }

                throw;
            }

            return(result);
        }