// 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; }