|
|||||||
V119 - Part IWhen 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) where 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 ArraysWhen 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) 0012 CALL DOSTIME(FINISH) 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 ArraysWhen 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 ValuesWhen 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) 0011 MATPARSE DATES INTO ARR 0012 FOR X = 1 TO CTR 0013 LOCATE ARR<X> IN OLD USING @VM SETTING X THEN 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) |
|||||||
| |||||||