summaryrefslogtreecommitdiff
path: root/tools.pas
diff options
context:
space:
mode:
Diffstat (limited to 'tools.pas')
-rw-r--r--tools.pas160
1 files changed, 133 insertions, 27 deletions
diff --git a/tools.pas b/tools.pas
index c7b3082..13e5a88 100644
--- a/tools.pas
+++ b/tools.pas
@@ -5,7 +5,7 @@ unit tools;
interface
uses
- classes, sysUtils, process, mystringlistunit, regExpr;
+ classes, sysUtils, process, mystringlistunit, regExpr, lowlevelunit;
type
tAktualitaet = (aNichtVorhanden,aVeraltet,aAktuell,aWirdErneuert);
@@ -25,14 +25,22 @@ type
constructor create(nam: ansiString; ak: tAktualitaet);
end;
tDateienMitDaten = class(tFPList)
+ private
+ sortiert: tLongintArray;
istSortiert: boolean;
+ procedure sortiereNachNamen; inline;
+ procedure quickSort(li,re,ungeradheit: longint);
function rItem(idx: longint): tDateiMitDatum; inline;
procedure wItem(idx: longint; neu: tDateiMitDatum); inline;
+ function rSItem(idx: longint): tDateiMitDatum; inline;
public
property items[idx: longint]: tDateiMitDatum
read rItem
write wItem; default;
+ property sItems[idx: longint]: tDateiMitDatum
+ read rSItem;
constructor create;
+ destructor destroy; override;
procedure mrProper;
function add(neu: tDateiMitDatum): longint;
function gleicheNamenWie(dmd: tDateienMitDaten): boolean;
@@ -41,7 +49,9 @@ type
function toMyStringList: tMyStringList;
function finde(name: string; wirdAktualitaet: tAktualitaet = aNichtVorhanden): tDateiMitDatum; overload; inline;
function finde(name: string; out istNeu: boolean; wirdAktualitaet: tAktualitaet = aNichtVorhanden): tDateiMitDatum; overload; inline;
- procedure sortiereNachNamen;
+ function findeIndex(name: string): longint; inline;
+ procedure matchAll(regEx: string; out indizes: tLongintArray; istRegex: boolean);
+ procedure delete(idx: longint);
end;
function min(a1,a2: tAktualitaet): tAktualitaet; inline; overload;
@@ -66,7 +76,7 @@ function dateienMitGueltigerSumme(sumNam: string): tMyStringList;
implementation
uses
- lowlevelunit, math;
+ math;
// tDateiMitDatum **************************************************************
@@ -82,9 +92,65 @@ end;
constructor tDateienMitDaten.create;
begin
inherited create;
+ setLength(sortiert,0);
istSortiert:=true;
end;
+destructor tDateienMitDaten.destroy;
+begin
+ setLength(sortiert,0);
+ inherited destroy;
+end;
+
+procedure tDateienMitDaten.sortiereNachNamen;
+var
+ i: longint;
+begin
+ if istSortiert then
+ exit;
+ setLength(sortiert,count);
+ for i:=0 to length(sortiert)-1 do
+ sortiert[i]:=i;
+ quickSort(0,count-1,0);
+ istSortiert:=true;
+end;
+
+procedure tDateienMitDaten.quickSort(li,re,ungeradheit: longint);
+var
+ pivot: string;
+ l,r,tmp: longint;
+begin
+ if li>=re then
+ exit;
+ r:=0;
+ for l:=li+1 to re do
+ if items[sortiert[l]].name<>items[sortiert[li]].name then begin
+ r:=1;
+ break;
+ end;
+ if r=0 then // nur gleiche Namen
+ exit;
+ pivot:=items[sortiert[(li+re) div 2]].name;
+ l:=li;
+ r:=re;
+ while l<=r do begin
+ while (l<length(sortiert)) and (vergleicheStrings(items[sortiert[l]].name,pivot)<ungeradheit) do
+ inc(l);
+ while (r>=0) and (vergleicheStrings(items[sortiert[r]].name,pivot)>ungeradheit-1) do
+ dec(r);
+ if l<r then begin
+ tmp:=sortiert[l];
+ sortiert[l]:=sortiert[r];
+ sortiert[r]:=tmp;
+ inc(l);
+ dec(r);
+ end;
+ end;
+ assert(l=r+1,'Fehler in Quicksort: '+intToStr(l)+'<>'+intToStr(r)+'+1!');
+ quickSort(li,r,1-ungeradheit);
+ quickSort(l,re,1-ungeradheit);
+end;
+
function tDateienMitDaten.rItem(idx: longint): tDateiMitDatum;
begin
result:=tDateiMitDatum(get(idx));
@@ -92,10 +158,17 @@ end;
procedure tDateienMitDaten.wItem(idx: longint; neu: tDateiMitDatum);
begin
+ assert(neu.name<>'','wItem: Dateiname darf nicht leer sein!');
put(idx,neu);
istSortiert:=false;
end;
+function tDateienMitDaten.rSItem(idx: longint): tDateiMitDatum; inline;
+begin
+ sortiereNachNamen;
+ result:=items[sortiert[idx]];
+end;
+
procedure tDateienMitDaten.mrProper;
var
i: longint;
@@ -103,12 +176,14 @@ begin
for i:=0 to count-1 do
items[i].free;
clear;
+ setLength(sortiert,0);
+ istSortiert:=true;
end;
function tDateienMitDaten.add(neu: tDateiMitDatum): longint;
begin
+ assert(neu.name<>'','add: Dateiname darf nicht leer sein!');
result:=inherited add(neu);
- assert(neu.name<>'','Dateiname darf nicht leer sein!');
istSortiert:=false;
end;
@@ -119,11 +194,9 @@ begin
result:=count=dmd.count;
if not result then
exit;
- sortiereNachNamen;
- dmd.sortiereNachNamen;
result:=false;
for i:=0 to count-1 do
- if items[i].name <> dmd[i].name then
+ if sItems[i].name <> dmd.sItems[i].name then
exit;
result:=true;
end;
@@ -139,15 +212,15 @@ end;
procedure tDateienMitDaten.append(dmd: tDateienMitDaten);
var
- i,j: longint;
- found: boolean;
+ i,j: longint;
begin
+ j:=0;
for i:=0 to dmd.count-1 do begin
- found:=false;
- for j:=0 to count-1 do
- found:=found or (items[j].name = dmd[i].name);
- if not found then
- add(dmd[i]);
+ while (j<length(sortiert)) and (vergleicheStrings(dmd.sItems[i].name,sItems[j].name)<0) do
+ inc(j);
+ if (j<length(sortiert)) and (vergleicheStrings(dmd.sItems[i].name,sItems[j].name)=0) then
+ continue;
+ add(dmd[i]);
end;
end;
@@ -169,15 +242,29 @@ end;
function tDateienMitDaten.finde(name: string; out istNeu: boolean; wirdAktualitaet: tAktualitaet = aNichtVorhanden): tDateiMitDatum;
var
+ i: longint;
+begin
+ i:=findeIndex(name);
+ if (i>=0) and (i<count) and (sItems[i].name = name) then begin
+ result:=sItems[i];
+ istNeu:=false;
+ exit;
+ end;
+ add(tDateiMitDatum.create(name,wirdAktualitaet));
+ istNeu:=true;
+ result:=tDateiMitDatum(last);
+end;
+
+function tDateienMitDaten.findeIndex(name: string): longint;
+var
li,re,i: longint;
begin
sortiereNachNamen;
- istNeu:=false;
li:=0;
re:=count-1;
while li<=re do begin
i:=(li+re) div 2;
- case vergleicheStrings(items[i].name,name) of
+ case vergleicheStrings(sItems[i].name,name) of
-1: li:=i+1;
1: re:=i-1;
0: begin
@@ -188,23 +275,42 @@ begin
end{of case};
end;
if li=re then begin
- assert(items[li].name=name,'Fehler in Bisektion: '''+items[li].name+'''<>'''+name+'''!');
- result:=items[li];
+ assert(sItems[li].name=name,'Fehler in Bisektion: '''+sItems[li].name+'''<>'''+name+'''!');
+ result:=li;
exit;
end;
assert(li=re+1,'Fehler in Bisektion: '+intToStr(li)+'<>'+intToStr(re)+'+1!');
- insert(li,tDateiMitDatum.create);
- istNeu:=true;
- result:=last;
- last.name:=name;
- last.aktuell:=wirdAktualitaet;
+ result:=li;
end;
-procedure tDateienMitDaten.sortiereNachNamen;
+procedure tDateienMitDaten.matchAll(regEx: string; out indizes: tLongintArray; istRegex: boolean);
+var
+ re: tRegExpr;
+ i: longint;
begin
- if not istSortiert then
- sort(@vergleicheNamenVonDateienMitDaten);
- istSortiert:=true;
+ setLength(indizes,0);
+ if istRegex then begin
+ re:=tRegExpr.create;
+ re.expression:=regEx;
+ for i:=0 to count-1 do
+ if re.exec(items[i].name) then begin
+ setLength(indizes,length(indizes)+1);
+ indizes[length(indizes)-1]:=i;
+ end;
+ end
+ else begin
+ i:=findeIndex(regEx);
+ if (i>=0) and (i<count) and (sItems[i].name=regEx) then begin
+ setLength(indizes,1);
+ indizes[0]:=longint(sortiert[i]);
+ end;
+ end;
+end;
+
+procedure tDateienMitDaten.delete(idx: longint);
+begin
+ inherited delete(idx);
+ istSortiert:=false;
end;
// allgemeine Funktionen *******************************************************