Transacciones de grafo de objetos con copia en escritura

THotPDF proporciona puntos de guardado anidados para grafos de objetos indirectos cargados o ensamblados sin clonar el documento al inicio de la transacción

Ciclo de vida de las transacciones

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 observadores de mutación pero no crea instantáneas; la primera escritura en una raíz indirecta existente en ese marco crea una instantánea, y las escrituras posteriores en la misma raíz la reutilizan

CommitGraphTransaction conserva el grafo actual y descarta o transfiere las instantáneas sin clonarlo; RollbackGraphTransaction restaura los objetos raíz en su lugar, elimina los objetos añadidos después del punto de guardado y restaura la asignación de números de objeto

Las transacciones anidadas son puntos de guardado independientes; una reversión interna vuelve al estado de entrada interno, mientras que una confirmación interna conserva suficiente historial para una reversión externa posterior

Preparación de escritura automática y explícita

Los cambios de THPDFDictionaryObject.AddValue, ReplaceValue y DeleteValue, de THPDFArrayObject.AddObject y SetIndexedItem, y de THPDFStreamObject.Length notifican automáticamente a la raíz indirecta contenedora

Los campos escalares públicos y los bytes de flujo sin procesar no pueden interceptar la asignación; llame a PrepareLoadedObjectForWrite antes de asignar Value, cambiar los indicadores públicos de objeto, reemplazar punteros de grafo o escribir mediante 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 instantáneas crece con las raíces indirectas modificadas y no con el tamaño total del documento; las cargas útiles de flujo grandes se vuelcan a archivos temporales propios después de GraphTransactionMemoryThreshold, cuyo valor predeterminado es 16 MiB

La reversión intercambia las entradas de diccionario, los elementos de matriz y el almacenamiento de flujo guardados de vuelta a la raíz existente, evitando una segunda copia profunda; el puntero de raíz permanece estable, pero los punteros a descendientes directos deben volver a adquirirse después de la reversión

GetGraphTransactionStatistics devuelve Active, Depth de anidamiento, SnapshotCount, AddedObjectCount, bytes de instantánea residentes y volcados, y bytes máximos de instantánea residentes

THPDFBeforeMutationEvent es la firma de observador de bajo nivel usada para enrutar las mutaciones de contenedor y de ciclo de vida a la instantánea de la raíz indirecta contenedora

Ámbito

Las transacciones cubren el grafo de objetos indirectos, el estado de ciclo de vida, las raíces añadidas y la asignación de números de objeto; los punteros propiedad del llamador, las matrices de ordenación de páginas cargadas, las cachés renderizadas y otro estado lateral de la fachada no se registran en el diario

No elimine, reordene ni reemplace entradas existentes en GetLoadedIndirectObjects mientras haya una transacción activa; use los métodos de contenedor de grafo y vuelva a adquirir los descendientes directos después de la reversión