Copy-on-Write-Transaktionen für Objektgraphen

THotPDF bietet verschachtelte Sicherungspunkte für geladene oder zusammengesetzte Graphen indirekter Objekte, ohne das Dokument beim Start einer Transaktion zu klonen

Transaktionslebenszyklus

PDF.BeginGraphTransaction('metadata edit');
try
  Info.AddStringValue('Producer', 'HotPDF');
  PDF.CommitGraphTransaction;
except
  PDF.RollbackGraphTransaction;
  raise;
end;

BeginGraphTransaction indiziert die aktuellen indirekten Wurzeln und installiert Änderungsbeobachter, erzeugt aber keine Schnappschüsse; der erste Schreibzugriff auf eine vorhandene indirekte Wurzel in diesem Frame erzeugt einen Schnappschuss, weitere Zugriffe auf dieselbe Wurzel verwenden ihn erneut

CommitGraphTransaction behält den aktuellen Graphen und verwirft oder überträgt Schnappschüsse ohne ihn zu klonen; RollbackGraphTransaction stellt Wurzelobjekte an Ort und Stelle wieder her, entfernt nach dem Sicherungspunkt angehängte Objekte und stellt die Vergabe von Objektnummern wieder her

Verschachtelte Transaktionen sind unabhängige Sicherungspunkte; ein innerer Rollback kehrt zum Zustand beim Eintritt in die innere Transaktion zurück, während ein innerer Commit genug Verlauf für einen späteren äußeren Rollback bewahrt

Automatische und explizite Schreibvorbereitung

THPDFDictionaryObject.AddValue, ReplaceValue und DeleteValue, THPDFArrayObject.AddObject und SetIndexedItem sowie Änderungen an THPDFStreamObject.Length benachrichtigen die umschließende indirekte Wurzel automatisch

Öffentliche Skalarfelder und rohe Streambytes können Zuweisungen nicht abfangen; rufen Sie PrepareLoadedObjectForWrite vor einer Zuweisung an Value, einer Änderung öffentlicher Objektflags, dem Ersetzen von Graphzeigern oder dem Schreiben über THPDFStreamObject.Stream auf

PDF.BeginGraphTransaction('raw stream edit');
try
  PDF.PrepareLoadedObjectForWrite(StreamObject);
  StreamObject.Stream.Size:= 0;
  StreamObject.Stream.WriteBuffer(Bytes[0], Length(Bytes));
  StreamObject.Length:= Length(Bytes);
  PDF.CommitGraphTransaction;
except
  PDF.RollbackGraphTransaction;
  raise;
end;

Speicher und Leistung

Der Schnappschussspeicher wächst mit den berührten indirekten Wurzeln statt mit der gesamten Dokumentgröße; große Stream-Nutzlasten werden nach GraphTransactionMemoryThreshold, dessen Standard 16 MiB beträgt, in eigene temporäre Dateien ausgelagert

Rollback tauscht gespeicherte Dictionary-Einträge, Arrayelemente und Streamspeicher zurück in die vorhandene Wurzel und vermeidet damit eine zweite tiefe Kopie; der Wurzelzeiger bleibt stabil, Zeiger auf direkte Nachfahren müssen nach einem Rollback jedoch erneut beschafft werden

GetGraphTransactionStatistics liefert Active, die Verschachtelungs-Depth, SnapshotCount, AddedObjectCount, residente und ausgelagerte Schnappschussbytes sowie Spitzenwerte für residente Schnappschussbytes

THPDFBeforeMutationEvent ist die Signatur des Beobachters auf niedriger Ebene, die Container- und Lebenszyklusänderungen an den Schnappschuss der umschließenden indirekten Wurzel weiterleitet

Umfang

Transaktionen decken den Graphen indirekter Objekte, Lebenszyklusstatus, angehängte Wurzeln und die Vergabe von Objektnummern ab; aufrufereigene Zeiger, Reihenfolgen geladener Seiten, gerenderte Caches und anderer Fassadenzustand werden nicht protokolliert

Entfernen, ordnen oder ersetzen Sie bestehende Einträge in GetLoadedIndirectObjects nicht, solange eine Transaktion aktiv ist; verwenden Sie Graphcontainer-Methoden und beschaffen Sie direkte Nachfahren nach dem Rollback erneut