{<--- Holt eine Textzeile aus der Quell-Datei --->}
function TTextFileSorter.LineFromFile(Row : Integer): AnsiString;
var
CharStr : PAnsiChar;
index : TLineIndex;
begin
index := FFileIndex[Row];
CharStr := StrAlloc(
Index.size +1);
FillChar(CharStr^,
Index.size +1, #0);
FInFileStream.Seek(
Index.offset, soFromBeginning);
FInFileStream.
Read(CharStr^,
Index.size);
Result := CharStr;
StrDispose(CharStr);
end;
{<--- Holt eine Textzeile via Index-Werte --->}
function TTextFileSorter.GetIndexLine(Row: Integer; LineTyp: TGetLineTyp): AnsiString;
begin
case LineTyp
of
glt_File : Result := LineFromFile(Row);
glt_FileUpper : Result := AnsiUpperCase(LineFromFile(Row));
glt_Prefetch : Result := FFileIndex[Row].prefetch;
end;
end;
{<--- Vergleicht Strings genau, also bei Bedarf nachladen --->}
function TTextFileSorter.CompareLinesExact(Row1, Row2 : Integer) : Integer;
begin
Result := CompareStr(GetIndexLine(Row1, glt_Prefetch),GetIndexLine(Row2, glt_Prefetch));
// Prefetch gleich, dann aus Quell-Datei vergleichen
if Result = 0
then
Result := CompareStr(GetIndexLine(Row1, glt_FileUpper),GetIndexLine(Row2, glt_FileUpper));
end;
{<--- Quicksort des Index mit Nachladen einer Zeile bei Bedarf --->}
procedure TTextFileSorter.SortIndex(LoIndex, HiIndex: Integer);
var
LoIdx, HiIdx, PivotIdx: Integer;
Swap : TLineIndex;
Promille : Integer;
begin
if FCancelSort
then Exit;
// Lokalen Indexbereich bilden
LoIdx := LoIndex;
HiIdx := HiIndex;
PivotIdx := (LoIndex + HiIndex)
div 2;
repeat
while CompareLinesExact(LoIdx, PivotIdx) < 0
do Inc(LoIdx);
while CompareLinesExact(PivotIdx, HiIdx) < 0
do Dec(HiIdx);
//while GetLine(LoIdx, LineTyp) < Pivot do Inc(LoIdx);
//while Pivot < GetLine(HiIdx, LineTyp) do Dec(HiIdx);
if LoIdx <= HiIdx
then begin
if LoIdx < HiIdx
then begin
Swap := FFileIndex[LoIdx];
FFileIndex[LoIdx] := FFileIndex[HiIdx];
FFileIndex[HiIdx] := Swap;
end;
Inc(LoIdx);
Dec(HiIdx);
end;
until LoIdx > HiIdx;
// NotifyEvent nur alle 0,1% aufrufen
if Assigned(FOnSorting)
then begin
Promille := (LoIndex * 1000)
div Length(FFileIndex);
if Promille > FLastPromille
then begin
FLastPromille := Promille;
FOnSorting(self, tfsSorting , Promille
div 10, FCancelSort);
end;
end;
if LoIndex < HiIdx
then SortIndex(LoIndex, HiIdx);
if LoIdx < HiIndex
then SortIndex(LoIdx, HiIndex);
end;