/* * This C program will read an DSPJRN outfile of *TYPE5 (new for V5R2) and * return bundling information. 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 allow * for the hidden entries to be included in your outfile which * also take up space on the Journal bundles. * * 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: * BUNDLE lib file * lib - library * outfile - dspjrn outfile * * Compile Statement: CRTSQLCI OBJ(LIB/BUNDLE) SRCFILE(LIB/BUNDLE) COMMIT(*NONE) OBJTYPE(*PGM) * */ /* include the necessary C header files */ #include #include #include #include /* 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; int i; /* a simple counter */ long int numents = 0; /* number of entries in outfile */ long int curr_ent = 1; /* current entry being processed */ short int armnum = 0; /* arm number of current entry */ long int entsize = 0; /* size of current entry */ short int formerarmnumber = -1; /* arm number of previous entry */ long int bundlesize = -1; /* running total size of current bundle */ long int runningnumbundles = 0; /* current number of bundles found */ unsigned long int totalsize = 0; /* cumulative size of all entries */ unsigned long int newtotalsize = 0; /* used for overflow checking */ long int maxbundle = -1; /* current maximum bundle size */ long int minbundle = 9999999; /* current minimum bundle size */ char selstmt[200]; /* character arrays to hold our select statements */ char sel2stmt[200]; char lib[11]; /* character array to hold input library name */ char outfile[11]; /* character array to hold outfile name */ EXEC SQL DECLARE c1 CURSOR FOR exestmt; /* declare SQL cursor C1 */ EXEC SQL DECLARE c2 CURSOR FOR actstmt; /* declare SQL cursor C2 */ EXEC SQL END DECLARE SECTION; /****************************************** * Parsing command line / error checking ******************************************/ if (argc != 3) { printf("ERROR - proper syntax is: BUNDLE lib outfile"); } else { /* extract the library from the first argument */ sprintf(lib, "%s", argv[1]); /* extract the outfile from the second argument */ sprintf(outfile, "%s", argv[2]); /* 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 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 number of 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); /* Create SQL query which will pull two columns from your OUTFILE: * the arm number on which each Journal entry resides and the * width in bytes of each Journal entry. These will be sorted * by the Journal Sequence number so that we see consecutive Journal * Entries in the order in which they were deposited. */ sprintf(sel2stmt, "SELECT JOARM, JOENTL 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 :armnum, :entsize; /* extract the arm number width */ newtotalsize = totalsize + entsize; /* check for overflow */ if (newtotalsize < totalsize) { printf("OVERFLOW on totalsize - use a smaller entry range\n"); return; } totalsize = newtotalsize; /* 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) { if (bundlesize > maxbundle) maxbundle = bundlesize; if (bundlesize < minbundle && bundlesize != -1) minbundle = bundlesize; } /* maintain stats considering this new bundle */ runningnumbundles = runningnumbundles + 1; bundlesize = entsize; /* prime the size of the new bundle */ } /* else this entry belongs to the current bundle */ else { bundlesize = bundlesize + entsize; } /* track the arm of the current entry */ formerarmnumber = armnum; curr_ent = curr_ent + 1; } EXEC SQL CLOSE c1; /* make sure to add our last bundle into the statistics */ if (bundlesize > maxbundle) maxbundle = bundlesize; if (bundlesize < minbundle && bundlesize != -1) minbundle = bundlesize; printf("Total size of all entries = %lu\n", totalsize); printf("Number of bundles = %ld\n", runningnumbundles); printf("Average bundle size = %ld bytes\n", totalsize / runningnumbundles); printf(" max bundle size = %ld bytes\n", maxbundle); printf(" min bundle size = %ld bytes\n", minbundle); printf("\n"); printf("The bundle size optimal size is 128 KB or wider\n"); printf("\n"); } return 0; }