home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 294.lha / TurboFile / Demos / SortFile.mod < prev    next >
Encoding:
Text File  |  1989-10-09  |  5.8 KB  |  169 lines

  1. MODULE SortFile;
  2. (*
  3.      Written by Dexter (Chip) Orange     July, 1987.
  4.  
  5.      This program was written in order to demonstrate the extraordinary
  6. features of the TurboFile system.  Its purpose is to sort a large file
  7. (one that won't fit into memory, and therefore, the AmigaDOS sort utility
  8. can't be used on) by creating an index on the specified sort key field, and
  9. then copying the input file to an output file in indexed (sorted) order.
  10. *)
  11.  
  12.  
  13. FROM SYSTEM IMPORT
  14.   ADR, ADDRESS;
  15. FROM RandomIO IMPORT
  16.   RandomFile, CloseRandomFile,  ReadRandomFile, RandomFileMode,
  17.   FileWriteAccessMode, SetWriteAccessMode, OpenRandomFile, WriteRandomFile,
  18.   NumRecs, Reset, RIOErrorMessage;
  19. FROM Indexes IMPORT
  20.   IndexFile, CreateIndex, CloseIndex, KeyPtr, FirstRecord, NextRecord,
  21.   OpenIndex, IndErrorMessage;
  22. FROM InOut IMPORT
  23.   WriteString, WriteLn, ReadString, WriteCard, ReadCard;
  24. FROM InOut IMPORT
  25.   WriteLongCard;
  26. FROM Memory IMPORT
  27.   FreeMem, AllocMem, MemReqSet, MemPublic, AvailMem;
  28. FROM DOS IMPORT
  29.   DeleteFile;
  30.  
  31.  
  32. CONST
  33.   TempFile = 'SORTFILE.INDEX';
  34.  
  35.  
  36. VAR
  37.   InputBS, OutputBS, IndexBS, BS, Rec, Rec2: LONGCARD;
  38.   FN, FN2, Comment: ARRAY [0..80] OF CHAR;
  39.   F, F2: RandomFile;
  40.   Index: IndexFile;
  41.   Col, KeyLength, RecLength, CommentSize: CARDINAL;
  42.   CurRec: KeyPtr;                       (* pointer to current record *)
  43.   Error: BOOLEAN;
  44.  
  45.  
  46. PROCEDURE AnotherRecord(VAR RecNum: LONGCARD; VAR KEY: KeyPtr): BOOLEAN;
  47. (* this procedure is called by CreateIndex in order to determine if there
  48. is another record to be added to the index.  If so, then RecNum is set to the
  49. record number, and KeyPtr is set to point to the associated key for that record.
  50. Note that a key need not be a simple field of a record, it can be any
  51.  combination
  52. of items you care to construct.  Also note that not every record in a file
  53. need be included in the index (this is especially nice when you have many
  54. records where the key field is blank).
  55. *)
  56. BEGIN
  57.   KEY := ADDRESS(LONGCARD(CurRec)+LONGCARD(Col-1));
  58.   INC(Rec);
  59.   RecNum := Rec;
  60. (* ReadRandomFile will return FALSE if there are no more records *)
  61.   RETURN ReadRandomFile(F, CurRec^, Rec);
  62. END AnotherRecord;
  63.  
  64.  
  65. BEGIN
  66.   WriteString('enter input file name: ');
  67.   ReadString(FN);
  68.   WriteLn;
  69.   WriteString(' enter output file name: ');
  70.   ReadString(FN2);
  71.   WriteLn;
  72.   WriteString(' enter record length: ');
  73.   ReadCard(RecLength);
  74.   WriteLn;
  75.   WriteString(' enter beginning column for key field: ');
  76.   ReadCard(Col);
  77.   WriteLn;
  78.   WriteString(' enter key field length: ');
  79.   ReadCard(KeyLength);
  80.   WriteLn;
  81. (* allocate an area to hold the current record *)
  82.   CurRec := AllocMem(LONGCARD(RecLength), MemReqSet{MemPublic});
  83.   IF (CurRec = NIL) THEN
  84.     WriteString(' out of memory ');
  85.     WriteLn;
  86.     RETURN;
  87.   END;
  88.   BS := AvailMem(MemReqSet{MemPublic}) DIV 2;
  89. (* only use half the available memory for file buffering *)
  90. (* divide the buffer space between the input and index files, giving the
  91. index file the lions share *)
  92.   InputBS := BS DIV 4;
  93.   IndexBS := BS-InputBS;
  94.   IF (NOT OpenRandomFile(F, FN, ReadOnly, RecLength, 0, InputBS)) THEN
  95.     WriteString(' unable to open input file  -- ');
  96.     WriteString(RIOErrorMessage);
  97.     WriteLn;
  98.   ELSE
  99.     WriteString(' sorting ');
  100.     WriteLongCard(NumRecs(F), 6);
  101.     WriteString(' records');
  102.     WriteLn;
  103. (* create the index *)
  104.     Rec := 0;
  105.     IF (NOT CreateIndex(Index, TempFile, 'TurboFile', 10, AnotherRecord,
  106.     KeyLength, IndexBS)) THEN
  107.       WriteString(' create index failed  -- ');
  108.       WriteString(IndErrorMessage);
  109.       WriteLn;
  110.     ELSE
  111. (* now the input file is going to be read in a very random order, rather than
  112. sequentially as when the index was created, so re-assign the allocations
  113. of the available buffer space so that the input file has very little, since
  114. random reading doesn't benefit much at all from a large buffer *)
  115.       InputBS := LONGCARD(2*RecLength);
  116.       IndexBS := (BS-InputBS) DIV 2;
  117.       OutputBS := InputBS;
  118.       Reset(F, RecLength, 0, InputBS);
  119. (* close the index file, and re-open it as a ReadOnly file, so that all its
  120. buffer space can be used as a read buffer *)
  121.       CloseIndex(Index);
  122.       Error := NOT OpenIndex(Index, TempFile, Comment, CommentSize, ReadOnly,
  123.       IndexBS);
  124.       IF (Error) THEN
  125.         WriteString(' unable to re-open index -- ');
  126.         WriteString(IndErrorMessage);
  127.         WriteLn;
  128.       END;
  129. (* now copy the input file in indexed order to the output file *)
  130.       IF (NOT OpenRandomFile(F2, FN2, NewFileWriteOnly, RecLength, 0, OutputBS))
  131.       THEN
  132.         WriteString(' unable to create output file  -- ');
  133.         WriteString(RIOErrorMessage);
  134.         WriteLn;
  135.       ELSE                              (* IF NOT OpenRandomFile *)
  136.         SetWriteAccessMode(F2, Sequential);
  137. (* improves write speed *)
  138.         Rec2 := 1;
  139.         IF (FirstRecord(Index, Rec)) THEN
  140. (* there is at least one record in the input file, and REC has its number *)
  141.           Error := FALSE;
  142.           REPEAT
  143.             IF (NOT ReadRandomFile(F, CurRec^, Rec)) THEN
  144.               WriteString(' error while reading input file  -- ');
  145.               WriteString(RIOErrorMessage);
  146.               WriteLn;
  147.               Error := TRUE;
  148.             ELSIF (NOT WriteRandomFile(F2, CurRec^, Rec2)) THEN
  149.               WriteString(' error  while writing output file  -- ');
  150.               WriteString(RIOErrorMessage);
  151.               WriteLn;
  152.               Error := TRUE;
  153.             ELSE
  154.               INC(Rec2);
  155.             END;                        (* if *)
  156.           UNTIL ((Error) OR (NOT NextRecord(Index, Rec)));
  157.         END;                            (* IF FirstRecord *)
  158.         CloseRandomFile(F2);
  159.       END;                              (* if OpenRandomFile *)
  160.       CloseIndex(Index);
  161.       Error := Error OR (NOT DeleteFile(ADR(TempFile)));
  162.     END;
  163.        (* if CreateIndex *)
  164.     CloseRandomFile(F);
  165.   END;
  166.      (* IF NOT OpenRandomFile *)
  167.   FreeMem(CurRec, LONGCARD(RecLength));
  168. END SortFile.
  169.