Ejemplo n.º 1
0
        /// <summary>
        /// Fetches prime numbers from existing result files.
        /// </summary>
        /// <param name="fileHandler">The object handling the result files.</param>
        /// <returns>Container holding information about the loaded prime numbers.</returns>
        public ExistingPrimesLoadingResult FetchExistingPrimes(ResultFileHandler fileHandler)
        {
            //Tell the user the loading has started.
            var startingArgs = new LoadingPrimesFromResultFileStartedArgs();

            OnLoadingPrimesFromResultFileStarted?.Invoke(this, startingArgs);

            //Load the existing primes.
            var result = fetchPrimes(fileHandler.ResultFiles);

            //Store the index of the last result file with room for more prime numbers.
            result.IndexOfLastResultFileToStoreIn = findFirstStorableFileIndex(fileHandler.ResultFiles);

            //Tell the user that the loading finished.
            int numberOfPrimesLoaded      = result.CachedPrimes.Count;
            int numberOfResultFilesLoaded = (int)Math.Ceiling(result.CachedPrimes.Count / (decimal)Configuration.NumberOfPrimesInFile);
            var loadingFinishedArgs       = new LoadingPrimesFromResultFileFinishedArgs(numberOfPrimesLoaded, numberOfResultFilesLoaded);

            OnLoadingPrimesFromResultFileFinished?.Invoke(this, loadingFinishedArgs);

            //Return the result from the loading.
            return(result);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Starts the prime number generation.
        /// </summary>
        public void GeneratePrimes()
        {
            //Set the handler handling the result files.
            FileHandler = new ResultFileHandler();
            FileHandler.OnPrimesWrittenToFile += FileHandler_OnPrimesWrittenToFile;

            //Load existing primes.
            var loader = new ExistingPrimesLoader();

            loader.OnLoadingPrimesFromResultFileStarted  += Loader_OnLoadingPrimesFromResultFileStarted;
            loader.OnLoadingPrimesFromResultFileFinished += Loader_OnLoadingPrimesFromResultFileFinished;
            loader.OnLoadingPrimesFromFile += Loader_OnLoadingPrimesFromFile;
            var loadResult = loader.FetchExistingPrimes(FileHandler);

            //End the execution if the user aborted it.
            if (loadResult.ExecutionWasAborted)
            {
                return;
            }

            //Extract the data from the loading result.
            CachedPrimes       = loadResult.CachedPrimes;
            MemoryLimitReached = loadResult.MemoryLimitReached;
            var numberToCheck = loadResult.NextNumberToCheck;

            //Setup variables for prime number generation.
            bool isPrime = false;

            try
            {
                //Inform the subscriber that the prime number generation has started.
                OnPrimeGenerationStarted?.Invoke(this, new PrimeGenerationStartedArgs());
                FileHandler.PrimeNumberGenerationHasStarted();

                //Skip memory stored generation if the memory was filled by the already generated prime numbers.
                if (!MemoryLimitReached)
                {
                    //Create variable keeping track of were the unstored primes begin.
                    var indexOfFirstUnstoredPrime = CachedPrimes.Count;

                    //Generate the first primes quickly by using only the computer memory.
                    Func <bool> memoryIteration = delegate()
                    {
                        //Check if the number is a prime.
                        isPrime = PrimeChecker.IsPrimeNumber(CachedPrimes, numberToCheck);

                        //Handle prime find.
                        if (isPrime)
                        {
                            try
                            {
                                //Add the prime to the list.
                                CachedPrimes.Add(numberToCheck);
                            }
                            catch (OutOfMemoryException ex)
                            {
                                if (Tools.MemoryIsFilledWithPrimes(ex))
                                {
                                    //We have reached the limit for how many primes the computer memory can hold.
                                    MemoryLimitReached = true;

                                    //Stop using the computer memory when generating prime numbers.
                                    return(false);
                                }
                                else
                                {
                                    //Unknown error. Keep throwing.
                                    throw;
                                }
                            }

                            //Write the primes to a file for reading by the user.
                            if (CachedPrimes.Count % Configuration.NumberOfPrimesInFile == 0)
                            {
                                writePrimesToFile(CachedPrimes, indexOfFirstUnstoredPrime, Configuration.NumberOfPrimesInFile);
                                indexOfFirstUnstoredPrime = CachedPrimes.Count;
                            }
                        }

                        //Prepare checking the next number.
                        numberToCheck++;

                        //Keep generating prime numbers.
                        return(true);
                    };
                    runInfiniteLoopUntilEscapeIsPressed(memoryIteration);

                    //Unless the memory limit is reached, it was the user who stopped the generation.
                    if (!MemoryLimitReached)
                    {
                        return;
                    }

                    //Store the unstored primes.
                    storeUnsavedPrimesAfterMemoryOverflow(CachedPrimes, numberToCheck);
                }

                //Generate the rest of the primes by using the harddrive as memory.
                Func <bool> diskIteration = delegate()
                {
                    throw new NotImplementedException();
                };
                runInfiniteLoopUntilEscapeIsPressed(diskIteration);
            }
            catch (Exception ex)
            {
                ex.Data.Add("CurrentNumberToCheck", numberToCheck);

                //Rethrow the exception.
                throw;
            }
        }