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

Problem in Unique Id generation using RANDOM


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

Active User


Joined: 03 May 2010
Posts: 154
Location: Kuala Lumpur

PostPosted: Thu Jan 23, 2014 9:01 am
Reply with quote

Hi All,

I have a situation, where I should create a unique id (length=25) in my COBOL program (CICS batch). Below given the format.

Code:
Position --> 0123456789012345678901234
Data     --> 2014012310584220*********
Meaning  --> YYYYMMDDHHMMSSMSRANDOMNUM


I've tried the below code for generate unique id.
Code:
01  WS-CURRENT-DATE-FIELDS.                   
   05  WS-CURRENT-DATE.                       
      10  WS-CURRENT-YEAR            PIC  9(4).
      10  WS-CURRENT-MONTH           PIC  9(2).
      10  WS-CURRENT-DAY             PIC  9(2).
   05  WS-CURRENT-TIME.                       
      10  WS-CURRENT-HOUR            PIC  9(2).
      10  WS-CURRENT-MINUTE          PIC  9(2).
      10  WS-CURRENT-SECOND          PIC  9(2).
      10  WS-CURRENT-MS              PIC  9(2).

05 RAND-NO1                       PIC 9(9).
05 WS-SEED                        PIC S9(4) COMP.

MOVE FUNCTION CURRENT-DATE       TO WS-CURRENT-DATE-FIELDS.
MOVE WS-CURRENT-MS               TO WS-SEED.
COMPUTE RAND-NO1 = FUNCTION RANDOM(WS-SEED) * 999999999.
MOVE WS-CURRENT-DATE-FIELDS      TO WS-UNIQUE-ID(1:16).
MOVE RAND-NO1                    TO WS-UNIQUE-ID(17:9).


It is generating below output as expected:
Code:
 2014012311062688400936804


But this program runs so much time from different users, where there is a posibilities of running multiple times at the same TIMESTAMP.
So the RANDOM function returning the same value and it because non-unique.

Could you guys can help me to overcome this issue. Even if you have any other logic/way to generate a unique id will also work for me.

Appriciate you efforts.
Back to top
View user's profile Send private message
Terry Heinze

JCL Moderator


Joined: 14 Jul 2008
Posts: 1249
Location: Richfield, MN, USA

PostPosted: Thu Jan 23, 2014 9:32 am
Reply with quote

WS-CURRENT-MS is only "hundredths" of a second of the current time. Can you replace it with a variation of MSSECONDMINUTEHOUR by using FUNCTION REVERSE of current time and expanding your seed length to S9(9) comp-5?
Back to top
View user's profile Send private message
sureshpathi10

Active User


Joined: 03 May 2010
Posts: 154
Location: Kuala Lumpur

PostPosted: Thu Jan 23, 2014 9:41 am
Reply with quote

Hi Terry,

I could try that, but, When the seed is same, output from RANDOM function is also same.
So, if this program runs twice in the same TIMESTAMP, RANDOM function returns the same random number, which I don't want.

Anyway I'll try your solution.
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 Jan 23, 2014 10:55 am
Reply with quote

You need to find something unique to include with your seed value -- in CICS systems, task number is usually a good choice.
Back to top
View user's profile Send private message
sureshpathi10

Active User


Joined: 03 May 2010
Posts: 154
Location: Kuala Lumpur

PostPosted: Thu Jan 23, 2014 11:21 am
Reply with quote

I agree Robert, Could you also give a hint about getting TASK number in a program?
Back to top
View user's profile Send private message
sureshpathi10

Active User


Joined: 03 May 2010
Posts: 154
Location: Kuala Lumpur

PostPosted: Thu Jan 23, 2014 12:02 pm
Reply with quote

I found that EIBTASKN will have the task number.
I couldn't test this scenario as we can't test in development for the same TIMESTAMP. I'll test in UAT and get back to you.

Could anyone brief, how this EIBTASKN getting generated, just curious ?
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 Jan 23, 2014 1:22 pm
Reply with quote

You need to understand the use of the seed.

The "random" number is a pseudo-random number generated by formula. Once one value is returned, the next value will always be the same. You don't have to worry about that in any way, it does not matter, but should be documented.

The "seed" tells random where to start. The same value seed always returns the same "random" value. The point of the seed is to give a reproduceable result.

Typically, you only provide one seed per run-unit. Show/record the seed. The rest happens automatically within the function processing.

If you only specify the seed once, you will not get a duplicate. If you don't specify the seed at all, you won't get a duplicate, but you will not be able to reproduce the sequence.
Back to top
View user's profile Send private message
sureshpathi10

Active User


Joined: 03 May 2010
Posts: 154
Location: Kuala Lumpur

PostPosted: Thu Jan 23, 2014 1:42 pm
Reply with quote

I'm completely understand Bill, and same found in here.
Quote:
For a given seed value, the sequence of pseudorandom numbers will always be the same.

When the program running multiple times with the same seed or without seed, all the output from RANDOM will be same.
So I need some unique seed to be used in RANDOM, which was well suggested Robert. Appreciate for your efforts though.
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10873
Location: italy

PostPosted: Thu Jan 23, 2014 1:52 pm
Reply with quote

Quote:
So I need some unique seed to be used in RANDOM, which was well suggested Robert. Appreciate for your efforts though.


did You care to try to understand what You were told ???

the seed is used ONLY during the TESTING phase in order to obtain reproducible results

once the testing is done DO NOT USE THE SEED and the random will return different values at each run of the program

thats the only case where audit/quality control will approve a promote to production of a source that has not been tested AS-PROMOTED
Back to top
View user's profile Send private message
sureshpathi10

Active User


Joined: 03 May 2010
Posts: 154
Location: Kuala Lumpur

PostPosted: Thu Jan 23, 2014 2:53 pm
Reply with quote

Of Course Enrico, I did understand, but if you run a program without seed, it will produce same set of random numbers.
I strongly suggest you to try this on your own (I've tried before posting here).

Quote:
the seed is used ONLY during the TESTING phase in order to obtain reproducible results

I guess, when seed is not specified it set to 'zero' as per this link

and Seed is not only for testing purpose, when we need of new sequence of pseudo-random numbers, we should use 'SEED'.
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 Jan 23, 2014 4:10 pm
Reply with quote

sureshpathi10,

In the code you have shown, you are using a seed every time. If you do this, you no longer have a random distribution.Understand the difference between a random distribution and something which looks sufficiently different from the last one that you think you have "random numbers".

The distribution may not matter in your case.

You limit your seed to four digits (or about 1/3 of five digits, depending on compile option).
This means, whatever your source of the seed, you have a maximum of 10,000 sequences. If using multiple seeds in a day, you will quickly run out of uniqueness for the nine-digit portion of your data, even though it is nine digits.

Use one seed per day. Make the seed value pretty big (very big) and not just big with a whole sequence of leading/trailer zeros (read the manual, the Enterprise COBOL, not ILE COBOL one). I always recorded the seed value, but can't say I used random numbers often and like enrico, I suspect, only from the Assembler RANDOM macro.

What is the multiply by lots of nines for? OK, I know what it is for, but why do it like that? Have a search here, there is a previous discussion you may find useful.
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Thu Jan 23, 2014 6:08 pm
Reply with quote

Quote:
Could anyone brief, how this EIBTASKN getting generated, just curious


The CICS Task Number (EIBTASKN) is generated internally by CICS (assigned to each Task) for each region and can be found in the TCA, mapped to DSECT DFHTCA, for each TCB. Don't try addressing the TCA in TS/3.2 and greater because the TCA-address (located in the CSA) is Fetch Protected (due to Threadsafe) and there's a different method to obtain the TCA-address. Just stick with EIBTASKN and you'll be fine.

As far as the random-number issue, you may consider using EIBTASKN (4-Bytes Packed-Decimal), the region's APPLID (8-Bytes Display) and a current Store-Clock value (either the standard 8-Byte binary-doubleword (STCK) or the extended 16-Byte binary-quadword (STCKE)).

Sub-Program "GETSTCK" -

Code:

*PROCESS RENT                          PROGRAM IS RE-ENTRANT           
***********************************************************************
*---------------------------------------------------------------------*
*                                                                     *
*        THIS SUB-PROGRAM RETURNS THE CURRENT STORE-CLOCK VALUE TO    *
*        THE CALLER AND CAN BE USED IN BOTH CICS AND BATCH. THE PPT   *
*        EXECUTION-KEY CAN BE 'USER' OR THIS SUB-PROGRAN CAN BE       *
*        STATICALLY CALLED (NO PPT-ENTRY REQUIRED).                   *
*                                                                     *
*        CALL SYNTAX:                                                 *
*                                                                     *
*        03  WS-GETSTCK-PARM-REC.                                     *
*            05  WS-GETSTCK-TOD    PIC S9(18)      BINARY.            *
*            05  WS-GETSTCK-TOD-X  REDEFINES WS-GETSTCK-TOD           *
*                                  PIC  X(08).                        *
*            05  WS-GETSTCK-PACKED PIC  X(16).                        *
*            05  WS-GETSTCK-RSA    PIC  X(72).                        *
*        03  WS-GETSTCK            PIC  X(08)      VALUE 'GETSTCK'.   *
*                                                                     *
*        CALL WS-GETSTCK               USING WS-GETSTCK-PARM-REC.     *
*                                                                     *
*        NOTE: WS-GETSTCK-PARM-REC DOES NOT REQUIRE INITIALISATION.   *
*                                                                     *
*---------------------------------------------------------------------*
***********************************************************************
         PRINT GEN                     ACTIVATE MACRO EXPANSION         
PRMDSECT DSECT                         PRMDSECT (R7)                   
         USING *,R7                    INFORM ASSEMBLER                 
PRMBEGIN EQU   *                       BEGIN-PARMAREA                   
PRMSTCK  DS    D                       CURRENT STORE-CLOCK (BINARY)     
PRMSTCKP DS    PL16                    CURRENT STORE-CLOCK (PACKED)     
PRMRSA   DS    XL72                    REGISTER-SAVEAREA               
PRMLGTH  EQU   *-PRMBEGIN              PARMAREA-LGTH                   
GETSTCK  CSECT                         BEGIN CSECT (R3)                 
         USING *,R3                    INFORM ASSEMBLER                 
         SAVE (14,12)                  SAVE REGISTERS                   
         LA    R3,0(,R15)              CSECT ADDRESSABIITY             
         J     ADDRPLST                ADDRESS PARMLIST                 
EYECTCHR DC    CL47' <<< ASSEMBLY DATE/TIME: &SYSDATC/&SYSTIME..00 >>>'
         ORG   EYECTCHR+6              REDEFINITION                     
         DC    X'A2A285948293A8'       LOWER-CASE 'SSEMBLY'             
         ORG   EYECTCHR+15             REDEFINITION                     
         DC    X'81A385'               LOWER-CASE 'ATE'                 
         ORG   EYECTCHR+20             REDEFINITION                     
         DC    X'899485'               LOWER-CASE 'IME'                 
         ORG   EYECTCHR+L'EYECTCHR     RESET LOCATION-COUNTER           
ADDRPLST DS    0H                      ENSURE ALIGNMENT                 
         L     R7,0(,R1)               PRMDSECT ADDRESSABILITY         
         XC    PRMBEGIN(PRMLGTH),PRMBEGIN                               
         LA    R15,PRMRSA              POINT TO OUR SAVEAREA           
         ST    R13,4(,R15)             BACKWARD-CHAIN                   
         ST    R15,8(,R13)             FORWARD-CHAIN                   
         LR    R13,R15                 POINT TO OUR SAVEAREA           
         STCK  PRMSTCK                 GET CURRENT-STCK                 
         LG    R1,PRMSTCK              PREPARE FOR 'LPGR'               
         LPGR  R1,R1                   MAKE IT POSITIVE                 
         CVDG  R1,PRMSTCKP             MAKE IT A PL16                   
         XR    R15,R15                 SET 'ALL IS WELL' RC             
         OC    PRMSTCK,PRMSTCK         STORE-CLOCK IS NON-ZERO?         
         JNZ   RTN2CLLR                YES, RETURN TO CALLER           
         XC    PRMSTCKP,PRMSTCKP       ENSURE X'00'S             
         LA    R15,16                  SET 'INVALID' RC                 
RTN2CLLR EQU   *                                                       
         OI    PRMSTCKP+L'PRMSTCKP-1,X'0F'                             
         L     R13,4(,R13)             RESTORE CALLER'S R13             
         XC    PRMRSA,PRMRSA           CLEAR OUR 'RSA'                 
         RETURN (14,12),RC=(15)        RESTORE REGISTERS AND RETURN     
         LTORG ,                                                       
         YREGS ,                       MVS REGISTER-EQUATE             
GETSTCK  AMODE 31 ,                                                     
GETSTCK  RMODE ANY ,                                                   
         END   ,                       END 'GETSTCK'                   

It was necessary to convert the STCK value to a PL16 within "GETSTCK". So, when you return to the caller, WS-GETSTCK-PACKED is treated as a PIC X(16) and can be moved as-is.

But after viewing a WS-GETSTCK-PACKED returned value, you could safely use positions 6-16 as part of your Random number (effectively, a PL11, which in COBOL is 9(21) PACKED-DECIMAL (if ARITH(EXTEND) were active).

This eliminates having to compile the calling program, specifying the ARITH(EXTEND) compiler option, which your compiler may or may not support.

IIRC, ARITH(EXTEND) was introduced with COBOL for OS/390, version 2.2.1 (about 11-13 years ago), but I've slept since then. icon_wink.gif

HTH....
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: Thu Jan 23, 2014 7:30 pm
Reply with quote

Hello,

Is it possible that there is no need for a random number? Unless i misunderstand, what is needed is a unique number. Why does it need to be random?
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10873
Location: italy

PostPosted: Thu Jan 23, 2014 8:08 pm
Reply with quote

icon_redface.gif
I was applying <some other language> rules ( REXX in this case )

probably worth looking at the equivalent LE function CEERAN0

-CEERAN0--(--seed--,--random_no--,--fc--)--------------------><

seed (input/output)
A fullword binary signed integer representing an initial value used to generate random numbers.
seed must be a variable; it cannot be an input-only parameter. The valid range is 0 to +2,147,483,646.

If seed equals 0, the seed is generated from the current Greenwich Mean Time.

On return to the calling routine, CEERAN0 changes the value of seed so that it can be used as the new seed in the next call.

random_no(output)
An 8-byte double precision floating-point number with a value between 0 and 1, exclusive.
If seed is invalid, random_no is set to -1 and CEERAN0 terminates with a non-CEE000 symbolic feedback code.

fc (output)
A 12-byte feedback code, optional in some languages, that indicates the resu
Back to top
View user's profile Send private message
sureshpathi10

Active User


Joined: 03 May 2010
Posts: 154
Location: Kuala Lumpur

PostPosted: Fri Jan 24, 2014 7:51 am
Reply with quote

Thanks Bill O'Boyle. I really appriciate your concerns.

I think, I owe Bill and Enrico a deep explanation of my situation.
(I've fixed it as Robert suggested and it is working fine).

I've a program with only one calling to RANDOM function.
Code:
COMPUTE RAND-NO1 = FUNCTION RANDOM * 999999999.

When I run this program without any seed I get "442707155".(run-unit 1)
When I run again I get the same value again.(run-unit 2) and so on.

I included a seed (millisecond) to the random function. So, when I test this program, it had given different random numbers as seed value were kept on changing.

At one case, where the seed value is same (consider this program running twice (run-unit1 & run-unit2) at the same millisecond) it produces the same random number, which affected my logic. So, I had come up with some seed values which will be unique for run-unit.

I hope, I didn't confuse more icon_smile.gif

Thanks guys for all your efforts.

icon_razz.gif
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: Fri Jan 24, 2014 7:18 pm
Reply with quote

Hello,

I'm still confused why a random number is needed?

For many years getting the "next available number" has worked well.
Back to top
View user's profile Send private message
Terry Heinze

JCL Moderator


Joined: 14 Jul 2008
Posts: 1249
Location: Richfield, MN, USA

PostPosted: Fri Jan 24, 2014 7:25 pm
Reply with quote

As Dick has mentioned, "next available number" guarantees uniqueness.
Back to top
View user's profile Send private message
sureshpathi10

Active User


Joined: 03 May 2010
Posts: 154
Location: Kuala Lumpur

PostPosted: Fri Jan 24, 2014 9:41 pm
Reply with quote

could you tell me what is next available number ?
Back to top
View user's profile Send private message
Nic Clouston

Global Moderator


Joined: 10 May 2007
Posts: 2455
Location: Hampshire, UK

PostPosted: Fri Jan 24, 2014 9:57 pm
Reply with quote

Quote:
could you tell me what is next available number ?

One more than the last number assigned - you have to keep track of it.
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: Fri Jan 24, 2014 10:24 pm
Reply with quote

Hello,

There are various ways to do this . . .

Typically the "next available" number is kept in a file or db table and as each new number is "taken" the number is incremented.
Back to top
View user's profile Send private message
sureshpathi10

Active User


Joined: 03 May 2010
Posts: 154
Location: Kuala Lumpur

PostPosted: Mon Jan 27, 2014 7:34 am
Reply with quote

This program is running million times a day and possibilities of running multiple times in a same TIME-STAMP.

So, I don't want to create a file/db-table to fetch the value and worry about these things.
1. Waste of resource (file/db)
2. Waste of process (read & update file/db)
3. Waste of CBU time (since I/O operation)
4. Cause of Deadlock.

A simple RANDOM function with unique seed would do my needful. It would be much faster then getting "next available number".

I'm sure "next available number" method will work on normal program that runs minimum times. Appreciate your suggestions icon_smile.gif
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: Mon Jan 27, 2014 7:58 pm
Reply with quote

Hello,

A million executions is not so many . . .

Also, i'll wager that using a file/table will add almost invisible overhead compared to whatever this process does.

Why do you believe the random number would be free?

If the next available number is in a file/table, it may never leave memory and there would be only logical i/o, not physical i/o.

There should be no chance for a deadlock if the code is properly implemented. If the code was written to get the next available as the first part of the code (and commit the change), the chance of a time-out is Greatly reduced if not eliminated.

Sounds like you already decided you want to use random. Keep in mind that this Can cause a duplicate that has to be dealt with.
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Mon Jan 27, 2014 9:01 pm
Reply with quote

In the CICS Forum, review the Sticky program DATETIME

ibmmainframes.com/viewtopic.php?t=61935

It's for CICS only (can be modified to be for Batch as well).

The Timestamp granularity is down to the microsecond.

If you combine the Date/Time (date-packed is PL5'0CCYYMMDD' and the time-packed is PL13'0HHMMSSTHMIJU"), together with the Task-Number as a PL4, you have a unique random number.
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 Map Vols and Problem Dataset All Other Mainframe Topics 2
No new posts Generate random number from range of ... COBOL Programming 3
No new posts Random read in ESDS file by using RBA JCL & VSAM 6
No new posts DFHPI1008 JSON generation failed COBOL Programming 0
No new posts VSAM return code 23 - for a Random read COBOL Programming 4
Search our Forums:

Back to Top