home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 294.lha / TurboFile / Demos / SORTFILE2.MOD < prev    next >
Text File  |  1989-10-09  |  6KB  |  173 lines

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