/* * This C program will read an DSPJRN outfile of *TYPE5 and return caching * latency information. This program will also create a view called your * + "VIEW" with the system clock times and matching bundle * latency value for an over-all histogram representation. You will receive * an error from this program stating that the JOARM column is missing * if you fail to produce the OUTFILE using the *TYPE5 option. * Use the DSPJRN INCHIDENT(*YES) option for accurate bundling information. * This will assure the hidden entries are included in your outfile. * * The following is an example of a DSPJRN command with the options * required: * DSPJRN JRN(LIB/JRN) OUTPUT(*OUTFILE) OUTFILFMT(*TYPE5) * OUTFILE(LIB/OUTFILE) INCHIDENT(*YES) * * Syntax for involking the CHACHELAG program: * CACHELAG lib outfile outputTableName * lib - library * dspjrnOutfile - Name of dspjrn outfile * outputFileName - File created with statistics to query * * Compile Statement: CRTSQLCI OBJ(LIB/CACHELAG) SRCFILE(LIB/CACHELAG) COMMIT(*NONE) OBJTYPE(*PGM) * */ /* These are the necessary C header files */ #include #include #include #include /* provides toupper() call */ /* Statements required for embedded SQL */ EXEC sql include SQLCA; EXEC sql include SQLDA; /* Begin main function */ int main(int argc, char *argv[]) { EXEC SQL BEGIN DECLARE SECTION; /** State Variables **/ int i; /* a simple counter */ long int firstSeqNum = -1; /* first Journal sequence number of a bundle */ char firstTimestamp[26]; /* first timestamp of a bundle */ short int formerarmnumber = -1; /* arm number of previous Journal entry */ long int curr_ent = 1; /* current entry being processed */ /** Holders for returned SQL values **/ long int numents = 0; /* number of entries in outfile */ short int armnum = 0; /* disk arm number of current entry */ long int seqnum = 0; /* sequence number of current entry*/ char jocode[1]; /* journal entry code of current entry*/ char jotype[2]; /* journal entry type of current entry*/ char timestamp[26]; /* timestamp of current entry */ float bundletime; /* total time of bundle */ /** Variables to keep Statistics **/ float bundlelag = 0; /* current bundle lag */ float maxbundle = -1; float minbundle = 9999999; long int runningnumbundles = 0; /* current number of bundles found */ /** SQL statment holders **/ char selstmt[200]; /* character arrays to hold our select statements */ char sel2stmt[200]; char sel3stmt[200]; char sel4stmt[200]; /* character array for preparing SQL statements */ char sel5stmt[200]; /*** Input Parameters **/ char lib[11]; /* character array to hold input library name */ char outfile[11]; /* character array to hold outfile name */ char tableName[11]; /* character array to hold row histogram output */ EXEC SQL DECLARE c1 CURSOR FOR exestmt; /* declare SQL cursor C1 */ EXEC SQL DECLARE c2 CURSOR FOR actstmt; /* declare SQL cursor C2 */ EXEC SQL DECLARE c3 CURSOR FOR timestmt; /* declare SQL cursor C3 */ EXEC SQL END DECLARE SECTION; /****************************************** * Parsing command line / error checking ******************************************/ if (argc != 4) { printf("ERROR - proper syntax is: CACHELAG lib dspjrnOutfile outputFileName"); } else { if(strlen(argv[3])>16) { printf("Table name is too long (>16 characters)"); return; } /* extract the library from the first argument */ sprintf(lib, "%s", argv[1]); /* extract the outfile from the second argument */ sprintf(outfile, "%s", argv[2]); /* extract the table name from the third argument */ sprintf(tableName, "%s", argv[3]); /* convert the library to upper case */ for (i = 0; i < 10; i++) { lib[i] = toupper(lib[i]); } /* convert the outfile to upper case */ for (i = 0; i < 10; i++) { outfile[i] = toupper(outfile[i]); } /* create SQL table to hold row histogram data */ sprintf(sel4stmt, "CREATE TABLE %s/%s (STARTTIME TIMESTAMP, BUNDLELATENCY DECIMAL(6,6))", lib, tableName); EXEC SQL EXECUTE IMMEDIATE :sel4stmt; /* create the SQL statement to determine the number of entries */ sprintf(selstmt, "SELECT COUNT(*) FROM %s/%s", lib, outfile); EXEC SQL PREPARE actstmt FROM :selstmt; EXEC SQL OPEN c2; /* open the SQL view (cursor) */ EXEC SQL FETCH c2 INTO :numents; /* set the total # of Journal entries */ EXEC SQL CLOSE c2; /* close the SQL cursor */ /* output the number of Entries to the screen */ printf("\n\n\n\n\n\n\n"); printf("number of entries = %d\n", numents); printf("\nBe patient, this could take a while...\n\n"); /* Create SQL query which will pull 5 columns from your OUTFILE: * Journal entry code * Journal entry type * The arm number on which each Journal entry resides * The sequence number each Journal entry. * Journal timestamp */ sprintf(sel2stmt, "SELECT JOCODE, JOENTT, JOARM, JOSEQN, JOTSTP FROM %s/%s order by JOSEQN", lib, outfile); EXEC SQL PREPARE exestmt FROM :sel2stmt; EXEC SQL OPEN c1; /* open the SQL view (cursor) */ /* loop through each entry in the outfile */ while(curr_ent <= numents) { /* get the next available entry */ EXEC SQL FETCH c1 INTO :jocode, :jotype, :armnum, :seqnum, :timestamp; /* extract the data*/ /* test if current entry is start of new bundle */ if (armnum != formerarmnumber) /* provided that we have seen a bundle */ { /* maintain overall stats if we really just finished a bundle */ if (formerarmnumber != -1) { /* don't count statistics if the bundle is just one entry */ if(seqnum != firstSeqNum +1) { // Get the total bundle size with a select from firstSeqNumseqnum -1 sprintf(sel3stmt, "SELECT JOTSTP - '%s' FROM %s/%s where JOSEQN = %ld", firstTimestamp, lib, outfile, seqnum - 1); EXEC SQL PREPARE timestmt FROM :sel3stmt; EXEC SQL OPEN c3; /* open the SQL view (cursor) */ EXEC SQL FETCH c3 INTO :bundletime; /* set the latency duration */ EXEC SQL CLOSE c3; /* close the SQL cursor */ bundlelag = bundlelag + bundletime; if(bundletime>maxbundle){ maxbundle = bundletime; } if(bundletimemaxbundle){ maxbundle = bundletime; } if(bundletime