home *** CD-ROM | disk | FTP | other *** search
- (******************************************************************************
- * combSort *
- * a combined sort is a mergsort that uses an internal quicksort in the *
- * splitFile phase to create long telems. *
- ******************************************************************************)
- unit combSort;
-
- {$R-}
-
- interface
-
- uses
- mergSort
- ,quickSrt
- ;
-
- type
- combinedSortPtr = ^ combinedSort;
- combinedSort = object(mergeSort)
- qs : quickSortPtr;
- ap : arrayOfPointersPtr;
-
- constructor init( fn : string; { file name }
- bs : word; { block size }
- tp : string; { temp path }
- on : string; { outfile name }
- q : quickSortPtr { how to do the internal sort }
- );
- function splitFile : longInt; virtual;
-
- end; { combinedSort object definition }
-
- implementation
-
- (******************************************************************************
- * combinedSort.init *
- ******************************************************************************)
- constructor combinedSort.init;
- begin
- mergeSort.init(fn, bs, tp, on);
- qs := q;
- end; {combinedSort.init}
-
- (******************************************************************************
- * combinedSort.splitFile *
- ******************************************************************************)
- function combinedSort.splitFile;
- var
- initialSize : longInt;
- { maximum number of sort records that can be performed by an internal sort }
- recordsToSort : longInt;
- { number of records to sort in a specific phase of the internal sort }
- reachedEOF : boolean;
- writeTo1 : boolean; { trigger, when true write to t1, else write to t2 }
- i : longint; { used to count total number of records in file }
- j : longint;
- begin
- writeTo1 := true;
- i := 0;
- reachedEOF := false;
- assign(t1, tempPath + 'mrgsrtt1.$$$');
- rewrite(t1, blokSize);
- if (ioResult <> 0) then
- reachedEOF := true;
- assign(t2, tempPath + 'mrgsrtt2.$$$');
- rewrite(t2, blokSize);
- if (ioResult <> 0) then
- reachedEOF := true;
- initialSize := maxAvail div (blokSize + sizeOf(pointer)) - 1;
- { one used internally by quicksort .. }
- getMem(ap, initialSize * sizeOf(pointer));
- { ap points to start of the array of pointers to block data }
- while (not reachedEOF) do begin
- recordsToSort := 0; { number of records to pass for internal sort .. }
- while ((recordsToSort < initialSize) and (not eof(mergFile))) do begin
- inc(recordsToSort);
- getMem(block1, blokSize);
- blockRead(mergFile, block1^, 1);
- ap^[recordsToSort] := block1;
- end; { read more blocks to be sorted in this phase }
- if (eof(mergFile)) then
- reachedEOF := true;
- if (recordsToSort <> 0) then begin
- qs^.numberOfElements := recordsToSort;
- qs^.ptrArray := ap; { set parameters for this phase of the internal sort }
- qs^.doYourJob;
- for j := 1 to recordsToSort do begin
- if (writeTo1) then
- blockWrite(t1, ap^[j]^, 1)
- else
- blockWrite(t2, ap^[j]^, 1);
- freemem(ap^[j], blokSize);
- end; { writing the telem to the file }
- writeTo1 := not writeTo1;
- i := i + recordsToSort;
- end; { there were records to sort .. }
- end; { while .. for read }
- freemem(ap, initialSize * sizeof(pointer));
- splitFile := i; { we return the number of records in the file .. }
- close(mergFile);
- close(t1);
- close(t2);
- telem := initialSize; { this is the catch, here we have an initial size .. }
- end; {combinedSort.splitFile}
-
- (******************************************************************************
- * MAIN *
- ******************************************************************************)
- end.