int main(int argc, char** argv) { int retval; bool one_pass = false; int i; int sleep_sec = 600; check_stop_daemons(); for (i=1; i<argc; i++) { if (is_arg(argv[i], "one_pass")) { one_pass = true; } else if (is_arg(argv[i], "dont_delete")) { dont_delete = true; } else if (is_arg(argv[i], "d") || is_arg(argv[i], "debug_level")) { if (!argv[++i]) { log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]); usage(argv[0]); exit(1); } int dl = atoi(argv[i]); log_messages.set_debug_level(dl); if (dl == 4) g_print_queries = true; } else if (is_arg(argv[i], "min_age_days")) { if (!argv[++i]) { log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]); usage(argv[0]); exit(1); } min_age_days = atof(argv[i]); } else if (is_arg(argv[i], "max")) { if (!argv[++i]) { log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]); usage(argv[0]); exit(1); } max_number_workunits_to_purge= atoi(argv[i]); } else if (is_arg(argv[i], "daily_dir")) { daily_dir=true; } else if (is_arg(argv[i], "zip")) { compression_type=COMPRESSION_ZIP; } else if (is_arg(argv[i], "gzip")) { compression_type=COMPRESSION_GZIP; } else if (is_arg(argv[i], "max_wu_per_file")) { if(!argv[++i]) { log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]); usage(argv[0]); exit(1); } max_wu_per_file = atoi(argv[i]); } else if (is_arg(argv[i], "no_archive")) { no_archive = true; } else if (is_arg(argv[i], "-sleep")) { if(!argv[++i]) { log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]); usage(argv[0]); exit(1); } sleep_sec = atoi(argv[i]); if (sleep_sec < 1 || sleep_sec > 86400) { log_messages.printf(MSG_CRITICAL, "Unreasonable value of sleep interval: %d seconds\n", sleep_sec ); usage(argv[0]); exit(1); } } else if (is_arg(argv[i], "--help") || is_arg(argv[i], "-help") || is_arg(argv[i], "-h")) { usage(argv[0]); return 0; } else if (is_arg(argv[i], "--version") || is_arg(argv[i], "-version")) { printf("%s\n", SVN_VERSION); exit(0); } else { log_messages.printf(MSG_CRITICAL, "unknown command line argument: %s\n\n", argv[i] ); usage(argv[0]); exit(1); } } retval = config.parse_file(); if (retval) { log_messages.printf(MSG_CRITICAL, "Can't parse config.xml: %s\n", boincerror(retval) ); exit(1); } log_messages.printf(MSG_NORMAL, "Starting\n"); retval = boinc_db.open( config.db_name, config.db_host, config.db_user, config.db_passwd ); if (retval) { log_messages.printf(MSG_CRITICAL, "Can't open DB\n"); exit(2); } install_stop_signal_handler(); boinc_mkdir(config.project_path("archives")); // on exit, either via the check_stop_daemons signal handler, or // through a regular call to exit, these functions will be called // in the opposite order of registration. // atexit(close_db_exit_handler); atexit(close_all_archives); while (1) { if (time_to_quit()) { break; } if (!do_pass() && !one_pass) { log_messages.printf(MSG_NORMAL, "Sleeping....\n"); sleep(sleep_sec); } if (one_pass) { break; } } // files and database are closed by exit handler exit(0); }
//***************************************************************************** // Function : Make Jump Tree // Caller : main() // Purpose : make use of bundle list, component list and interval look-up table to form the structures, consume over 90% (or more) of total execution time // Input : seq // : crik // Return : none // Display : structures, if display priority is lv 2 or lower // Note : 1st dimension - rowI : row i, lower bound of interval with fix size of string length (seq->strLen) // : 2nd dimension - colJ : column j, upper " " // : 3rd dimension - hgtK : height k, number of cmpnt types which may fit into the interval //***************************************************************************** int make_jump_tree(config* seq, global* crik, int start, int end) { disp(seq,DISP_ALL,"################################################################################################ Entering 'make_jump_tree'\n"); disp(seq,DISP_ALL,"Recursion level starts at zero from here\n"); local* todd = init_todd(crik); int16_t i; int16_t hlixBranchngIndx1 = 0; // all branches of hlix are rooted (numbered) from make_jump_tree() crik->hlixInStru = NULL; crik->intrvlCntr = 0; // this reset is necessary because it's just used by make_bundle_list() // Combine bundles into component list if necessary if(seq->bundle) make_bundled_cmpntList(seq, crik); int keepgoing; #ifdef _MPI knob* cmpnts[crik->numCmpnt]; int counter = 0; for(i = 0; i < crik->numCmpntTypOcupid; i++) { cmpnts[counter] = crik->cmpntList[crik->cmpntListOcupidTyp[i]].knob; cmpnts[counter]->newCLindex = counter; counter++; while(cmpnts[counter-1]->cmpntListNext != NULL) { cmpnts[counter] = cmpnts[counter-1]->cmpntListNext; cmpnts[counter]->newCLindex = counter; counter++; } } crik->numCmpnt = counter; int cmpntTracker[counter]; for(i = 0; i < counter; i++) cmpntTracker[i] = cmpnts[i]->newCLindex; crik->mpiCList = cmpnts; make_jump_tree_parallel(seq, crik, todd, cmpnts, cmpntTracker); #else // scan thru the whole cmpnt list for(i = 0; i < crik->numCmpntTypOcupid; i++) { // grab one component on the component type indicated by crik->cmpntListOcupidTyp[i] todd->cmpntLLCursr = crik->cmpntList[crik->cmpntListOcupidTyp[i]].knob; keepgoing = 1; // check if it's worth it to go thru the rest of the components if(!time_to_quit(seq, todd)) { while(todd->cmpntLLCursr) { disp(seq,DISP_ALL,"at 'make_jump_tree' while loop, lvl 0 hlix selected\n"); disp(seq,DISP_ALL,"{%2d-%-2d{ }%2d-%-2d}\n", todd->cmpntLLCursr->opnBrsOutIndx, todd->cmpntLLCursr->opnBrsInnIndx, todd->cmpntLLCursr->closeBrsInnIndx, todd->cmpntLLCursr->closeBrsOutIndx); hlixBranchngIndx1++; clear_old_hlix_link(crik); // from here, a complex series of recursion starts here <----- CORE OF SWELLIX take_cmpnt_list_normal_path(seq, crik, todd, hlixBranchngIndx1); todd->RSTO = NULL; todd->intrvlIns->opnBrsInnIndx = -1; todd->intrvlIns->closeBrsInnIndx = -1; todd->intrvlIns->lvlOfRecur = -1; todd->intrvlIns->intrvlInsFormdFlag = 0; todd->intrvlIns->jumpTreeNext = NULL; todd->intrvlIns->intrvlCntr = 0; todd->intrvlBeh->opnBrsInnIndx = -1; todd->intrvlBeh->closeBrsInnIndx = -1; todd->intrvlBeh->lvlOfRecur = -1; todd->intrvlBeh->intrvlInsFormdFlag = 0; todd->intrvlBeh->jumpTreeNext = NULL; todd->intrvlBeh->intrvlCntr = 0; todd->cmpntLLCursr = todd->cmpntLLCursr->cmpntListNext; } // end while } } // end for #endif exit_curr_recur(seq,crik, todd); return 0; } // end make_jump_tree
// return true if did anything // bool do_pass() { int retval = 0; // The number of workunits/results purged in a single pass of do_pass(). // Since do_pass() may be invoked multiple times, // corresponding global variables store global totals. // int do_pass_purged_workunits = 0; int do_pass_purged_results = 0; // check to see if we got a stop signal. // Note that if we do catch a stop signal here, // we call an exit handler that closes [and optionally compresses] files // before returning to the OS. // check_stop_daemons(); bool did_something = false; DB_WORKUNIT wu; char buf[256]; if (min_age_days) { char timestamp[15]; mysql_timestamp(dtime()-min_age_days*86400., timestamp); sprintf(buf, "where file_delete_state=%d and mod_time<'%s' limit %d", FILE_DELETE_DONE, timestamp, DB_QUERY_LIMIT ); } else { sprintf(buf, "where file_delete_state=%d limit %d", FILE_DELETE_DONE, DB_QUERY_LIMIT ); } int n=0; while (1) { retval = wu.enumerate(buf); if (retval) { if (retval != ERR_DB_NOT_FOUND) { log_messages.printf(MSG_DEBUG, "DB connection lost, exiting\n" ); exit(0); } break; } if (strstr(wu.name, "nodelete")) continue; did_something = true; // if archives have not already been opened, then open them. // if (!no_archive && !wu_stream) { open_all_archives(); } retval = purge_and_archive_results(wu, n); do_pass_purged_results += n; if (!no_archive) { retval= archive_wu(wu); if (retval) { log_messages.printf(MSG_CRITICAL, "Failed to write to XML file workunit:%d\n", wu.id ); exit(5); } log_messages.printf(MSG_DEBUG, "Archived workunit [%d] to a file\n", wu.id ); } // purge workunit from DB // if (!dont_delete) { retval= wu.delete_from_db(); if (retval) { log_messages.printf(MSG_CRITICAL, "Can't delete workunit [%d] from database:%d\n", wu.id, retval ); exit(6); } } log_messages.printf(MSG_DEBUG, "Purged workunit [%d] from database\n", wu.id ); if (config.enable_assignment) { DB_ASSIGNMENT asg; char buf2[256]; sprintf(buf, "workunitid=%d", wu.id); asg.delete_from_db_multi(buf2); } purged_workunits++; do_pass_purged_workunits++; wu_stored_in_file++; if (!no_archive) { fflush(NULL); // if file has got max # of workunits, close and compress it. // This sets file pointers to NULL // if (max_wu_per_file && wu_stored_in_file>=max_wu_per_file) { close_all_archives(); wu_stored_in_file = 0; } } if (time_to_quit()) { break; } } if (do_pass_purged_workunits) { log_messages.printf(MSG_NORMAL, "Archived %d workunits and %d results\n", do_pass_purged_workunits, do_pass_purged_results ); } if (did_something && wu_stored_in_file>0) { log_messages.printf(MSG_DEBUG, "Currently open archive files contain %d workunits\n", wu_stored_in_file ); } if (do_pass_purged_workunits > DB_QUERY_LIMIT/2) { return true; } else { return false; } }