// print a single job ad // static void printJob(ClassAd & ad) { if (longformat) { if (use_xml) { fPrintAdAsXML(stdout, ad); } else { fPrintAd(stdout, ad); } printf("\n"); } else { if (customFormat) { mask.display(stdout, &ad); } else { displayJobShort(&ad); } } }
// Read the history from a single file and print it out. static void readHistoryFromFile(char *JobHistoryFileName, char* constraint, ExprTree *constraintExpr) { int EndFlag = 0; int ErrorFlag = 0; int EmptyFlag = 0; AttrList *ad = NULL; long offset = 0; bool BOF = false; // Beginning Of File MyString buf; FILE* LogFile=safe_fopen_wrapper(JobHistoryFileName,"r"); if (!LogFile) { fprintf(stderr,"History file (%s) not found or empty.\n", JobHistoryFileName); exit(1); } // In case of rotated history files, check if we have already reached the number of // matches specified by the user before reading the next file if (specifiedMatch != 0) { if (matchCount == specifiedMatch) { // Already found n number of matches, cleanup fclose(LogFile); return; } } if (backwards) { offset = findLastDelimiter(LogFile, JobHistoryFileName); } while(!EndFlag) { if (backwards) { // Read history file backwards if (BOF) { // If reached beginning of file break; } offset = findPrevDelimiter(LogFile, JobHistoryFileName, offset); if (offset == -1) { // Unable to match constraint break; } else if (offset != 0) { fseek(LogFile, offset, SEEK_SET); buf.readLine(LogFile); // Read one line to skip delimiter and adjust to actual offset of ad } else { // Offset set to 0 BOF = true; fseek(LogFile, offset, SEEK_SET); } } if( !( ad=new AttrList(LogFile,"***", EndFlag, ErrorFlag, EmptyFlag) ) ){ fprintf( stderr, "Error: Out of memory\n" ); exit( 1 ); } if( ErrorFlag ) { printf( "\t*** Warning: Bad history file; skipping malformed ad(s)\n" ); ErrorFlag=0; if(ad) { delete ad; ad = NULL; } continue; } if( EmptyFlag ) { EmptyFlag=0; if(ad) { delete ad; ad = NULL; } continue; } if (!constraint || EvalBool(ad, constraintExpr)) { if (longformat) { ad->fPrint(stdout); printf("\n"); } else { if (customFormat) { mask.display(stdout, ad); } else { displayJobShort(ad); } } matchCount++; // if control reached here, match has occured if (specifiedMatch != 0) { // User specified a match number if (matchCount == specifiedMatch) { // Found n number of matches, cleanup if (ad) { delete ad; ad = NULL; } fclose(LogFile); return; } } } if(ad) { delete ad; ad = NULL; } } fclose(LogFile); return; }
QuillErrCode HistorySnapshot::printResults(SQLQuery *queryhor, SQLQuery *queryver, bool longformat, bool fileformat, bool custForm, AttrListPrintMask *pmask, const char *constraint /* = "" */) { AttrList *ad = 0; QuillErrCode st = QUILL_SUCCESS; // initialize index variables off_t offset = 0, last_line = 0; cur_historyads_hor_index = 0; cur_historyads_ver_index = 0; if (!longformat && !custForm) { short_header(); } ExprTree *tree = NULL; if (constraint) { ParseClassAdRvalExpr(constraint, tree); } while(1) { st = getNextAd_Hor(ad, queryhor); if(st != QUILL_SUCCESS) break; if (longformat || constraint) { st = getNextAd_Ver(ad, queryver); if (constraint && EvalBool(ad, tree) == FALSE) { continue; } // in the case of vertical, we dont want to quit if we run // out of tuples because 1) we want to display whats in the ad // and 2) the horizontal cursor will correctly determine when // to stop - this is because in all cases, we only pull out those // tuples from vertical which join with a horizontal tuple if(st != QUILL_SUCCESS && st != DONE_HISTORY_VER_CURSOR) break; if (fileformat) { // Print out the job ads in history file format, i.e., print the *** delimiters MyString owner, ad_str, temp; int compl_date; ad->sPrint(ad_str); if (!ad->LookupString(ATTR_OWNER, owner)) owner = "NULL"; if (!ad->LookupInteger(ATTR_COMPLETION_DATE, compl_date)) compl_date = 0; temp.formatstr("*** Offset = %ld ClusterId = %d ProcId = %d Owner = \"%s\" CompletionDate = %d\n", offset - last_line, curClusterId_hor, curProcId_hor, owner.Value(), compl_date); offset += ad_str.Length() + temp.Length(); last_line = temp.Length(); fprintf(stdout, "%s", ad_str.Value()); fprintf(stdout, "%s", temp.Value()); } else if (longformat) { ad->fPrint(stdout); printf("\n"); } } if (!longformat) { if (custForm == true) { ASSERT(pmask != NULL); pmask->display(stdout, ad); } else { displayJobShort(ad); } } } if(ad != NULL) { delete ad; ad = NULL; } if(st == FAILURE_QUERY_HISTORYADS_HOR || st == FAILURE_QUERY_HISTORYADS_VER) return st; return QUILL_SUCCESS; }
// Read the history from a single file and print it out. static void readHistoryFromFileOld(const char *JobHistoryFileName, const char* constraint, ExprTree *constraintExpr) { int EndFlag = 0; int ErrorFlag = 0; int EmptyFlag = 0; ClassAd *ad = NULL; long offset = 0; bool BOF = false; // Beginning Of File MyString buf; int flags = 0; if( !backwards ) { // Currently, the file position manipulations used in -backwards // do not work with files > 2GB on platforms with 32-bit file // offsets. flags = O_LARGEFILE; } int LogFd = safe_open_wrapper_follow(JobHistoryFileName,flags,0); if (LogFd < 0) { fprintf(stderr,"Error opening history file %s: %s\n", JobHistoryFileName,strerror(errno)); #ifdef EFBIG if( (errno == EFBIG) && backwards ) { fprintf(stderr,"The -backwards option does not support files this large.\n"); } #endif exit(1); } FILE *LogFile = fdopen(LogFd,"r"); if (!LogFile) { fprintf(stderr,"Error opening history file %s: %s\n", JobHistoryFileName,strerror(errno)); exit(1); } // In case of rotated history files, check if we have already reached the number of // matches specified by the user before reading the next file if (specifiedMatch != 0) { if (matchCount == specifiedMatch) { // Already found n number of matches, cleanup fclose(LogFile); return; } } if (backwards) { offset = findLastDelimiter(LogFile, JobHistoryFileName); } if(longformat && use_xml) { std::string out; AddClassAdXMLFileHeader(out); printf("%s\n", out.c_str()); } while(!EndFlag) { if (backwards) { // Read history file backwards if (BOF) { // If reached beginning of file break; } offset = findPrevDelimiter(LogFile, JobHistoryFileName, offset); if (offset == -1) { // Unable to match constraint break; } else if (offset != 0) { fseek(LogFile, offset, SEEK_SET); buf.readLine(LogFile); // Read one line to skip delimiter and adjust to actual offset of ad } else { // Offset set to 0 BOF = true; fseek(LogFile, offset, SEEK_SET); } } if( !( ad=new ClassAd(LogFile,"***", EndFlag, ErrorFlag, EmptyFlag) ) ){ fprintf( stderr, "Error: Out of memory\n" ); exit( 1 ); } if( ErrorFlag ) { printf( "\t*** Warning: Bad history file; skipping malformed ad(s)\n" ); ErrorFlag=0; if(ad) { delete ad; ad = NULL; } continue; } if( EmptyFlag ) { EmptyFlag=0; if(ad) { delete ad; ad = NULL; } continue; } if (!constraint || constraint[0]=='\0' || EvalBool(ad, constraintExpr)) { if (longformat) { if( use_xml ) { fPrintAdAsXML(stdout, *ad); } else { fPrintAd(stdout, *ad); } printf("\n"); } else { if (customFormat) { mask.display(stdout, ad); } else { displayJobShort(ad); } } matchCount++; // if control reached here, match has occured if (specifiedMatch != 0) { // User specified a match number if (matchCount == specifiedMatch) { // Found n number of matches, cleanup if (ad) { delete ad; ad = NULL; } fclose(LogFile); return; } } } if(ad) { delete ad; ad = NULL; } } if(longformat && use_xml) { std::string out; AddClassAdXMLFileFooter(out); printf("%s\n", out.c_str()); } fclose(LogFile); return; }