星期三, 11月 01, 2023

2002-03-18 如何於 AS/400(iSeries) 上作資料壓縮?


如何於 AS/400(iSeries) 上作資料壓縮?

當有資料於AS/400(iSeries)間作大量資料傳輸時,使用資料壓縮技術可以使資料量大幅縮小,
提昇網路效率及縮短處理時間,AS/400(iSeries)本身即提供硬體(Tape Driver)及軟體壓縮,這
種功能對於 MQ Series 的資料傳輸特別有用,可以利用 Database 的 variable length field 
屬性將 PF 欄位定義為 VARLEN(length)

 A   VARFL1  125     COLHDG('Variable' 'Length'  'Alc 25') 
 A              VARLEN(25) 

表示預設長度25位長,當欄位長26時,此時在
資料庫中真正長度是50,每次加25直到125欄位長度為止。

於compile RPG 時需指定specify Convert Option Parameter of CVTOPT(*VARCHAR). 

此次我只使用傳統的PF並不使用 keyword VARLEN
            

建立測試資料庫
CRTPF FILE(CPRDTA) RCDLEN(240) IGCDTA(*YES)


壓縮程式
File  :QRPGLESRC
Member:COMPRESSR
Type  :RPGLE
Usage :CRTBNDRPG PGM(COMPRESSR)

     H debug(*yes) DFTACTGRP(*NO)
      * IBM offers two algorithms: simple terse (whatever that is) and
      *                            LZ1.
      * IBM's patented implementation of the Lempel-Ziv algorithm,
      * used in WinZip and pkzip.
      * To use compression, you need to provide the address and length of
      * the source and result strings, and the algorithm number.
      * (1=Simple Terse, 2=IBM LZ1.)

     FCPRDTA    UF A F  240        Disk
      * Prototype for MI builtin function:
     D Compress        pr                  Extproc('_CPRDATA')
     D  RcvrPtr                        *   Value

      * Compression template:

     D Rcvr            ds
     D  SourceLen                    10i 0 Inz(%Size(Source))
     D  ResultLen                    10i 0 Inz(%Size(Result))
     D  CompressLen                  10i 0 Inz(0)
     D  Algorithm                     5i 0 Inz(2)
     D                               18    Inz(*LOVAL)
     D  SourcePtr                      *   Inz(%Addr(Source))
     D  ResultPtr                      *   Inz(%Addr(Result))

     D Source          s           2400    Inz(*ALL'The cat sat on the mat.')
     D Result          s           2400

     ICPRDTA    AA  01
     I                                  1  240  DATA

     C                   Eval      DATA = Source
     C                   Except    WRTDTA
     C                   CallP     Compress (%Addr(Rcvr))
     C                   Eval      DATA = Result
     C                   Except    WRTDTA

     C                   Eval      *InLR = *On

     OCPRDTA    EADD         WRTDTA
     O                       DATA               240

       

解壓縮程式
File  :QRPGLESRC
Member:DCOMPRESSR
Type  :RPGLE
Usage :CRTBNDRPG PGM(DCOMPRESSR)

     H debug(*yes) DFTACTGRP(*NO)
     FCPRDTA    UF A F  240        Disk
      * Prototype for MI builtin function:
     D Decompress      pr                  Extproc('_DCPDATA')
     D  RcvrPtr                        *   Value

      * Decompression template:
     D Rcvr            ds
     D                                4    Inz(*LOVAL)
     D  ResultLen                    10i 0 Inz(%Size(Result))
     D  DecompressLen                10i 0 Inz(0)
     D                               20    Inz(*LOVAL)
     D  SourcePtr                      *   Inz(%Addr(Source))
     D  ResultPtr                      *   Inz(%Addr(Result))

     D Source          s           2400
     D Result          s           2400

     ICPRDTA    AA  01
     I                                  1  240  DATA

     C                   Read      CPRDTA
     C                   Read      CPRDTA

     C                   Eval      Source = Data
     C                   CallP     Decompress (%Addr(Rcvr))
     C                   Eval      Data = Result
     C                   Except    WRTDTA

     C                   Eval      *InLR = *On

     OCPRDTA    EADD         WRTDTA
     O                       DATA               240


            

測試程式的流程
Call COMPRESSR 將測試原始資料寫入 CPRDTA(第一筆)
          將測試資料壓縮並寫入 CPRDTA
Call DCOMPRESSR從 CPRDTA 讀取被壓縮的資料(及第二筆)
          將讀取的壓縮的資料解壓縮並寫入 CPRDTA(第三筆)

DSPPFM CPRDTA 可看出第一筆與第三筆資料是一樣的

你可以利用範例程式,規劃你的壓縮程序
            



沒有留言: