IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

z/OS Discussion :

Test (rapide) de l'existence d'un membre d'un PDS dans du REXX


Sujet :

z/OS

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 37
    Points : 44
    Points
    44
    Par défaut Test (rapide) de l'existence d'un membre d'un PDS dans du REXX
    Bonjour,

    Dans un programme REXX, j'ai besoin de savoir dans quel pds se trouve une copy COBOL. Pour cela j'utilise actuellement sysdsn.
    Le problème est que lorsque je dois effectuer plusieurs tests à la suite cela commence à prendre du temps.

    Ma question est donc : comment réaliser ce test d'existence de manière plus rapide?

    Merci d'avance.

  2. #2
    Membre confirmé Avatar de Homer-ac
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    449
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 449
    Points : 586
    Points
    586
    Par défaut
    tu fais directement un sysdsn sur le membre ?
    quelque chose dans le genre : if SYSDSN("'"COMPSRC"("COMPMBR")'") ^= 'OK' ?
    Ca ne devrait pas être mortel en temps sauf si tu as un grand nombre de PDS et de copy COBOL a balayer. Si c'est réellement le cas, tu as sans doute intérêt à te créer un référentiel en amont.
    J'ai déjà traité des trucs comme ça mais fait un peut usine à gaz et ce n'est pas si facile à expliquer.
    L'idée générale, Tu passes un ISRSUPC avec un SRCHFOR sur ' COPY ' de tous tes sources '(le 3.14 mais en Batch). qque chose comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    //SEARCH  EXEC PGM=ISRSUPC,PARM=(SRCHCMP,'IDPFX NOSUMS NOPRTCC')  
    //*                                                               
    //NEWDD  DD DISP=SHR,DSN=BIB.SOURCES.NO1                          
    //       DD DISP=SHR,DSN=BIB.SOURCES.NO2                          
    //       DD DISP=SHR,DSN=BIB.SOURCES.NO3                          
    //       DD DISP=SHR,DSN=....ETC........                          
    //OUTDD  DD DISP=(,PASS),DSN=&&LIST1,SPACE=(TRK,(90,90),RLSE),    
    //          UNIT=SYSALLDA,LRECL=133,RECFM=FB,BLKSIZE=0            
    //SYSIN  DD *                                                     
    SLIST OFF                                                         
    SRCHFOR ' COPY '                                                  
    CMPCOLM 8:60                                                      
    //*                                                               
    //* 02 - SUPPRESSION DES LIGNES NON SIGNIFICATIVES 
    //TRI002  EXEC PGM=SORT                                           
    //SYSOUT   DD  SYSOUT=*                                           
    //SYSPRINT DD  SYSOUT=*                                           
    //SORTIN   DD  DSN=&&LIST1,DISP=(OLD,DELETE)                      
    //SORTOUT  DD DISP=(,CATLG),DSN=&SORTIE,SPACE=(TRK,(90,90),RLSE), 
    //           UNIT=SYSALLDA,LRECL=132,RECFM=FB,BLKSIZE=0           
    //SYSIN    DD  *                                                  
     SORT FIELDS=(01,79,CH,A),EQUALS                                  
     OMIT COND=(01,01,CH,EQ,C' ')                                     
     SUM FIELDS=NONE                                                  
     OUTREC FIELDS=(1,132)                                            
    //*
    Tu as donc la liste des copy que tu appareilles avec les directory de tes PDS de COPY en syslib des procs de compilations COBOL. Tu peux utiliser un REXX ou IEHLIST pour ça. Tu ajoutes une 'bit map' sur chacune (010000, pour la première, 001000 pour la seconde, 000100 pour la 3ème etc, puis tu fais un SORT sur le nom de membre et un SUM FIELDS sur la bit map. qque chose comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    //S0001    EXEC PGM=SORT                               
    //SYSOUT   DD SYSOUT=*                                 
    //SORTIN   DD ...............    
    //SORTOUT  DD DSN=&&OUT1,DISP=(NEW,PASS),              
    //         LRECL=80,RECFM=FB,SPACE=(TRK,(1,1),RLSE)                      
    //SYSIN    DD *                                        
      SORT FIELDS=(1,50,CH,A)                              
      SUM  FIELDS=NONE                                     
      OUTREC FIELDS=(1,73,C'0010000')                      
    //*                                                    
    //S0002    EXEC PGM=SORT                               
    //SYSOUT   DD SYSOUT=*                                 
    //SORTIN   DD DSN=.............................
    //SORTOUT  DD DSN=&&OUT2,DISP=(NEW,PASS),              
    //         LRECL=80,RECFM=FB,SPACE=(TRK,(1,1),RLSE)                      
    //SYSIN    DD *                                        
      SORT FIELDS=(6,41,CH,A)                              
      SUM  FIELDS=NONE                                     
      OUTREC FIELDS=(1,73,C'0001000')
    ............................ 
    //* CUMUL SUR LES FICHIERS DE LA BITMAP 
    //S0030    EXEC PGM=SORT                                            
    //SYSOUT   DD SYSOUT=*                                              
    //SORTIN   DD DSN=&&OUT1,DISP=(OLD,DELETE)                          
    //         DD DSN=&&OUT2,DISP=(OLD,DELETE) 
    //         DD ..............................                         
    //SORTOUT  DD DSN=....................                              
    //SYSIN    DD *                                                     
      SORT FIELDS=(5,41,CH,A),EQUALS                                    
      SUM  FIELDS=(74,7,ZD)                                             
    //*
    La position du ou des 1 te donne la ou les bibli qui contiennent la COPY, id avec le résultat d'ISRSUPC (avec 100000), ton fichier résultant te donne un état des lieux complet. Je sais c'est tordu mais je te donne juste un truc pour des références croisées un peu complexes assez facile à développer en JCL basique avec un peu d'habitude..

  3. #3
    Membre confirmé Avatar de Homer-ac
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    449
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 449
    Points : 586
    Points
    586
    Par défaut
    Tout d'abord mes excuses ekans, la fonction SYSDSN est tellement usuelle dans un REXX que je n'avais pas remarqué qu'il y avait des problèmes de performances particuliers de ce côté (il faut dire qu'en REXX, les performances ce n'est pas top de toutes façons).
    Comme j'avais répondu un peu trop vite sans vérifier, j'ai regardé d'un peu plus près. Effectivement, sysdsn n'est pas brillant si on multiplie les appels, et j'en suis le premier surpris. J'ai testé le REXX suivant: on recherche un certain nombre de membres dans 5 PDS. D'abort par SYSDSN, puis par Library management. Cette dernière méthode est 5 à 6 fois plus rapide !
    Le REXX testé : (effectivement les temps de ton REXX vont bigrement s'améliorer si tu passes par un LMMFIND).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    /* REXX SYSDSN/LMMFIND */
    TB.1 = 'membre1'                                                      
    TB.2 = 'membre2'                                                      
    TB.3 = 'membre3'                                                      
    TB.4 = 'membre4'                                                     
    TB.5 = 'membre5'                                                      
    TB.6 = 'membre6'                                                         
    TB.7 = 'inexistant'                                                         
    TF.1 = 'Premier PDS'
    TF.2 = 'Second PDS''                                                  
    TF.3 = 'PDS-3'                                                  
    TF.4 = 'PDS-4'                                          
    TF.5 = 'PDS-5'                                                 
    say 'on cherche'   TB.1","TB.2","TB.3","TB.4","TB.5","TB.6","TB.7      
    DEBUT= Sysvar('SYSCPU')   /* temps de départ */
    do i2 = 1 to 7  /* recherche par SYSDSN */     
       do I1 = 1 to 5                                                      
          TF = TF.I1                                                       
          DSN ="'"TF.I1"("TB.I2")'"                                        
          if Ssysdsn(DSN) = 'OK' then do                                    
             say left(TB.I2,8) 'sur' TF.I1                                 
             I1 = 999                                                      
             leave                                                         
          end                                                              
          if I1 = 5 then say left(TB.I2,8) 'est inconnu !'                 
        end                                                                  
     end                                                                     
     FIN  = Sysvar('SYSCPU')                                                 
     say 'Temps = ' FIN - DEBUT  
    /* recherche par LMMFIND */                               
     Address ISPEXEC                                                         
     "CONTROL ERRORS RETURN"                                                 
     DDNAME='TEMP01' ; MYBIB = "'"TF.1"','"TF.2"','"TF.3"','"TF.4"','"TF.5"'" 
    address tso "ALLOC DA("MYBIB") FILE("DDNAME") SHR REUSE"  /* ALLOC TSO */              
     "LMINIT  DATAID(DAID1) DDNAME("DDNAME") ENQ(SHRW)"                      
     "LMOPEN  DATAID("DAID1") OPTION(INPUT)"                                 
     if rc > 0 then exit RC                                                  
     do I2 = 1 to 7                                                          
        "LMMFIND DATAID("DAID1") MEMBER("TB.I2") STATS(YES)"                 
         if RC = 0 then say left(TB.I2,8) 'sur' TF.ZLLIB                     
         else say           left(TB.I2,8) 'est inconnu !'                    
     end                                                                     
     "LMCLOSE DATAID("DAID1")"                                               
     "LMFREE  DATAID("DAID1")"                                               
     say 'Temps = ' Sysvar('SYSCPU') - FIN                                   
     exit
    PS: je laisse quand même la réponse précédente, l'idée du SORT avec SUM sur une 'bit map' peut quand même servir à certains.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 37
    Points : 44
    Points
    44
    Par défaut
    Merci Homer-ac, mon rexx va 2 fois plus vite maintenant!

    Je suis passer de 0.20 à 0.10 en seconde cpu ce qui est non négligeable car j'utlise cette macro très souvent quand je parcours un programme COBOL.

  5. #5
    Membre confirmé Avatar de Homer-ac
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    449
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 449
    Points : 586
    Points
    586
    Par défaut
    J'avais constaté de mon côté un gain plus important.
    les bib sont des PDS ou des PDSE (type LIBRARY) ?
    La taille de la directory peut bien entendu tout changer. Sinon pour une macro EDIT tres répétitive tu peux essayer la séquence suivante :
    (en fonction du contexte tu peux ainsi éviter des alloc multiples puisque la liste des bib. de copy est stable).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    /* recherche par LMMFIND */                               
     Address ISPEXEC                                                         
     "CONTROL ERRORS RETURN"                                                 
     DDNAME='TEMP01' ; MYBIB = "'"TF.1"','"TF.2"','"TF.3"','"TF.4"','"TF.5"'" 
     "LMINIT  DATAID(DAID1) DDNAME("DDNAME") ENQ(SHRW)" 
    if RC > 0 then do 
       x=msg('OFF') 
       address tso "FREE F("DDNAME") 
       x=msg('ON') 
       address tso "ALLOC DA("MYBIB") FILE("DDNAME") SHR REUSE"  /* ALLOC TSO */  
       "LMINIT  DATAID(DAID1) DDNAME("DDNAME") ENQ(SHRW)"  /* RETRY */
       if RC > 4 then exit RC
    end
     "LMOPEN  DATAID(DAID1) .....

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 37
    Points : 44
    Points
    44
    Par défaut
    Il s'agit bien de PDSE.
    La différence de performance est surtout dû au fait que j'utilisais des pipes dans la suite de la macro pour récupérer le contenu des copy. Je les ai remplacé par LMGET qui est bien plus performant.
    J'ai aussi rajouté ton astuce pour éviter d'allouer/désallouer à chaque utilisation de la macro.
    Maintenant je suis passer à 0.02 secondes cpu dans le pire des cas.

    Sinon comment fait-on pour passer la discussion en résolu?

  7. #7
    Membre confirmé Avatar de Homer-ac
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    449
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 449
    Points : 586
    Points
    586
    Par défaut
    J'ai corrigé une bourde dans mon post précédent, sympa tu l'as surement relevée mais pas notée. quant à la marque résolu il me semble que si tu saisis ton identifiant et passes en Edit sur un post que tu as ouvert, tu devrais avoir le bouton qui va bien.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 11/06/2014, 12h10
  2. test si une valeur existe dans un tableau
    Par Maria1505 dans le forum Servlets/JSP
    Réponses: 10
    Dernier message: 15/08/2007, 18h10
  3. JUnit Test type does not exist
    Par theAlex dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 10/07/2007, 14h13
  4. [XML] Teste si un attribut existe
    Par jbrasselet dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 04/07/2007, 13h55
  5. test si une form existe déjà
    Par coucoucmoi dans le forum Composants VCL
    Réponses: 5
    Dernier message: 09/12/2003, 19h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo