In order for this site to work correctly, and for us to improve the site, we need to store a small file (called a cookie) on your computer.
By continuing to use this website, you agree to our cookies and privacy policy.
Home page Home page Home page Home page
Pixel Header R1 C1 Pixel
Pixel Header R2 C1 Pixel
Pixel Header R3 C1 Pixel

V119 - Part I

When fields are not BTREE indexed on AREV the system must go through the long process if physically sorting records if a sorted report is requested. Those of you who leave the status line enabled will be familiar with the "% sorted" message whilst the process occurs. The mechanism to achieve this functionality is a program called EXTERNAL.SORT and I set out to document this. However it became apparent in the course of researches that EXTERNAL.SORT was horrendously complex to use BUT relied upon another routine to do most of the hard work for it, a routine called V119. This is an assembler routine and could best be described as "the SORT routine". As we don't wish to replace EXTERNAL.SORT I therefore opted to document V119 instead.

V119 is a multifunction routine designed both to sort data and to handle sort-file management. As these are two discrete areas this discussion will be split over two issues with this issue dealing with using V119 to sort blocks of data that can be fitted into one AREV variable. The first thing to be said for V119 is that it is FAST ! On first experimentation I thought that V119 wasn't actually sorting it sorted so fast. I was acheiving timings of 0.2 seconds to sort hundreds of records. Even on an XT performance is acceptable.

The calling syntax for V119 is

0001           CALL V119("S", "", ORDER, JUST, DATA, FLAG)


    ORDER    is the sort order, A for Ascending, D for Descending
      JUST     is the justification, L for Left, R for Right
      DATA     is the information to be sorted
      FLAG     is an indication of whether the operation failed or succeeded

Sorting Single Data Arrays

When the data to be sorted consists purely of single data elements the calling syntax is very straightforward. Consider the following lines of code designed to display a sorted list of entries on the VOC file.

0001      OPEN "VOC" TO VF THEN
0002         DAT = ""
0003         SELECT VF
0004         EOF = 0
0005         LOOP
0006            READNEXT ID ELSE EOF = 1
0007         UNTIL EOF DO
0008            DAT := ID : @RM
0009         REPEAT
0010         CALL DOSTIME(START)
0011         CALL V119("S", "", "A", "L", DAT, FLAG)
0013         CONVERT @RM TO @FM IN DAT
0014         DATA = "Took " : FINISH - START : @FM : DAT
0015         CALL MSG(DATA, "", "", "")
0016      END

Note that the data array to be sorted was built up with @RM (Record Markers - Char(255)) delimiters, note also that the data had a trailing @RM. This is intentional, the sort will fail without it.

There seems to be no significant length at which V119 fails to operate. That is to say, V119 does not sort by the first x characters, rather it sorts by all characters. This was verified using the following section of code

0001      A = STR(@UPPER.CASE, 1000)
0002      * This produces a variable of 26000 characters
0003      B = A
0004      A := "Z"
0005      B := "A"
0006      C = A : @RM : B : @RM
0007      CALL V119("S", "", "A", "L", C, FLAG)
0008      CONVERT @RM TO @FM IN C
0009      C[-1,1] = ""
0010      PRINT C<1>[-1,1]
0011      PRINT C<2>[-1,1]

This section of code printed Z followed by A, in other words it had sorted B before A.

Sorting Multiple Data Arrays

When the data to be sorted consists of multiple sort fields, the call to V119 has to be amended slightly. Firstly, for each sort field there must be a corresponding ORDER and JUSTIFICATION. This is accomplished by creating a string of characters with no delimiters for each passed parameter. Further the data passed should have data records @RM delimited, but sort fields within data records should be @FM delimited.

Thus assuming a requirement to sort a record by four fields, first sort being Ascending Left, second being Descending Right, third being Descending Left and fourth being Ascending Right, the ORDER paramenter would be "ADDA" and the JUSTIFICATION would be "LRLR". Thus modifying the example above to sort by four fields.

0001      EOF = 0
0002      LOOP
0003         READNEXT ID ELSE EOF = 1
0004      UNTIL EOF DO
0005         READ REC FROM VF, ID THEN
0006            DATA := FIELD(REC,@FM,1,4) : @RM
0007         END
0008      REPEAT
0009      CALL V119("S", "", "ADDA", "LRLR", DAT, FLAG)
0010      CONVERT @FM : @RM TO "-" : @FM IN DAT
0011      CALL MSG(DAT, "", "", "")

Sorting Single Data Arrays with Associated Values

When the data to be sorted consists of a single sort field with associated data fields (EG a date array with corresponding order quantities), the system will cope automatically, just pass the values delimited as above but omit the multiple sort criteria.

0001      DATES = @RECORD<10>
0002      AMOUNTS = @RECORD<11>
0003      CTR = COUNT(DATES, @VM) + (DATES # "")
0004      IF CTR THEN
0005         DAT = ""
0006         *
0007         * This could also be achieved by imaginative use of the ::: operator
0008         * and a CONVERT statement
0009         *
0010         FOR X = 1 TO CTR
0011            DAT := DATES<0,X> : @FM: AMOUNTS<0,X> : @RM
0012         NEXT
0013         CALL V119("S", "", "A", "R", DAT, FLAG)
0014         CONVERT @RM : @FM TO @FM : @VM IN DAT
0015         DAT[-1,1] = ""
0016         FOR X = 1 TO CTR
0017            @RECORD<10,X> = DAT<X,1>
0018            @RECORD<11,X> = DAT<X,2>
0019         NEXT
0020      END

This is still a remarkably quick way of sorting, and it keep track of the relationships internally. This type of routine can be used to best advantage on a pre-save process to ensure that records always display associated multivalues in the correct order. (Whether or not associated multi-values ought to be used extensively is a design decision which can be better addressed at a later date.)

Whilst this method is a quick way of achieving an associated single sort, it is worth bearing in mind that under some circumstances quicker results may be obtained by using a call to V119 to sort the controlling field followed by a standard insertion sort. This is of especial interest when the controlling multivalue can be guaranteed to be unique. EG

0001      DATES = @RECORD<10> ; OLD = DATES
0002      AMOUNTS = @RECORD<11>
0003      CTR = COUNT(DATES, @VM) + (DATES # "")
0004      IF CTR THEN
0005         CONVERT @VM TO @RM IN DATES
0006         DATES := @RM
0007         CALL V119("S", "", "A", "R", DATES, FLAG)
0008         CONVERT @RM TO @FM IN DATES
0009         DATES[-1,1] = ""
0010         DIM ARR(CTR)
0012         FOR X = 1 TO CTR
0014               @RECORD<10,X> = ARR<X>
0015               @RECORD<11,X> = AMOUNTS<0,Z>
0016            END
0017         NEXT
0018      END

(Volume 1, Issue 7, Pages 4,9,10)
Pixel Footer R1 C1 Pixel