Cleaned the code.

This commit is contained in:
Nicolás A. Ortega 2017-02-02 19:53:29 +01:00
parent 22239ec644
commit a3ec19d47c
No known key found for this signature in database
GPG Key ID: 614272579C2070D1
4 changed files with 96 additions and 95 deletions

View File

@ -31,4 +31,6 @@ Change Log
- Allow user to save found primes to be loaded later. - Allow user to save found primes to be loaded later.
- User can save and read primes in raw output. - User can save and read primes in raw output.
- v1.0: Parallelization - v1.0: Parallelization
- Indivisible is now completely parallelized. - Now completely parallelized.
- Cleaned up/organized the code-base
- Exporting files uses less memory

View File

@ -5,59 +5,60 @@
int inputPrimes(char *file, List *list) { int inputPrimes(char *file, List *list) {
// Assert safeguards // Assert safeguards
assert(file != NULL); assert(file);
assert(list != NULL); assert(list);
FILE *pFile = fopen(file, "r"); FILE *in = fopen(file, "r");
if(pFile == NULL) return 1; if(!in) return 1;
mpz_t n; mpz_t n;
mpz_init(n); mpz_init(n);
while(mpz_inp_raw(n, pFile) != 0) { while(mpz_inp_raw(n, in))
if(addToList(list, n) == 1) return 3; if(addToList(list, n) == 1) return 3;
}
if(fclose(pFile) != 0) return 2; if(fclose(in)) return 2;
return 0; return 0;
} }
int outputPrimes(char *file, List *list) { int outputPrimes(char *file, List *list) {
// Assert safeguards // Assert safeguards
assert(file != NULL); assert(file);
assert(list != NULL); assert(list);
FILE *out = fopen(file, "w");
if(!out) return 1;
FILE *oFile = fopen(file, "w");
if(oFile == NULL) return 1;
printf("Saving primes to `%s'...\n", file); printf("Saving primes to `%s'...\n", file);
puts("0%"); puts("0%");
for(size_t i = 0; i < list->end; ++i) { for(size_t i = 0; i < list->end; ++i) {
if(mpz_out_raw(oFile, list->list[i]) == 0) return 3; if(!mpz_out_raw(out, list->list[i])) return 3;
if(i == list->end / 4) puts("25%"); if(i == list->end / 4) puts("25%");
else if(i == list->end / 2) puts("50%"); else if(i == list->end / 2) puts("50%");
else if(i == list->end * 3 / 4) puts("75%"); else if(i == list->end * 3 / 4) puts("75%");
} }
puts("100%"); puts("100%");
if(fclose(oFile) != 0) return 2;
if(fclose(out)) return 2;
return 0; return 0;
} }
int exportPrimes(char *file, List *list, int base) { int exportPrimes(char *efile, char *dfile, int base) {
// Assert safeguards // Assert safeguards
assert(file != NULL); assert(efile);
assert(list != NULL); assert(dfile);
assert(list->list != NULL);
FILE *eFile = fopen(file, "w"); FILE *in = fopen(dfile, "r");
if(eFile == NULL) return 1; FILE *out = fopen(efile, "w");
printf("Exporting primes to `%s'...\n", file); if(!in || !out) return 1;
puts("0%");
for(size_t i = 0; i < list->end; ++i) { printf("Exporting primes to `%s'...\n", efile);
if(mpz_out_str(eFile, base, list->list[i]) == 0) return 3; mpz_t n;
fprintf(eFile, "\n"); mpz_init(n);
if(i == list->end / 4) puts("25%"); while(mpz_inp_raw(n, in)) {
else if(i == list->end / 2) puts("50%"); if(!mpz_out_str(out, base, n)) return 3;
else if(i == list->end * 3 / 4) puts("75%"); fprintf(out, "\n");
} }
puts("100%");
if(fclose(eFile) != 0) return 2; if(fclose(in) || fclose(out)) return 2;
puts("Finished exporting primes.");
return 0; return 0;
} }

View File

@ -28,10 +28,10 @@ int outputPrimes(char *file, List *list);
/** /**
* @brief Export primes from a List to a plain text file. * @brief Export primes from a List to a plain text file.
* @param file File to output primes as plain text to. * @param efile File to export primes as plain text to.
* @param list List to read primes from. * @param dfile File to read primes from.
* @param base The base in which the primes will be written. * @param base The base in which the primes will be written.
* @returns If 0 then load was successful, if 1 then failed to open, * @returns If 0 then load was successful, if 1 then failed to open,
* if 2 failed to close, if 3 failed when writing. * if 2 failed to close, if 3 failed when writing.
*/ */
int exportPrimes(char *file, List *list, int base); int exportPrimes(char *efile, char *dfile, int base);

View File

@ -24,7 +24,7 @@ int main(int argc, char *argv[]) {
f_version = false, f_version = false,
f_quiet = false; f_quiet = false;
int base = 10; int base = 10;
char *file = NULL; char *dfile = NULL;
char *efile = NULL; char *efile = NULL;
// Parse commandline arguments // Parse commandline arguments
@ -50,7 +50,7 @@ int main(int argc, char *argv[]) {
} }
break; break;
case 'f': case 'f':
file = optarg; dfile = optarg;
break; break;
case 'e': case 'e':
efile = optarg; efile = optarg;
@ -75,37 +75,52 @@ int main(int argc, char *argv[]) {
} else if(f_version) { } else if(f_version) {
printf("Indivisible %s\n", VERSION); printf("Indivisible %s\n", VERSION);
return 0; return 0;
} else if(f_quiet && !dfile) {
puts("Error: you cannot run in quiet mode without specifying a data file.");
printUsage(argv[0]);
return 0;
}
if(efile && !dfile) {
puts("Error: you must have a file to export to.");
printUsage(argv[0]);
return 0;
} else if(efile && dfile) {
exportPrimes(efile, dfile, base);
return 0;
}
if(!omp_get_cancellation()) {
puts("Warning: the OpenMP cancellation environment variable (`OMP_CANCELLATION') is not enabled.");
char in;
while(true) {
printf("[e]nable/[c]ontinue/[q]uit? ");
scanf("%c", &in);
if(in == 'e' || in == 'E') {
putenv("OMP_CANCELLATION=true");
execv(argv[0], argv);
} else if(in == 'c' || in == 'C') {
break;
} else if(in == 'q' || in == 'Q') {
return 0;
}
}
} }
// Quit on ^C by setting `run = false' // Quit on ^C by setting `run = false'
run = true; run = true;
signal(SIGINT, leave); signal(SIGINT, leave);
if(efile != NULL && file == NULL) { puts("Use Ctrl+C to exit.");
fprintf(stderr, "There must be an input file to export! Use `-h' for help.\n");
return 1;
}
bool newFile = true; bool newFile = true;
if(file != NULL) { if(dfile) {
struct stat s; struct stat s;
if(stat(file, &s) == 0) newFile = false; if(stat(dfile, &s) == 0) newFile = false;
} }
int exitCode = 0; int exitCode = 0;
if(!omp_get_cancellation() && efile == NULL) {
puts("Warning: the OpenMP cancellation (`OMP_CANCELLATION') environment variable is not enabled.");
char cont = '\0';
while(true) {
printf("Continue? (y/n) ");
scanf("%c", &cont);
if(cont == 'y' || cont == 'Y')
break;
else if(cont == 'n' || cont == 'N')
return exitCode;
}
}
// Primes we've found // Primes we've found
List primes; List primes;
if(initList(&primes) == 1) { if(initList(&primes) == 1) {
@ -117,19 +132,25 @@ int main(int argc, char *argv[]) {
mpz_t num; mpz_t num;
mpz_init(num); mpz_init(num);
if(efile == NULL) puts("Use Ctrl+C to exit."); // Variable for sqrt of `num'
mpz_t numRoot;
mpz_init(numRoot);
// Index of the prime number above and closest to `numRoot'
size_t rootInd = 0;
if(newFile) { if(newFile) {
// Add 2, a known prime to this list // Add 2, a known prime to this list
mpz_set_ui(num, 2); mpz_set_ui(num, 2);
if(addToList(&primes, num) == 1) { if(addToList(&primes, num) == 1) {
fprintf(stderr, "Failed to allocate more memory for list.\n"); fprintf(stderr, "Failed to allocate more memory for list.\n");
exitCode = 1;
goto releaseMemory; goto releaseMemory;
} }
// Add 3 as well to optimize the algorithm // Add 3 as well to optimize the algorithm
mpz_set_ui(num, 3); mpz_set_ui(num, 3);
if(addToList(&primes, num) == 1) { if(addToList(&primes, num) == 1) {
fprintf(stderr, "Failed to allocate more memory for list.\n"); fprintf(stderr, "Failed to allocate more memory for list.\n");
exitCode = 1;
goto releaseMemory; goto releaseMemory;
} }
if(!f_quiet) { if(!f_quiet) {
@ -137,52 +158,31 @@ int main(int argc, char *argv[]) {
} }
} else { } else {
// Load primes from file // Load primes from file
int err = inputPrimes(file, &primes); int err = inputPrimes(dfile, &primes);
if(err == 0) { if(err == 0) {
printf("Loaded %zu primes.\n", primes.end); printf("Loaded %zu primes.\n", primes.end);
} else { } else {
if(err == 1) if(err == 1)
fprintf(stderr, "Failed to open Indivisible file `%s'.\n", file); fprintf(stderr, "Failed to open Indivisible file `%s'.\n", dfile);
else if(err == 2) else if(err == 2)
fprintf(stderr, "Failed to close Indivisible file `%s'.\n", file); fprintf(stderr, "Failed to close Indivisible file `%s'.\n", dfile);
else if(err == 3) else if(err == 3)
fprintf(stderr, "Failed to allocate more memory for list.\n"); fprintf(stderr, "Failed to allocate more memory for list.\n");
exitCode = 1; exitCode = 1;
goto releaseMemory; goto releaseMemory;
} }
/** /**
* Yes, I realize there's a -1 here, I don't know why but it won't * I set to `primes.end-1' because primes.end indicates the next new
* work if it's not there, so don't change it unless necessary. * element in the list that can be used, which is also equal to the total
* number of elements in the list.
*/ */
mpz_set(num, primes.list[primes.end-1]); mpz_set(num, primes.list[primes.end-1]);
} }
if(efile != NULL) { while(run) {
int err = exportPrimes(efile, &primes, base);
if(err == 0) {
puts("Successfully exported primes.");
} else {
if(err == 1)
fprintf(stderr, "Failed to open/create plain text file `%s'.\n", efile);
else if(err == 2)
fprintf(stderr, "Failed to close plain text file `%s'.\n", efile);
else if(err == 3)
fprintf(stderr, "Failed to write prime to plain text file `%s'.\n", efile);
exitCode = 1;
}
goto releaseMemory;
}
// Variable for sqrt of `privNum'
mpz_t numRoot;
mpz_init(numRoot);
mpz_add_ui(num, num, 2); mpz_add_ui(num, num, 2);
size_t rootInd = 0;
while(run) {
// Calculate the sqrt(num) // Calculate the sqrt(num)
mpz_sqrt(numRoot, num); mpz_sqrt(numRoot, num);
@ -216,32 +216,31 @@ int main(int argc, char *argv[]) {
// `num' is a prime so we add it to the list and print it // `num' is a prime so we add it to the list and print it
if(addToList(&primes, num) == 1) { if(addToList(&primes, num) == 1) {
fprintf(stderr, "Failed to allocate more memory for list.\n"); fprintf(stderr, "Failed to allocate more memory for list.\n");
exitCode = 1;
goto releaseMemory; goto releaseMemory;
} }
if(!f_quiet) { if(!f_quiet) {
if(mpz_out_str(stdout, base, num) == 0) if(!mpz_out_str(stdout, base, num))
fprintf(stderr, "Could not print to `stdout'!\n"); fprintf(stderr, "Could not print to `stdout'!\n");
printf("\n"); printf("\n");
} }
} }
mpz_add_ui(num, num, 2);
} }
printf("Found %zu primes.\n", primes.end); printf("Found %zu primes.\n", primes.end);
if(file != NULL) { if(dfile) {
int err = outputPrimes(file, &primes); int err = outputPrimes(dfile, &primes);
if(err == 0) { if(err == 0) {
puts("Successfully saved primes."); puts("Successfully saved primes.");
} else { } else {
if(err == 1) if(err == 1)
fprintf(stderr, "Failed to open/create file `%s'.\n", file); fprintf(stderr, "Failed to open/create file `%s'.\n", dfile);
else if(err == 2) else if(err == 2)
fprintf(stderr, "Failed to close file `%s'.\n", file); fprintf(stderr, "Failed to close file `%s'.\n", dfile);
else if(err == 3) else if(err == 3)
fprintf(stderr, "Failed while writing a prime to `%s'.\n", file); fprintf(stderr, "Failed while writing a prime to `%s'.\n", dfile);
exitCode = 1; exitCode = 1;
goto releaseMemory; goto releaseMemory;
} }
@ -261,8 +260,7 @@ releaseMemory:
} }
void printUsage(char *progName) { void printUsage(char *progName) {
printf("%s [-f <file>] [-q] [-b <base>]\n", progName); printf("%s [[-f <file> [-e <file> | -q]] [-b <base>] | [-h] | [-v]]\n", progName);
printf("%s -f <file> -e <file>\n", progName);
} }
void leave() { run = false; } void leave() { run = false; }