Thanks much!
RK.
WHAT!! YOU have a QUESTION!?? I thought you were just full of
answers!! ;-)
How 'bout
...
DCL &RECSTHERE *CHAR 1
DCLF mylib/myfile
...
CHGVAR VAR(&RECSTHERE) VALUE('N')
RCVF
MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(NONETHERE)
CHGVAR VAR(&RECSTHERE) VALUE('Y')
NONTHERE: ...
...
/* have a nice day */
Bet there's an API to do this better!
Dick Daniels
http://www.wynth.com/
Richard Knechtel wrote:
>
> Does anyone know a way to check for an empty Physical file in CL?
>
> Thanks much!
>
> RK.
--
Gernot Langle
PARAS Solutions, Inc.
http://www.parassolutions.com
mailto:gla...@parassolutions.com
How about this?
RTVMBRD file NBRCURRCD(&NBR)
IF (&NBR *EQ 0) THEN(the bloody thing's empty!)
--
Dave Shaw, General Nutrition, Greenville, SC (just down the road from BMW -
Bubba Makes Wheels :)
The opinions expressed may not be my employer's unless I'm sufficiently
persuasive...
Learning more every day!
Dick Daniels
http://www.wynth.com/
Never mind I figured it out!
This seems to work ok:
DCLF FILE(MYFILE)
RCVF
MONMSG MSGID(CPF0864) EXEC(GOTO CMDLBL(ERROR)) /* EOF EXCEPTION */
Unless someone has a better way to suggest to me. I'm willing to learn a
new trick.
Usually I find the answers to my questions.. But this time I posted
prior to finding my solution. But I like the RTVMBRD better than mine.
(Less lines of code! OPTIMIZE, OPTIMIZE, OPTIMIZE!
> How 'bout
> ...
> DCL &RECSTHERE *CHAR 1
> DCLF mylib/myfile
> ...
> CHGVAR VAR(&RECSTHERE) VALUE('N')
> RCVF
> MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(NONETHERE)
> CHGVAR VAR(&RECSTHERE) VALUE('Y')
>
> NONTHERE: ...
> ...
> /* have a nice day */
>
> Bet there's an API to do this better!
>
If there is, I don't know about it. But then again I havn't used API's
(yet). Except for (QCMDEXEC and QUSCMDLN).
That makes two of us. I think RTVMBRD takes less code then my solution..
An easy way would be to copy the file to another using CPYF and monitor
for the "no records in file" escape message (I forget the exact text).
If the file actually does contain records and lots of them, this could
take some time to execute, so I would also add selection criteria
(probably a range of relative record numbers, e.g from record 1 to
record 2) to the CPYF comand to limit the number of records copied in
that case.
Heheh, well it WAS late, and the other way came to mind first :)
RTVMBRD is indeed easier than the method I described. I can only say
going back a long way on the platform is sometimes a disadvantage - you
occasionally revert to the way you would have done it before the RTVMBRD
command existed...
The way to do this is to use - retrieve member description command e.g.
RTVMBRD FILE(&filename) NBRCURRCD(&RCDS)
the variable &RCDS should be declared as 10 0 dec.
You can then - IF COND(&RCDS *NE 0) THEN(DO) or whatever -
Hope this helps,
DaveB (UK)
Alistair Duguid wrote in message <36245975...@kmatech.com>...
If you OPEN the file and then examine the Open Feedback area, you will find
that there is a number of records field. this performs fastest. (I won't
vouch for its accuracy for logical files or for REUSEDLT(*YES) files)
Martin Neugebauer wrote in message <362495FD...@xpoint.at>...
For what I ended up doing (due to ever changing customer needs) was
this:
First I did:
CHKOBJ OBJ(*LIBL/MYFILE) OBJTYPE(*FILE)
MONMSG MSGID(CPF9801) EXEC(GOTO ERROR)
(make sure the darn thing is there)
Second I did:
RCVF
MONMSG MSGID(CPF0944) EXEC(DO)
(see if their is a member in the file (due to a pc side application may
or may not just delete the member. They will be FTP'ing data to the PF).
Third I did:
RTVMBRD FILE(*LIBL/VS2CAMIS) NBRCURRCD(&NBR)
IF COND(&NBR *EQ 0) THEN(DO)
(do what customer requested if File is empty)
IF COND(&NBR *NE 0) THEN(DO)
(do what customer wanted if there is data in the file)
(I also put in error handling to cover any generated errors)
I think I coverd all possible checks I could think of for file checks.
Any one else have other checks they use?
Regards,
RK.
Tim wrote:
> RTVMBRD is slow and using the API's is almost as bad.
>
> If you OPEN the file and then examine the Open Feedback area, you will find
> that there is a number of records field. this performs fastest. (I won't
> vouch for its accuracy for logical files or for REUSEDLT(*YES) files)
>
I can't comment on the slow part, though I would not expect it to be, as
compared to an OPEN <and don't try this method on a lot of VIEWs> since the
OPEN should be performing significantly more work. However the OPEN method is
best when overrides can be used by the pgm... since the RTVMBRD will not honor
an override.
Regards, Chuck
All comments provided "as is" with no warranties of any kind whatsoever.
This is interesting. Are you aware that multiple MONMSG commands can be
used after a command, and that a MONMSG can specify multiple MSGIDs?
For example (not saying this is an ideal solution) you could do
something like:
RTVMBRD FILE(*LIBL/VS2CAMIS) NBRCURRCD(&NBR)
MONMSG MSGID(CPF9810 CPF9812 CPF9815 CPF3019)
(do lib/file/mbr not found actions)
MONMSG MSGID(CPF3018 CPF3051 CPF327B)
(do not available actions)
MONMSG MSGID(CPF9820 CPF9822)
(do not authorized actions)
MONMSG MSGID(CPF3027)
(do 'not a db file' actions)
< etc ... >
IF COND(&NBR *EQ 0) THEN(DO)
(do what customer requested if File is empty)
IF COND(&NBR *NE 0) THEN(DO)
(do what customer wanted if there is data in the file)
So it may be possible to eliminate unnecessary steps (eg CHKOBJ/RCVF).
There is not much overhead for the extra MONMSG commands, because the
MSGIDs are checked only when an exception is signalled. And I'm
guessing the normal case is the RTVMBRD works, ie no exception.
fwiw...
--
Karl Hanson
Well, since you're asking:
First: Like Karl Hanson pointed out, you can just do a RTVMBRD and handle
all the errors you can think of after that. This might also eliminate the
need for a DCLF (thus also eliminating the need for recompilation after file
changes).
Second: You have no checks for authority (also mentioned by Karl).
Third: You have no 'catch all' for errors you don't foresee now.
Last: As I'm nitpicking anyway: you might want to change the second IF into
an ELSE. Your construction assumes (rightly, I hope) that the value of &NBR
is not changed between the two IF's. But programs are often changed later.
Joep Beckeringh
> So it may be possible to eliminate unnecessary steps (eg CHKOBJ/RCVF).
> There is not much overhead for the extra MONMSG commands, because the
> MSGIDs are checked only when an exception is signalled. And I'm
> guessing the normal case is the RTVMBRD works, ie no exception.
> fwiw...
>
> --
>
> Karl Hanson
Karl,
Thanks, this looks like an interesting thing to look at. I'll have to
play with this some.
Regards,
RK.
While OPEN may be more expensive than other database I/O, it is still much
cheaper than external program calls.
This comparison was done before ILE came into existence and when the RTVMBRD
and the equivalent API were brand new. Of course things may have changed...
On the other hand, if the program goes on to process the records in the
opened file, then the open feedback method beats the RTVMBRD method hands
down.
Charles R. Pence wrote in message <362609D3...@vnet.ibm.com>...
In your comparison of OPEN vs RTVMBRD, you were in a HLL program to begin with. Then you
compared the cost to OPEN and check the open feedback area to the cost of making an
external call to a CL program. The performance penalty in this case is the external call
to the CL program.
On the other hand, in the scenario described originally in this thread, the questioner is
in a CL program to begin with. In this case, you would need to call a HLL program to get
to the open feedback area - in other words, the same penalty in your example applies here
- the external call to the HLL program. It should, indeed, be considerably faster to use
RTVMBRD than to make the external call to the HLL program to check the open feedback area.
Gary Guthrie
Editor, The RPG Source
Technical Editor, NEWS/400 magazine
Just out of curiosity, how does one access the Open Feedback area in CL?
Tom Liotta
In article <xEbV1.10$B54.3...@news.rdc1.ne.home.com>,
"Tim" <scot...@home.com.xyz> wrote:
> RTVMBRD is slow and using the API's is almost as bad.
>
> If you OPEN the file and then examine the Open Feedback area, you will find
> that there is a number of records field. this performs fastest. (I won't
> vouch for its accuracy for logical files or for REUSEDLT(*YES) files)
>
> Martin Neugebauer wrote in message <362495FD...@xpoint.at>...
> >Wake up!
> >Use RTVMBRD ...
> >Also, there are a number of file-APIs, in case you need to know something
> >not accessible with RTVMBRD ... (see System API Reference)
> >Martin
> >
> >Alistair Duguid wrote:
> >
> >> Richard Knechtel wrote:
> >> >
> >> > Does anyone know a way to check for an empty Physical file in CL?
> >> >
> >> > Thanks much!
> >> >
> >> > RK.
> >>
> >> An easy way would be to copy the file to another using CPYF and monitor
> >> for the "no records in file" escape message (I forget the exact text).
> >>
> >> If the file actually does contain records and lots of them, this could
> >> take some time to execute, so I would also add selection criteria
> >> (probably a range of relative record numbers, e.g from record 1 to
> >> record 2) to the CPYF comand to limit the number of records copied in
> >> that case.
> >
> >
> >
>
>
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
True, This program is a CL to begin with wich will call HLL programs
(RPG IV) to actually process the file. So I think the RTVMBRD will give
me less overhead. I would assume this is correct.
RK.
Ah, a good valid point.
> Second: You have no checks for authority (also mentioned by Karl).
>
Yeah, I hadn't thought about that. Especially since these jobs will be
run in a batch environment.
> Third: You have no 'catch all' for errors you don't foresee now.
>
Would the use of global error checking take care of this?
Example:
/* GLOBAL ERROR CHECKING */
ERRCHK:
MONMSG MSGID(CPF0000) +
EXEC(GOTO CMDLBL(ERROR))
RCVMSG MSGTYPE(*LAST) MSG(&MSG)
(my mainline code goes here)
/* END PART OF GLOBAL ERROR CHECKING ROUTINE */
ERROR:
RCVMSG MSGTYPE(*LAST) MSG(&MSG)
MONMSG MSGID(CPF0000)
SNDPGMMSG MSG(&MSG)
MONMSG MSGID(CPF0000)
DSPJOBLOG OUTPUT(*PRINT) /* SPOOL JOBLOG */
MONMSG MSGID(CPF0000)
> Last: As I'm nitpicking anyway: you might want to change the second IF into
> an ELSE. Your construction assumes (rightly, I hope) that the value of &NBR
> is not changed between the two IF's. But programs are often changed later.
>
This is true using an ELSE probably would be a better way to do it.
(especially since oyu never know who will come behind you and "break"
it. :^)
Thanks.
RK.
Yes, this would be a helpful thing to know.
Regards,
RK.
tho...@inorbit.com wrote in message <706di3$qb1$1...@nnrp1.dejanews.com>...
>Tim:
>
>Just out of curiosity, how does one access the Open Feedback area in CL?
>
>Tom Liotta
>
<snip>
>Would the use of global error checking take care of this?
>Example:
>
>/* GLOBAL ERROR CHECKING */
>ERRCHK:
> MONMSG MSGID(CPF0000) +
> EXEC(GOTO CMDLBL(ERROR))
> RCVMSG MSGTYPE(*LAST) MSG(&MSG)
>
>(my mainline code goes here)
>
>/* END PART OF GLOBAL ERROR CHECKING ROUTINE */
>ERROR:
> RCVMSG MSGTYPE(*LAST) MSG(&MSG)
> MONMSG MSGID(CPF0000)
> SNDPGMMSG MSG(&MSG)
> MONMSG MSGID(CPF0000)
> DSPJOBLOG OUTPUT(*PRINT) /* SPOOL JOBLOG */
> MONMSG MSGID(CPF0000)
>
<snip>
Richard,
I 'stole' my global error handling from utilities in QUSRTOOL a long time
ago. It basically consists of three steps:
1. Set a flag indicating an unforeseen error has occurred. This is to
prevent endless looping when an error occurs during the error handling
(meaning you have to check this flag before you do the actual error
handling).
2. Receive all the informational messages that have been sent to you and
send them to your caller.
3. Receive the escape message you've got and send it (as an escape message)
to your caller. This will lead to an error in the caller, which can be
handled there or passed on. In a batch job this will normally lead to an
abnormal ending of the job, which will usually lead to printing of the
joblog.
For steps 2 and 3 I use command wrappers for API's QMHMOVPM (move program
messages) and QMHRSNEM (resend escape message). I got these command
wrappers from a magazine (probably News/400).
You see, just knowing where to find things to copy can help a lot :-)
Joep Beckeringh
This program retrievies all the database files in a library and depending on
the value of the test parameter, it either uses RTVMBRD to get the number of
current records, or it calls a PLI program I wrote that opens the file and
gets the record count from the open feedback area.
In general for small numbers of files either method performs similarly, a
noticeable difference appears at around 1600 tests, at which point (on my
system), the open feedback method steadily and increasingly beats the
RTVMBRD method.
So much for the assumption that RTVMBRD necessarily performs better.
Don't misunderstand me, I am not advocating the open feedback method as
"the" solution for the person who needs a record count in a CL program. I
was offering it as an alternative. Many times we have HLL programs that need
to know how many records are in the file to before it begins processing. The
open feedback method in this case is actually easier and much cheaper than
calling a CL program or calling the RTVMBR api (naturally we are talking
nanoseconds here if only one test is being performed).
PGM (&LIB &TEST)
DCL &LIB *CHAR 10
DCL &TEST *CHAR 1
DCL &NUMREC *DEC (10 0)
DCL &NUMRECB *CHAR 4
DCL &FILESPEC *CHAR 33
DCLF QAFDBASI
DSPFD FILE(&LIB/*ALL) TYPE(*BASATR) +
OUTPUT(*OUTFILE) FILEATR(*PF *LF) +
OUTFILE(QTEMP/QAFDBASI)
SNDPGMMSG MSG('The test is starting')
OVRDBF QAFDBASI QTEMP/QAFDBASI
LOOP: RCVF
MONMSG CPF0000 EXEC(GOTO ENDLOOP)
IF (&TEST = '0') +
DO
RTVMBRD FILE(&ATLIB/&ATFILE) NBRCURRCD(&NUMREC)
MONMSG CPF0000
ENDDO
ELSE +
DO
CHGVAR &FILESPEC (&ATLIB *TCAT '/' *TCAT &ATFILE)
CALL RECORDS (&NUMRECB &FILESPEC)
MONMSG (PLI0000 CPF0000)
ENDDO
GOTO LOOP
ENDLOOP:
SNDPGMMSG MSG('The test has completed')
ENDPGM
The following program gets the record count from the open feedback area. The
important part is that the record count starts at the 76th positon of the
feedback area and is 4 byte binary number.
RECORDS:PROCEDURE (OBJNAME) RETURNS(FIXED BIN(31));
DCL OBJNAME CHAR(33);
DCL FILENAME CHAR(10);
DCL LIBRARY CHAR(10);
DCL MEMBER CHAR(10);
DCL OBJNAME400 CHAR(33);
%INCLUDE QPLIINCL(PARSE);
%INCLUDE QPLIINCL(TRIMR);
DCL DUMMYFILE FILE SEQL RECORD INPUT INTERNAL;
DCL 1 OPNFDB,
2 FILLER CHAR(75),
2 RCDCNT FIXED BIN(31) UNALIGNED;
ON ERROR
BEGIN;
RCDCNT = -1;
GOTO EOJ;
END;
CALL PARSE(OBJNAME,FILENAME,LIBRARY,MEMBER);
SELECT('');
WHEN(LIBRARY³³MEMBER)
OBJNAME400 = FILENAME;
WHEN(LIBRARY)
OBJNAME400 = TRIMR(FILENAME)³³'('³³TRIMR(MEMBER)³³')';
WHEN(MEMBER)
OBJNAME400 = TRIMR(LIBRARY)³³'/'³³FILENAME;
OTHERWISE
OBJNAME400 = TRIMR(LIBRARY)³³'/'³³TRIMR(FILENAME)³³
'('³³TRIMR(MEMBER)³³')';
END;
OPEN FILE(DUMMYFILE) TITLE(OBJNAME400);
CALL PLIOPNFDB (DUMMYFILE,OPNFDB);
CLOSE FILE(DUMMYFILE);
EOJ: RETURN (RCDCNT);
END RECORDS;
Timothy J. McCollough
mailto:ti...@omahasteaks.com
Richard Knechtel wrote in message <362759...@ftc.gov>...
>Gary Guthrie wrote:
>>
>> Tim,
>>
>> In your comparison of OPEN vs RTVMBRD, you were in a HLL program to begin
with. Then you
>> compared the cost to OPEN and check the open feedback area to the cost of
making an
>> external call to a CL program. The performance penalty in this case is
the external call
>> to the CL program.
>>
>> On the other hand, in the scenario described originally in this thread,
the questioner is
>> in a CL program to begin with. In this case, you would need to call a HLL
program to get
>> to the open feedback area - in other words, the same penalty in your
example applies here
>> - the external call to the HLL program. It should, indeed, be
considerably faster to use
>> RTVMBRD than to make the external call to the HLL program to check the
open feedback area.
>>
>> Gary Guthrie
>> Editor, The RPG Source
>> Technical Editor, NEWS/400 magazine
>
I would tend to disagree that this is a question that merits testing. I disagree based on
two issues.
1) Presuming for the moment that your example is faster, it's difficult to imagine a
situation in which you would need to retrieve the information for a large number of files
as in your example
2) Small gains in performance should not outweight clarity of code. RTVMBRD is vastly more
comprehensible and shorter. In other words, adheres to good programming practice.
For practical purposes, we're probably not talking a great difference in time irrespective
of the method. In light of that IMO RTVMBRD is the superior method (even if it was a
little slower)
> This program retrievies all the database files in a library and depending on
> the value of the test parameter, it either uses RTVMBRD to get the number of
> current records, or it calls a PLI program I wrote that opens the file and
> gets the record count from the open feedback area.
>
> In general for small numbers of files either method performs similarly, a
> noticeable difference appears at around 1600 tests, at which point (on my
> system), the open feedback method steadily and increasingly beats the
> RTVMBRD method.
Here's a few observations and questions with respect to your test.
1) At what point did you take the timestamps to determine which performs better? Did you
only measure the time it took for RTVMBRD or other code that is being executed.
2) Were other things running at the time the tests were running?
3) Did you flush pages between tests so that nothing is "pre-loaded" in memory giving one
method an advantage over the other.
4) In your test, the pointer to the PLI program only need be resolved once and that's
where a major performance penalty occurs. That explains why the PLI program performs
better on subsequent calls. In a typical case where you only need to retrieve the
information for 1 file, this is more significant in terms of theoretical, relative
performance.
> So much for the assumption that RTVMBRD necessarily performs better.
Let's discuss the points concerning your tests before we arrive at your conclusion, here.
> Don't misunderstand me, I am not advocating the open feedback method as
> "the" solution for the person who needs a record count in a CL program. I
> was offering it as an alternative. Many times we have HLL programs that need
> to know how many records are in the file to before it begins processing. The
> open feedback method in this case is actually easier and much cheaper than
> calling a CL program or calling the RTVMBR api (naturally we are talking
> nanoseconds here if only one test is being performed).
I'm glad to see that you don't advocate your suggestion.
Please provide us with the details of your timestamps, environment, etc. as asked above.
We'd like to hear about it.
Gary Guthrie
Editor, The RPG Source
Technical Editor, NEWS/400 magazine
Your programs:
It is up to you to form your own opinion.
>1) Presuming for the moment that your example is faster, it's difficult to
imagine a
>situation in which you would need to retrieve the information for a large
number of files
>as in your example
Granted. Besides which DSPFD to an outfile would give all this anyway and
avoid a silly argument
>2) Small gains in performance should not outweight clarity of code. RTVMBRD
is vastly more
>comprehensible and shorter. In other words, adheres to good programming
practice.
>
>For practical purposes, we're probably not talking a great difference in
time irrespective
>of the method. In light of that IMO RTVMBRD is the superior method (even if
it was a
>little slower)
Granted. I was responding to the a priori dismissal of the method I
suggested by others in this news group that said RTVMBRD *must* be faster,
therefore better.
>
>> This program retrievies all the database files in a library and depending
on
>> the value of the test parameter, it either uses RTVMBRD to get the number
of
>> current records, or it calls a PLI program I wrote that opens the file
and
>> gets the record count from the open feedback area.
>>
>> In general for small numbers of files either method performs similarly, a
>> noticeable difference appears at around 1600 tests, at which point (on my
>> system), the open feedback method steadily and increasingly beats the
>> RTVMBRD method.
>
>Here's a few observations and questions with respect to your test.
>
>1) At what point did you take the timestamps to determine which performs
better? Did you
>only measure the time it took for RTVMBRD or other code that is being
executed.
The CL program sends a message to the program queue before the outfile is
processed and after it has finished. The joblog was examined to find the
timestamp on the message
>2) Were other things running at the time the tests were running?
Usually goes without saying... I can hardly kick everyone off to do
extra-curricular experimentation.
>3) Did you flush pages between tests so that nothing is "pre-loaded" in
memory giving one
>method an advantage over the other.
You tell me, can I force the system to flush pages? Would there be any way
to verify it?
I ran the CL program in a single threaded batch subsystem which runs in its
own memory pool, The program ran two times for each method over 6 different
and increasingly large libraries. I should have brought my test results home
but I didn't I simply remember the conclusion.
>4) In your test, the pointer to the PLI program only need be resolved once
and that's
>where a major performance penalty occurs. That explains why the PLI program
performs
>better on subsequent calls. In a typical case where you only need to
retrieve the
>information for 1 file, this is more significant in terms of theoretical,
relative
>performance.
Should I repeat the test and use a variable for the PLI program name? Does
anybody really care?
>I'm glad to see that you don't advocate your suggestion.
I only advocate this suggestion in situations that call for it.
Let me start by saying that I'm not trying to be argumentative, just complete and factual.
You might also consider that perhaps assumptions weren't being made on at least some of
the posters' parts. Maybe, just maybe, somebody took a look at low-level code generated
and came to an informed conclusion. Maybe somebody took the time to perform some valid
benchmarking tests before expressing their conclusion.
While you now say that you're obviously not going to perform a scientific experiment for
such an academic point, you didn't make that assertion when you posted your authoritative
results (you emphasized that as the number of iterations increased the marked improvement
of the INFDS method). In so doing, you might mislead those who read your conclusions.
When you cite benchmark results, it is important to report them accurately. There are
several flaws in your benchmark data - I'll point out some of them for educational
purposes.
> I was responding to the a priori dismissal of the method I
> suggested by others in this news group that said RTVMBRD *must* be faster,
> therefore better.
There's no question whether RTVMBRD is better - it is. As I pointed out, irrespective of
small performance differences RTVMBRD is more manageable, to the point, and maintainable.
> The CL program sends a message to the program queue before the outfile is
> processed and after it has finished. The joblog was examined to find the
> timestamp on the message
Here's one of the flaws I mentioned. This doesn't measure the speed of retrieving the
information by RTVMBRD. The measurement includes time for reading the file, moving data
around the buffers, potential exception handling, compares and branches, unconditional
branches,... Same for the INFDS method - it involves other steps here. The differences you
see, therefore, are not between RTVMBRD and CALL, but rather the totality of the code
paths. That's not a valid comparison.
> Usually goes without saying... I can hardly kick everyone off to do
> extra-curricular experimentation.
No, it doesn't go without saying. The load on the system makes a big difference in
performance benchmarks, as does anything that might already be "pre-set". It is completely
invalid benchmark data without these controls. Again, this misleads people who read your
conclusions.
> Should I repeat the test and use a variable for the PLI program name? Does
> anybody really care?
No, I don't think anybody does really care - I believe most think RTVMBRD is by far
superior, and they probably also believe that it is faster and that valid benchmark data
would support that conclusion.
Please don't take my comments personal - that's not the intention. The intention is to be
complete and accurate so that those who hope to learn something in this venue have the
information they need to draw their conclusions.
Cool, I need to take a look at this I think.
Thanks!
RK.