diff options
Diffstat (limited to 'tools.pas')
-rw-r--r-- | tools.pas | 160 |
1 files changed, 133 insertions, 27 deletions
@@ -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 ******************************************************* |