Copy-on-Write транзакции върху обектния граф

THotPDF дава вложени savepoint-и за заредени или сглобени indirect-object графове, без да клонира документа при старта на транзакцията

Жизнен цикъл на транзакцията

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

BeginGraphTransaction индексира текущите indirect корени и инсталира наблюдатели за мутации, но не създава snapshots; първият запис към съществуващ indirect корен в тази рамка създава един snapshot, а следващите записи към същия корен го преизползват

CommitGraphTransaction запазва текущия граф и изхвърля или прехвърля snapshots, без да го клонира; RollbackGraphTransaction възстановява root обектите на място, премахва обектите, добавени след savepoint-а, и възстановява разпределението на объектни номера

Вложените транзакции са независими savepoint-и; вътрешен rollback се връща към вътрешното входно състояние, а вътрешен commit пази достатъчно история за по-късен външен rollback

Автоматична и изрична подготовка за запис

Промени в THPDFDictionaryObject.AddValue, ReplaceValue и DeleteValue, THPDFArrayObject.AddObject и SetIndexedItem и THPDFStreamObject.Length уведомяват автоматично обхващащия indirect корен

Публичните скаларни полета и суровите stream байтове не могат да прихванат присвояване; викайте PrepareLoadedObjectForWrite преди да зададете Value, да смените публични обектни флагове, да замените указатели в графа или да пишете през 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;

Памет и производителност

Паметта за snapshots расте с докоснатите indirect корени, а не с общия размер на документа; големи stream payload-и се изливат в собствени временни файлове след GraphTransactionMemoryThreshold, чийто default е 16 MiB

Rollback-ът връща запазените dictionary записи, елементи на масиви и stream хранилища обратно в съществуващия корен, без второ дълбоко копиране; указателят към корена остава стабилен, но указателите към преки наследници трябва да се вземат наново след rollback

GetGraphTransactionStatistics връща Active, вложаща дълбочина Depth, SnapshotCount, AddedObjectCount, resident и изляти snapshot байтове и пик на резидентните snapshot байтове

THPDFBeforeMutationEvent е low-level observer сигнатурата, използвана да насочва мутации на контейнери и жизнен цикъл към snapshot-а на обхващащия indirect корен

Обхват

Транзакциите обхващат indirect-object графа, състоянието на жизнения цикъл, добавените корени и разпределението на объектни номера; указателите, притежавани от извикващия, масивите за подредба на заредени страници, рендерираните кешове и друго фасадно странично състояние не се журналират

Не премахвайте, пренареждайте и не заменяйте съществуващи записи в GetLoadedIndirectObjects, докато транзакция е активна; използвайте методите на graph контейнерите и си вземете преките наследници наново след rollback