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 >
Wrap
Text File
|
1989-10-09
|
6KB
|
173 lines
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.