Wednesday 7 March 2012

Dynamic Variable with Dynamic Array Occurrence

Most of has used dynamic variables in natural, with 4.1 we can abuse it further by utilizing it in dynamic array as well. Probably I should have explained what came along with 4.1 features first but one of the biggest advantages of 4.1 features is its advantage to hold more than 32K of data in work area. In fact we can have 1GB (but please check with your environment support or DBA’s before you decide to invoke these features, it may snap your system if not wisely coded). The major advantage of dynamic variable with dynamic array occurrence is the elimination of “Index not within array structure” errors since we code it in such a way as to have a upper limit based on forecasted growth. And if used wisely, we can eliminate this error completely (but please make sure someone does a good code reviewJ). The option is a double edged sword: it not only eliminates “Index not within array structure” and loads or dynamically expands array data based on growth but with the negative fallout that if it exceeds 1GB your process falls over. So be very cautious on its usage.

The simple trick in a dynamic variable with dynamic array occurrence is to capture the current occurrence by just moving the *COUNTER variable to the counter variable to expand the dynamic variable & array. The result is – a characteristic of passed field is taken as characteristics of the result field for dynamic field. And it’s most efficient usage would be to use in loading reference-data.



A sample piece of code will look like this:



DEFINE DATA LOCAL
01 REF VIEW OF REFERENCE-DATA
  02 RD-KEY             /* 15 BYTES OF SUPER-DESCRIPTOR
  02 REDEFINE RD-KEY
     03 RD-KEY1 (A5)          /* FIRST HALF OF SUPER
     03 RD-DATA (A10)         /* SECOND HALF OF SUPER

01 #START-RD-KEY (A15)
01 #END-RD-KEY   (A15)
01 #CITY-ARRAY   (A/*) DYNAMIC
01 #CITY-COUNT   (I4)
01 #CITY-INDEX   (I4)
END-DEFINE
*
RESET #START-RD-KEY #END-RD-KEY #CITY-COUNT
COMPRESS 'MIAMI' INTO #START-RD-KEY LEAVING NO SPACE
COMPRESS 'MIAMI' H'FF' INTO #END-RD-KEY LEAVING NO SPACE
*
HISTOGRAM MULTI-FETCH OF 1000 REF FROM #START-RD-KEY
 TO #END-RD-KEY
  ADD 1 TO #CITY-COUNT /* Or Move *COUNTER
  EXPAND ARRAY #CITY-ARRAY TO (1:#CITY-COUNT) /* expands the array to counter
  MOVE RD-DATA TO #CITY-ARRAY (#CITY-COUNT) /* resultant variable takes characteristics of moving variable
END-HISTOGRAM
*
* Sample code to check if data is loaded
IF #CITY-COUNT > 0
  IF #CITY-ARRAY (*) EQ SCAN 'MIAMI'
/* SCAN is a new option in 4.1 and similar to examine but just checks for existence of a value
      WRITE 'MATCH FOUND FOR MIAMI'
  ELSE
      WRITE 'MATCH NOT FOUDN FOR MIAMI'
  END-IF
END-IF
END



If used wisely the advantages are limitless providing a good optimization in many fronts wherever applicable, probably opening the Pandora’s Box for another discussion (loading most frequent data to array for optimized performance :-)).




3 comments:

  1. hey your blog appears in top 3 google search result for "dynamic variable in natural and adabase".

    for elsewhere i read that EXPAND, RESIZE and REDUCE do not impact current physical size of a dynamic variable. e.g.

    DEFINE DATA LOCAL
    1 #D (A) DYNAMIC
    1 #A (A20) INIT <'QWERTASDFG'>
    1 #LENGTH (I2)
    END-DEFINE
    *
    MOVE #A TO #D
    *
    EXAMINE #D FOR 'X' GIVING LENGTH #LENGTH
    *
    WRITE '*LENGTH FOR #D IS: ' *LENGTH (#D) /
    '#LENGTH FOR #D IS: ' #LENGTH
    PRINT 'VALUE OF #D IS:' #D
    *
    EXPAND DYNAMIC #D TO 30
    *
    WRITE '-- AFTER EXPAND DYNAMIC --'
    WRITE '*LENGTH FOR #D IS: ' *LENGTH (#D) /
    '#LENGTH FOR #D IS: ' #LENGTH
    *
    MOVE '**' TO SUBSTRING (#D,27,2)
    EXAMINE #D FOR 'X' GIVING LENGTH #LENGTH
    *
    WRITE '-- AFTER MOVE TO SUBSTRING --'
    WRITE '*LENGTH FOR #D IS: ' *LENGTH (#D) /
    '#LENGTH FOR #D IS: ' #LENGTH
    *
    END

    would produce following output

    *LENGTH FOR #D IS: 20
    #LENGTH FOR #D IS: 10
    VALUE OF #D IS: QWERTASDFG

    -- AFTER EXPAND DYNAMIC --
    *LENGTH FOR #D IS: 20
    #LENGTH FOR #D IS: 10
    This was followed by NAT1326 error message.


    By my understaning about Dynamic variable (they are stored in buffer with some padding area, so as long as padding is not exhausted they can be expanded and ofcourse can be reduced in size).

    Your views on this???

    Sachin

    ReplyDelete
    Replies
    1. Making use of Dynamic arrays in the right places does make sense and may provide faster execution when used appropriately.if you do MOVE 'A' TO FIXED-FIELD-8-BYTES, Natural has to move the character and then blank out the rest of the field; if you do MOVE 'A' TO DYNAMIC-VARIABLE Natural moves the character and then simply sets the length, which is usually faster than blanking the rest of the field, especially when the fixed field would be greater than 256 bytes. Also, EXPAND/REDUCE/RESIZE don't necessary change any memory allocations (and those are the things that slow down performance) because Natural generally allocates memory for a dynamic variable in 64 or 256 byte increments (of course, the program doesn't know) so if the length changes within reasonable size , it's just a length setting for the data, but no memory re-allocation. There are also downsides, such as, you can't redefine them so if you must use MOVE SUBSTRING, there goes some of your gain. As for expandable array, FANTASTIC! They may not be faster than fixed arrays, but the only thing that will cause an array overflow in batch is going over 2 GB. Great for eliminating maintenance headaches.

      Delete
  2. Naturally Adabas: Dynamic Variable With Dynamic Array Occurrence >>>>> Download Now

    >>>>> Download Full

    Naturally Adabas: Dynamic Variable With Dynamic Array Occurrence >>>>> Download LINK

    >>>>> Download Now

    Naturally Adabas: Dynamic Variable With Dynamic Array Occurrence >>>>> Download Full

    >>>>> Download LINK

    ReplyDelete