Transacciones copy-on-write del grafo de objetos
THotPDF proporciona savepoints anidados para grafos de indirect objects cargados o ensamblados, sin clonar el documento al iniciar la transacción
Ciclo de vida de la transacción
PDF.BeginGraphTransaction('metadata edit');
try
Info.AddStringValue('Producer', 'HotPDF');
PDF.CommitGraphTransaction;
except
PDF.RollbackGraphTransaction;
raise;
end;
BeginGraphTransaction indexa las raíces indirectas actuales e instala observers de mutación, pero no crea snapshots; la primera escritura sobre una raíz indirecta existente en ese frame crea un snapshot, y las escrituras posteriores sobre la misma raíz lo reutilizan
CommitGraphTransaction conserva el grafo actual y descarta o transfiere los snapshots sin clonarlo; RollbackGraphTransaction restaura los objetos raíz in situ, elimina los objetos añadidos después del savepoint y restaura la asignación de números de objeto
El rollback invalida el cache de relaciones de formulario cargado antes de restaurar los objetos, así que las búsquedas de campos posteriores se reconstruyen desde el grafo restaurado en lugar de retener referencias a campos o widgets eliminados
Las transacciones anidadas son savepoints independientes; un rollback interno vuelve al estado de entrada interno, mientras que un commit interno conserva historial suficiente para un rollback externo posterior
Preparación automática y explícita de escrituras
THPDFDictionaryObject.AddValue, ReplaceValue y DeleteValue, THPDFArrayObject.AddObject y SetIndexedItem, y los cambios de THPDFStreamObject.Length notifican automáticamente a la raíz indirecta que los envuelve
Los campos escalares públicos y los bytes crudos del stream no pueden interceptar la asignación; llame a PrepareLoadedObjectForWrite antes de asignar Value, cambiar flags públicos del objeto, reemplazar punteros del grafo o escribir a través de 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;
Memoria y rendimiento
La memoria de snapshots crece con las raíces indirectas tocadas, no con el tamaño total del documento; los payloads grandes de stream se derraman a archivos temporales propios después de GraphTransactionMemoryThreshold, cuyo valor por defecto es 16 MiB
El rollback intercambia de vuelta las entradas de diccionario, los elementos de array y el almacenamiento de stream guardados dentro de la raíz existente, evitando una segunda copia profunda; el puntero de la raíz permanece estable, pero los punteros a descendientes directos deben readquirirse después del rollback
GetGraphTransactionStatistics devuelve Active, la Depth de anidamiento, SnapshotCount, AddedObjectCount, los bytes residentes y derramados de snapshots, y el pico de bytes residentes de snapshots
THPDFBeforeMutationEvent es la firma de observer de bajo nivel usada para enrutar las mutaciones de contenedores y de ciclo de vida hacia el snapshot de la raíz indirecta que envuelve
Alcance
Las transacciones cubren el grafo de indirect objects, el estado de ciclo de vida, las raíces añadidas y la asignación de números de objeto; los punteros propiedad del caller, los arrays de orden de páginas cargadas, las cachés renderizadas y demás estado lateral del facade no se journalean
No elimine, reordene ni reemplace entradas existentes en GetLoadedIndirectObjects mientras haya una transacción activa; use los métodos de contenedor del grafo y readquiera los descendientes directos después del rollback