(Originally posted 2016-05-24.)
On Twitter I joked ‘refactoring’ is ‘taking perfectly well working code and risking breaking it’. This post describes one such exercise.
tl;dr: It was well worth it!
In DFSORT Tables I wrote about a technique to create tables (or grids) using IFTHEN.
It’s been a maintenance headache to the extent that the “Principle” Of Sufficient Disgust kicked in. So this post shares some optimisations in ISPF File Tailoring I’ve just made that might prove useful to you.
In our code we use ISPF File Tailoring, substituting in variables from ISPF panels to create e.g. JCL decks. It’s what makes us quick to generate engagement-specific JCL.
This particular portion of our code is a sequence of DFSORT steps against DDF-specific DB2 SMF 101 Accounting Trace records, related to DDF Counts. It generates CSV files we import into spreadsheet programs.
Repeated Fragments Of Code
The JCL had grown into a series of repeated DFSORT reports. When I say “repeated” I mean we had 3 reporting steps where large portions of the DFSORT code was repeated.
So the first optimisation was to replace these 3 queries with sets of repeated File Tailoring Imbeds.
Now adjustments get made once and automatically appear in all 3 places in the generated JCL.
I said “sets” because I created imbed files for DFSORT Symbols, 2 for INREC fragments, 1 for SUM, and 2 for OUTFIL OUTREC.
Looping Field Generation
I’d been creating tables for 4 DB2 subsystems – so sets of 5 columns (these 4 plus 1 for “Other”).
Sometimes – in customer data – I’d had fewer than 4 subsystems in the data. This was OK because my code just generated blank columns that can easily be deleted in the spreadsheet.
But my latest customer set of data has 6 major DB2 subsystems in. When run with my original code a lot of data appeared in the “Other” columns; Not what I wanted.
Time to go to 8 subsystems, or was it?
So I hand-crafted 6 Subsystems’ worth. It was tedious but not impossible.
But then I realised I could do this much better with ISPF File Tailoring looping:
I set a variable at the top:
)SET SSIDS = 8
And then I loop all the repeated lines:
)DO I = 1 TO &SSIDS ZERO, )ENDDO
ZERO is a DFSORT symbol for
While making this massive sequence of edits I actually corrected an error (a typo) in my code I hadn’t noticed before.
At one point I defined a “1 short of” variable as the last line had to be different:
)SET SSIDS1 = &SSIDS - 1
In general this mass edit was well worth it; The code is much more maintainable.
The code uses STCK-value related thresholds that I set using real world values such as “1 second”.
Setting these thresholds was obscure and error-prone.
So now I let ISPF File Tailoring do the calculation for me:
)SETF THRESH = @eval(4096000/4) RT_BUCKET&B,+&THRESH000 1/4 Second
In the first line of the above the
/4 yields 1/4 of a second and the use of
)SETF rather than
In the second line the
B variable is the bucket number whose threshold is being set. The
000 is needed because the values that
@eval can use and generate are 32-bit signed integers.
When tailored, with a value of
&B(the bucket number) we get:
RT_BUCKET8,+1024000000 1/4 Second
This is much more maintainable – so I could change the bucket thresholds at any time.
The three sets of changes give me much tighter and more maintainable code, fixing as bug or two along the way.
One further tweak I can see is defining a bunch more variables in the panel, such as the number of DB2 subsystems and the thresholds. But that will have to await another day.