Hi,
ich hab mir ein Tool für ein inkrementelles Backup von mehreren Verzeichnissen geschrieben.
In der Testumgebung mit ca. 5000 Files funktioniert das auch wunderbar und sogar sehr performant. Leider ist dies im realen Einsatz, bei dem ca. 75.000 Dateien gesichert werden müssen, nicht mehr der Fall. Es gibt erhebliche Performanceprobleme beim Ausführen.
Das Ganze ist wie folgt implementiert:
Da es sich um ein inkrementelles Backup handelt, muss ich alle gesicherten Dateien mit den entsprechenden Dateien auf der Festplatte abgleichen. Dazu hab ich mir eine pseudo-Hash-Funktion geschrieben, die eben viel schneller ist als MD5 oder ähnliches. Dafür nicht unbedingt eindeutig, aber für meine Zwecke vollkommen ausreichend.
Bei einem Backup gehe ich nun wie folgt vor:
1. Laden der Liste von gesicherten Dateien mit den alten Hashwerten
2. Vergleichen aller dieser Dateien mit den aktuell auf der Festplatte vorhandenen Dateien
3. Daraus eine Liste mit Dateien erstellen, die kopiert werden müssen. Dazu gehören: Neue Dateien und geänderte Dateien
4. Auf der Festplatte nicht mehr vorhandene Dateien markieren
Um die Performance zu erhöhen setze ich auf HashMaps. Diese kommen aus der DCL. Die Zuordnung ist dabei: <Dateiname, Hash>
Die konkrete Implementierung für diese Schritte ist:
Delphi-Quellcode:
procedure TForm1.DoBackUp();
var
fileListLastState: IStrStrMap;
fileListCurrState: IStrStrMap;
begin
// ..
// Updated und Added Files finden
iter := fileListCurrState.KeySet.First; // Hier gibt's ein Performanceproblem
while iter.HasNext do
begin
key := iter.Next;
if fileListLastState.ContainsKey(key) then
begin
if not (fileListLastState.GetValue(key)=getHash(key)) then
begin
UpdatedFiles.PutValue(key, getHash(key));
end;
end
else
begin
AddedFiles.PutValue(key, getHash(key));
end;
end;
// Deleted Files finden
iter := fileListLastState.KeySet.First; // Hier gibt's ein Performanceproblem
while iter.HasNext do
begin
key := iter.Next;
if not fileListCurrState.ContainsKey(key) then
begin
DeletedFiles.PutValue(key, '-');
end;
end;
Danach werden dann die Dateien kopiert.
Das konkrete Problem ist jetzt, wenn die fileListCurrState (Dateien auf der Festplatte) und auch die fileListLastState (Dateien vom letzten Backup) z.B. 75.000 Einträge enthalten. Dann benötigt alleine das Holen eines Iterators für eine Map eine Ewigkeit.
Wie kann ich das Ganze aus performancetechnischer Sicht verbessern? Oder komplett anders aufbauen?
Vielen Dank schon für's Lesen
Pascal