Transactions de graphe d’objets à copie sur écriture
THotPDF fournit des points de sauvegarde imbriqués pour les graphes d’objets indirects chargés ou assemblés, sans cloner le document au début de la transaction
Cycle de vie d’une transaction
PDF.BeginGraphTransaction('metadata edit');
try
Info.AddStringValue('Producer', 'HotPDF');
PDF.CommitGraphTransaction;
except
PDF.RollbackGraphTransaction;
raise;
end;
BeginGraphTransaction indexe les racines indirectes actuelles et installe des observateurs de mutation, sans créer d’instantané ; la première écriture dans une racine indirecte existante de ce cadre crée un instantané, réutilisé par les écritures suivantes dans cette même racine
CommitGraphTransaction conserve le graphe courant et abandonne ou transfère les instantanés sans le cloner ; RollbackGraphTransaction restaure les objets racine sur place, supprime les objets ajoutés après le point de sauvegarde et restaure l’allocation des numéros d’objet
Les transactions imbriquées sont des points de sauvegarde indépendants ; une annulation interne revient à l’état d’entrée interne, tandis qu’une validation interne conserve assez d’historique pour une annulation externe ultérieure
Préparation automatique et explicite des écritures
THPDFDictionaryObject.AddValue, ReplaceValue et DeleteValue, THPDFArrayObject.AddObject et SetIndexedItem, ainsi que les modifications de THPDFStreamObject.Length notifient automatiquement la racine indirecte englobante
Les champs scalaires publics et les octets bruts de flux ne peuvent pas intercepter une affectation ; appelez PrepareLoadedObjectForWrite avant d’affecter Value, de modifier des indicateurs d’objet publics, de remplacer des pointeurs de graphe ou d’écrire via THPDFStreamObject.Stream
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;
Mémoire et performances
La mémoire des instantanés augmente avec les racines indirectes touchées plutôt qu’avec la taille totale du document ; les grandes charges de flux basculent vers des fichiers temporaires détenus après GraphTransactionMemoryThreshold, fixé par défaut à 16 Mio
L’annulation rétablit les entrées de dictionnaire, éléments de tableau et stockages de flux enregistrés dans la racine existante, évitant une seconde copie profonde ; le pointeur de racine reste stable, mais les pointeurs vers les descendants directs doivent être redemandés après l’annulation
GetGraphTransactionStatistics renvoie Active, la profondeur d’imbrication Depth, SnapshotCount, AddedObjectCount, les octets d’instantanés en mémoire et déversés, ainsi que le pic des octets en mémoire
THPDFBeforeMutationEvent est la signature d’observateur de bas niveau qui achemine les mutations de conteneur et de cycle de vie vers l’instantané de la racine indirecte englobante
Périmètre
Les transactions couvrent le graphe d’objets indirects, l’état du cycle de vie, les racines ajoutées et l’allocation des numéros d’objet ; les pointeurs appartenant à l’appelant, tableaux d’ordre des pages chargées, caches de rendu et autres états de façade ne sont pas journalisés
Ne supprimez, ne réordonnez ni ne remplacez les entrées existantes de GetLoadedIndirectObjects pendant qu’une transaction est active ; utilisez les méthodes de conteneur du graphe et redemandez les descendants directs après une annulation