home *** CD-ROM | disk | FTP | other *** search
- MODULE SortFile2;
- (*
- Written by Dexter (Chip) Orange July, 1987.
-
- This program was written in order to demonstrate the extraordinary
- features of the TurboFile system. Its purpose is to sort a large file
- (one that won't fit into memory, and therefore, the AmigaDOS sort utility
- can't be used on) by creating an index on the specified sort key field, and
- then copying the input file to an output file in indexed (sorted) order.
- It does this a little differently than the SortFile program by using
- routines from the SequentialIO module for the output file.
-
- *)
-
-
- FROM SYSTEM IMPORT
- ADR, ADDRESS;
- FROM RandomIO IMPORT
- RandomFile, CloseRandomFile, ReadRandomFile, RandomFileMode, OpenRandomFile,
- NumRecs, Reset, RIOErrorMessage;
- FROM SequentialIO IMPORT
- OpenSequentialFile, SequentialFileMode, WriteSequentialFile,
- CloseSequentialFile, SequentialFile , SIOErrorMessage;
- FROM Indexes IMPORT
- IndexFile, CreateIndex, CloseIndex, KeyPtr, FirstRecord, NextRecord,
- OpenIndex, IndErrorMessage;
- FROM InOut IMPORT
- WriteString, WriteLn, ReadString, WriteCard, ReadCard;
- FROM InOut IMPORT
- WriteLongCard;
- FROM Memory IMPORT
- FreeMem, AllocMem, MemReqSet, MemPublic, AvailMem;
- FROM DOS IMPORT
- DeleteFile;
-
-
- CONST
- TempFile = 'SORTFILE.INDEX';
-
-
- VAR
- InputBS, OutputBS, IndexBS, BS, Rec, Rec2: LONGCARD;
- FN, FN2, Comment: ARRAY [0..80] OF CHAR;
- F: RandomFile;
- F2: SequentialFile;
- Index: IndexFile;
- Col, KeyLength, RecLength, CommentSize: CARDINAL;
- CurRec: KeyPtr; (* pointer to current record *)
- Error: BOOLEAN;
-
-
- PROCEDURE AnotherRecord(VAR RecNum: LONGCARD; VAR KEY: KeyPtr): BOOLEAN;
- (* this procedure is called by CreateIndex in order to determine if there
- is another record to be added to the index. If so, then RecNum is set to the
- record number, and KeyPtr is set to point to the associated key for that record.
- Note that a key need not be a simple field of a record, it can be any
- combination
- of items you care to construct. Also note that not every record in a file
- need be included in the index (this is especially nice when you have many
- records where the key field is blank).
- *)
- BEGIN
- KEY := ADDRESS(LONGCARD(CurRec)+LONGCARD(Col-1));
- INC(Rec);
- RecNum := Rec;
- (* ReadRandomFile will return FALSE if there are no more records *)
- RETURN ReadRandomFile(F, CurRec^, Rec);
- END AnotherRecord;
-
-
- BEGIN
- WriteString('enter input file name: ');
- ReadString(FN);
- WriteLn;
- WriteString(' enter output file name: ');
- ReadString(FN2);
- WriteLn;
- WriteString(' enter record length: ');
- ReadCard(RecLength);
- WriteLn;
- WriteString(' enter beginning column for key field: ');
- ReadCard(Col);
- WriteLn;
- WriteString(' enter key field length: ');
- ReadCard(KeyLength);
- WriteLn;
- (* allocate an area to hold the current record *)
- CurRec := AllocMem(LONGCARD(RecLength), MemReqSet{MemPublic});
- IF (CurRec = NIL) THEN
- WriteString(' out of memory ');
- WriteLn;
- RETURN;
- END;
- BS := AvailMem(MemReqSet{MemPublic}) DIV 2;
- (* only use half the available memory for file buffering *)
- (* divide the buffer space between the input and index files, giving the
- index file the lions share *)
- InputBS := BS DIV 4;
- IndexBS := BS-InputBS;
- IF (NOT OpenRandomFile(F, FN, ReadOnly, RecLength, 0, InputBS)) THEN
- WriteString(' unable to open input file -- ');
- WriteString(RIOErrorMessage);
- WriteLn;
- ELSE
- WriteString(' sorting ');
- WriteLongCard(NumRecs(F), 6);
- WriteString(' records');
- WriteLn;
- (* create the index *)
- Rec := 0;
- IF (NOT CreateIndex(Index, TempFile, 'TurboFile', 10, AnotherRecord,
- KeyLength, IndexBS)) THEN
- WriteString(' create index failed -- ');
- WriteString(IndErrorMessage);
- WriteLn;
- ELSE
- (* now the input file is going to be read in a very random order, rather than
- sequentially as when the index was created, so re-assign the allocations
- of the available buffer space so that the input file has very little, since
- random reading doesn't benefit much at all from a large buffer *)
- InputBS := LONGCARD(2*RecLength);
- IndexBS := (BS-InputBS) DIV 2;
- OutputBS := InputBS;
- Reset(F, RecLength, 0, InputBS);
- (* close the index file, and re-open it as a ReadOnly file, so that all its
- buffer space can be used as a read buffer *)
- CloseIndex(Index);
- Error := NOT OpenIndex(Index, TempFile, Comment, CommentSize, ReadOnly,
- IndexBS);
- IF (Error) THEN
- WriteString(' unable to re-open index -- ');
- WriteString(IndErrorMessage);
- WriteLn;
- END;
- (* now copy the input file in indexed order to the output file *)
- IF (NOT OpenSequentialFile(F2, FN2, NewSequentialFile, OutputBS)) THEN
- WriteString(' unable to create output file -- ');
- WriteString(SIOErrorMessage);
- WriteLn;
- ELSE (* IF NOT OpenSequentialFile *)
- Rec2 := 1;
- IF (FirstRecord(Index, Rec)) THEN
- (* there is at least one record in the input file, and REC has its number *)
- Error := FALSE;
- REPEAT
- IF (NOT ReadRandomFile(F, CurRec^, Rec)) THEN
- WriteString(' error while reading input file -- ');
- WriteString(RIOErrorMessage);
- WriteLn;
- Error := TRUE;
- ELSIF (NOT WriteSequentialFile(F2, CurRec^, LONGCARD(RecLength)))
- THEN
- WriteString(' error while writing output file -- ');
- WriteString(SIOErrorMessage);
- WriteLn;
- Error := TRUE;
- ELSE
- INC(Rec2);
- END; (* if *)
- UNTIL ((Error) OR (NOT NextRecord(Index, Rec)));
- END; (* IF FirstRecord *)
- CloseSequentialFile(F2);
- END; (* if OpenRandomFile *)
- CloseIndex(Index);
- Error := Error OR (NOT DeleteFile(ADR(TempFile)));
- END;
- (* if CreateIndex *)
- CloseRandomFile(F);
- END;
- (* IF NOT OpenRandomFile *)
- FreeMem(CurRec, LONGCARD(RecLength));
- END SortFile2.
-