IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

Array shrinking in COBOL


IBM Mainframe Forums -> COBOL Programming
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
anil.sahukari

New User


Joined: 11 Mar 2010
Posts: 5
Location: Chennai

PostPosted: Thu Aug 04, 2011 5:46 pm
Reply with quote

Hi,

This is related to Array shrinking/reset the count of the array occurance.

I have record with mutiple arrays.

Sample record is...

01 WS-CUSTOMER-RECORD.
03 WS-CUST-NAME PIC X(20).
03 WS-CUST-EMAIL-ADDRESS PIC X(40).
03 WS-CUST-ORDERS 0 TO 100 DEPENDING ON count1.
05 WS-DATA1.
10 product-number pic 9(5).
10 order-number pic 9(10).
03 WS-CUST-GiftS 0 TO 100 DEPENDING ON count2.
05 ws-data2.
10 product-number pic 9(5).
10 gift-prod-number pic 9(5).
10 gift-details pic x(20).


First I am searching the all the customer data from the database and keeping to arrays.
Based on the occurance of WS-CUST-ORDERS and WS-CUST-Gifts the count1 and count 2 will be set correspondingly.
For example let us assume count1 = 20, count2 = 15.
Here the array size is defined. So array will be created. After this process
I want to MOVE/SET the blanks to the array element if one field in element of array is satisfies the condition.

.
.
.

Move 1 to INDicator1

PERFORM VARYING INDicator1 FROM 1 BY 1 UNTIL
INDicator1 > count1

IF product-number OF ws-data1(INDicator1) < 101

move/SET BLANKS to ws-data1(INDicator1) <<--- This is want I want (This is similar to shrinking the array)

Add 1 to reduce-count1

END-IF
End-PERFORM.

SUBTRACT reduce-count1 FROM count1
.
.
.
Could you please let me know how reset the count of the array occurance?
Back to top
View user's profile Send private message
Robert Sample

Global Moderator


Joined: 06 Jun 2008
Posts: 8696
Location: Dubuque, Iowa, USA

PostPosted: Thu Aug 04, 2011 6:02 pm
Reply with quote

What do you mean by "similar to shrinking the array"?
what do you mean by "how reset the count of hte array occurance (sic)"?

If you're doing what I THINK you're doing, and you clear the first of 20 entries of WS-DATA1, where is your logic to move entries 2 to 20 over to fill in the missing element?
Back to top
View user's profile Send private message
dbzTHEdinosauer

Global Moderator


Joined: 20 Oct 2006
Posts: 6966
Location: porcelain throne

PostPosted: Thu Aug 04, 2011 6:14 pm
Reply with quote

1. COBOL Arrays are host-variable structures for db2.

2. what you are talking about is an ODO (Occurs Depending On) variable length COBOL Internal Table.

3. Your record definition sucks.
the ODO object (count field) should be part of the record. preferably both before the first ODO Table.

4. the easiest way to deal with multiple ODO's in a record is to move them to working-storage structures.

5. when building the record, move the first odo, then the second after populating the ODO Object.

6. populated items must be contiguous. the ODO object can not have 6
and you decide that occurance 6 should be spaces and occurance 7 should have data.

7. setting-up your data this way makes your question moot.
Back to top
View user's profile Send private message
anil.sahukari

New User


Joined: 11 Mar 2010
Posts: 5
Location: Chennai

PostPosted: Thu Aug 04, 2011 6:14 pm
Reply with quote

If a condition satifies...
I want to resize the araay occurance and move BLANKS to array element.
Back to top
View user's profile Send private message
dbzTHEdinosauer

Global Moderator


Joined: 20 Oct 2006
Posts: 6966
Location: porcelain throne

PostPosted: Thu Aug 04, 2011 6:18 pm
Reply with quote

anil.sahukari wrote:
If a condition satifies...
I want to resize the araay occurance and move BLANKS to array element.


then you are going to have to
shift the populated items below the now blank item up 1 occurance.
Back to top
View user's profile Send private message
Robert Sample

Global Moderator


Joined: 06 Jun 2008
Posts: 8696
Location: Dubuque, Iowa, USA

PostPosted: Thu Aug 04, 2011 6:19 pm
Reply with quote

Quote:
I want to resize the araay occurance and move BLANKS to array element.
Most NORMAL programmers would do one or the other. If you reduce the count1 variable (in your posted code), the last element of the table (or array) is the one going away -- period. If you move spaces to the seventh element of the array, then reduce the array count by one, you've actually wiped out values in two array elements -- number 7 and number 20, based upon your example.

Based upon your demonstrated level of expertise, you would be far, far, far, far better off getting rid of the OCCURS DEPENDING ON clasues and just use fixed-size tables.
Back to top
View user's profile Send private message
anil.sahukari

New User


Joined: 11 Mar 2010
Posts: 5
Location: Chennai

PostPosted: Thu Aug 04, 2011 11:52 pm
Reply with quote

Guys, thanks for responding...
Every every customer that count1 and count2 differs so I should use the DEPENING on clause and also in order to not to not to waste the memory also by defining the maximum size.

Can we resize the array(ODO once it's declared) and move BLANKS to a particular array item?
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Thu Aug 04, 2011 11:58 pm
Reply with quote

How many records on your file? What "memory" don't you want to waste?

As dbz has pointed out, you are riding for a fall by not having your ODO counts on the record. I have no idea how you intend to read the record later and know what is what.
Back to top
View user's profile Send private message
Robert Sample

Global Moderator


Joined: 06 Jun 2008
Posts: 8696
Location: Dubuque, Iowa, USA

PostPosted: Fri Aug 05, 2011 12:24 am
Reply with quote

Be aware that if your array is defined in WORKING-STORAGE, you will save a grand total of ZERO bytes by using OCCURS DEPENDING ON. COBOL allocates the maximum possible size for the array in WORKING-STORAGE so using OCCURS versus OCCURS DEPENDING ON won't impact the memory used.

If the array is defined as part of an FD, and the DEPENDING ON variables are not part of that same FD definition, you are BEGGING for S0C4 storage abends in the future. Unlike WORKING-STORAGE, OCCURS DEPENDING ON arrays in an FD or LINKAGE SECTION will actually vary in size and hence you must be very, very, very careful when using such variables or you attempt to access storage you are not allowed to and an abend occurs.

Finally, why are you wanting to not "waste" memory? If your system is anywhere near current, your program probably has 2 GB (or more) of memory to use so there's not much chance of your "wasted" memory causing any problems.
Back to top
View user's profile Send private message
Phrzby Phil

Senior Member


Joined: 31 Oct 2006
Posts: 1042
Location: Richmond, Virginia

PostPosted: Fri Aug 05, 2011 5:41 am
Reply with quote

The worst thing to waste is the time of the next programmer (could be you) when they try to figure out what your code is doing.

Keep it simple.
Back to top
View user's profile Send private message
Marso

REXX Moderator


Joined: 13 Mar 2006
Posts: 1353
Location: Israel

PostPosted: Fri Aug 05, 2011 2:00 pm
Reply with quote

Even after a few explanations, it is still hard to understand what you want to do...

Even if you define an OCCURS DEPENDING ON table, the amount of memory used in the program will stay the same (allocated to the maximum value).
There will be no "shrinking".
The second ODO will always be located at the same place, whether there are 1, 2, 3 or 20 or 99 occurrences in the first ODO.
Back to top
View user's profile Send private message
dbzTHEdinosauer

Global Moderator


Joined: 20 Oct 2006
Posts: 6966
Location: porcelain throne

PostPosted: Fri Aug 05, 2011 2:22 pm
Reply with quote

Quote:
The second ODO will always be located at the same place, whether there are 1, 2, 3 or 20 or 99 occurrences in the first ODO.


your point about working-storage is important.


but not in an FD record area, if properly defined and constructed
that's what makes multiple ODOs in a record difficult for the unexperienced.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Fri Aug 05, 2011 3:33 pm
Reply with quote

I'm also at a loss as to what is actually required.

I haven't used multiple ODOs with the newest compilers, but this is how it used to work. Well, not a full explanation, but of the storage "movements".

Code:
01  SAY-WE-HAVE-A-FILE-RECORD.
      05  SOME-STUFF-OF-ALL-SORTS-OF-TYPES  PIC X(300).
      05  NUMBER-OF-CUSOMTER-ORDERS COMP PIC S9(4).
      05  NUMBER-OF-CUSTOMER-GIFTS COMP PIC S9(4).
      05  CUSTOMER-ORDERS.
          10  FILLER OCCURS 0 TO 100 TIMES
              DEPENDING ON NUMBER-OF-CUSTOMER-ORDERS.
              15  CUSTOMER-ORDER-STUFF PIC X(100).
      05  CUSTOMER-GIFTS.
          10  FILLER OCCURS 0 TO 100 TIMES
              DEPENDING ON NUMBER-OF-CUSTOMER-GIFTS.
              15  CUSTOMER-GIFT-STUFF PIC X(100).


Explanation holds(held) whething in file, working-storage or linkage sections, unless otherwise stated.

SAY-WE-HAVE-A-FILE-RECORD, CUSTOMER-ORDERS and CUSTOMER-GIFTS are all "variable length" group items. Look at the map of your data from the compiler, and you'll see they appear differently than other items.

Point 1, "more difficult" (until you know how) to locate in a dump.

The start position of CUSTOMER-GIFTS depends on the length of CUSTOMER-ORDERS.

Point 2, to find data from a dump which for items after a variable length field is again more difficult. See Point 1.

Every time the value of NUMBER-OF-CUSOMTER-ORDERS changes, the length of SAY-WE-HAVE-A-FILE-RECORD and CUSTOMER-ORDERS and the start position of CUSTOMER-GIFTS are all automatically re-calculated.

Every time the value of NUMBER-OF-CUSOMTER-GIFTS changes, the length of SAY-WE-HAVE-A-FILE-RECORD and CUSTOMER-GIFTS is automatically re-calculated.

Point 3, there is a lot of processing going on "under the covers" every time you MOVE ZERO or ADD +1 or whatever to the counts.

In working-storage, the amount of storage allocated is the maximum amount of entries specified (in this case 100 on each ODO). This cannot be increased or decreased at run-time. The amount of storage is unchanged. The part of that storage which is used is what is variable.

Point 4, no storage is saved in your program by using ODO.

In the file section, the ODOs are what makes those particular records variable in length. Cobol reads the record, and then will calculate the start positions and lengths of the three variable-length items. Note, if there is inconsistency between the counters and the record-length, then your data is screwed as soon as you read the record.

Point 5, for variable length items in a file, the counter(s) must be included in the file, and before the definition of the variable part.

In the linkage section, no storage is defined, so no storage is saved.

There are assorted "advanced" techniques for using ODO in the linkage section, but I don't think it appropriate to expand on that for this TS at the moment.

Now, watch.

Say NUMBER-OF-CUSTOMER-ORDERS and NUMBER-OF-CUSTOMER-GIFTS are set to one and the fields CUSTOMER-ORDER-STUFF and CUSTOMER-GIFT-STUFF are populated appropriately.

Now, add one to NUMBER-OF-CUSTOMER-ORDERS.

What happens?

SAY-WE-HAVE-A-FILE-RECORD and CUSTOMER-ORDERS have their lengths re-calculated to reflect the new value of NUMBER-OF-CUSTOMER-ORDERS. The start position of CUSTOMER-GIFTS is recalculated.

What happens to the data already in CUSTOMER-GIFTS?

Nothing unless you make it happen yourself, and, since it is no-longer pointed-to by CUSTOMER-GIFTS, you have to have done it already. If you do nothing, you are just about to overwrite it with the 2nd occurence of CUSTOMER-ORDERS. CUSTOMER-GIFTS now points to some rubbish, possibily a valid-looking previous entry (worst case) or possibly just rubbish (preferable, as easier to spot afterwards).

Point 6, although lengths and start positions are automatically calculated where necessary, the data itself is never moved unless you do it.

I can go on, but I think this is enough.

If you still want to use ODO even, let alone multiple ODO's, then do a lot of work to absolutely understand them first, and ensure that your development and support colleagues fully understand them as well.

Otherwise, just consider your file and system as trash waiting to happen.
Back to top
View user's profile Send private message
dick scherrer

Moderator Emeritus


Joined: 23 Nov 2006
Posts: 19244
Location: Inside the Matrix

PostPosted: Sat Aug 06, 2011 9:24 am
Reply with quote

Hello,

In your initial posted record layout:
Quote:
01 WS-CUSTOMER-RECORD.
03 WS-CUST-NAME PIC X(20).
03 WS-CUST-EMAIL-ADDRESS PIC X(40).
03 WS-CUST-ORDERS 0 TO 100 DEPENDING ON count1.
05 WS-DATA1.
10 product-number pic 9(5).
10 order-number pic 9(10).
03 WS-CUST-GiftS 0 TO 100 DEPENDING ON count2.
05 ws-data2.
10 product-number pic 9(5).
10 gift-prod-number pic 9(5).
10 gift-details pic x(20).
The Orders and Gifts arrays depend on count 1 and count 2. These are not in the record and MUST be for you to create the varying record you want.

Some of our files use this approach to save more than 95% of the space required to store the data in fixed format. Well, the new layouts do - the originals were fixed-length so no one would have to think (analysts or programmers). Now that this is standard, it is quite clear to everyone.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Sat Aug 06, 2011 1:48 pm
Reply with quote

Hello,

Which is why I asked about file size.

In a "sparsely populated" table, the savings can be very significant. With "not many records", the question is So What?

There are other techniques, like have two records, each with one ODO.

To proceed with the example here - once it has the counts on the record itself - I'd suggest writing a module to do the i/o for the file. This module can "normalise" the odos on the way in, and odo them on the way out.

All the programs using the data have a definition of the record with no odos, no added complexity to worry about
Back to top
View user's profile Send private message
dick scherrer

Moderator Emeritus


Joined: 23 Nov 2006
Posts: 19244
Location: Inside the Matrix

PostPosted: Sun Aug 07, 2011 3:06 am
Reply with quote

Hi Bill,

As important or possibly more than the space savings is the concept that the depending on count(s) must be in the record definition. Your example shows this, but the original does not.

The size saving was more just reminiscing on my part icon_wink.gif

d
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Sun Aug 07, 2011 5:09 am
Reply with quote

Hi Dick,

I think between us we've made the point at least half-a-dozen times. I hope it sticks :-)

I suppose that Cobol would let one write the record, and read it, but the data in the occurs' would be unusable, unless one happened to correctly "guess" the original values of the counts....
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Sun Aug 07, 2011 5:58 am
Reply with quote

One more shot and then I'm done unless Anil returns.

I've been checking, and this is from the Enterprise Cobol Programming Guide, Appendix B

Quote:
When you increment the value of the ODO object and add an element to a table,
you can inadvertently overlay the variably located data items that follow the table.
To avoid this type of error, do these steps:
1. Save the variably located data items that follow the table in another data area.
2. Increment the value of the ODO object.
3. Move data into the new table element (if needed).
4. Restore the variably located data items from the data area where you saved
them.


The lengths are not re-calculated every time the ODO object (name on the DEPENDING ON) changes like I said they used to be, but when an item affected by a variable-length table is referenced. This would be important when looking at a dump. The lengths present in the dump would actually be the lengths when it was last necessary to calculate them, not the lengths reflected by the current value of the ODO item.

From the Language Reference:

Quote:
The object of the OCCURS DEPENDING ON clause must not occupy any
storage position within the range of the table (that is, any storage position
from the first character position in the table through the last character
position in the table).


This might be a clue as to why TS thought the counters should not be in his 01. A guess. If correct, it is a misunderstanding of the above, which is saying that the ODO object must not be within the range of the storage occupied by the OCCURS.

This is confusing, I have to say, as it would be difficult to achieve.

Further:

Quote:
At the time that the group item, or any data item that contains a subordinate
OCCURS DEPENDING ON item or that follows but is not subordinate to the
OCCURS DEPENDING ON item, is referenced, the value of the object of the
OCCURS DEPENDING ON clause must fall within the range integer-1 through
integer-2.


The implication here is that there is some sort of "bounds" checking. This did not used to be the case, and I guess only by looking at the pseudo-assembler generated would be know if this is the case or not now.

Compiler option SSRANGE will apply to OCCURS DEPENDING ON, but that is seperate from the above.
Back to top
View user's profile Send private message
Marso

REXX Moderator


Joined: 13 Mar 2006
Posts: 1353
Location: Israel

PostPosted: Sun Aug 07, 2011 2:09 pm
Reply with quote

I wanted to write more detailed information, but them my wife shouted "What are you doing on the computer?" and "We are out of lemon!"...
But, as Bill said, the subject has been widely covered.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Sun Aug 07, 2011 2:13 pm
Reply with quote

Uncanny Marso, we have lemon but no flour, and I'm not supposed to be doing this either :-)

Edit: Rats, I said I'd stopped. Just struck by the odd co-incidence.
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> COBOL Programming

 


Similar Topics
Topic Forum Replies
No new posts Replace each space in cobol string wi... COBOL Programming 3
No new posts COBOL -Linkage Section-Case Sensitive COBOL Programming 1
No new posts COBOL ZOS Web Enablement Toolkit HTTP... COBOL Programming 0
No new posts Calling DFSORT from Cobol, using OUTF... DFSORT/ICETOOL 5
No new posts Generate random number from range of ... COBOL Programming 3
Search our Forums:

Back to Top