FOLDABLE_VERBS
FOLDABLE_VERBS = [\Drupal\strata\Journal\Verb::CREATE, \Drupal\strata\Journal\Verb::UPDATE, \Drupal\strata\Journal\Verb::DELETE]
Verbs that describe a change to the contents of a subject, and so can fold.
Reduces a window of journal ops to the net effect on each subject.
One request can touch a node a dozen times: a create, an update per widget, another update from a hook. All twelve ops describe one subject, and a restore only needs the value the subject held at the end of the window. Folding a window before it is flushed keeps a journal proportional to the number of subjects that changed rather than to the number of writes.
The fold runs per JournalOp::key(), over ops in sequence order, and applies one rule per pair:
A survivor keeps the sequence, the microtime and the parentHash of the earliest op in the run it replaces, and the payloadHash, payloadLength, label, actor and requestId of the latest. The sequence keeps ordering against other subjects stable. The parentHash names the state before the window, which is the last version the store received; an intermediate digest names a value that was never written.
Two kinds of op never fold, and are emitted verbatim in sequence order:
collapse(list<\Drupal\strata\Journal\JournalOp> $ops) : list<\Drupal\strata\Journal\JournalOp>
Folds a window down to the net effect on each subject.
| list<\Drupal\strata\Journal\JournalOp> | $ops | The window, in any order; the sequence decides which op is earlier. |
The surviving ops by sequence ascending, never more of them than went in. An op that took part in no fold is the same instance that went in.
statistics(list<\Drupal\strata\Journal\JournalOp> $before, list<\Drupal\strata\Journal\JournalOp> $after) : array{input: int, output: int, dropped: int, ratio: float}
What the fold bought, for the flush log and the operator-facing window view.
| list<\Drupal\strata\Journal\JournalOp> | $before | The window as captured. |
| list<\Drupal\strata\Journal\JournalOp> | $after | The window as collapse() returned it. |
Counts either side of the fold, how many ops disappeared, and input over output as a factor. The ratio is 1.0 when nothing survived, so a caller can print it without a guard.
fold(\Drupal\strata\Journal\JournalOp $earlier, \Drupal\strata\Journal\JournalOp $later) : \Drupal\strata\Journal\JournalOp|null
Merges the op a run has produced so far with the next op on the same subject.
| \Drupal\strata\Journal\JournalOp | $earlier | The survivor of the run so far, which is the first op of the run when there is only one. |
| \Drupal\strata\Journal\JournalOp | $later | The next op on the same key. |
The single op that replaces both, or NULL when the pair cancels out and neither survives.
survivingVerb(\Drupal\strata\Journal\Verb $earlier, \Drupal\strata\Journal\Verb $later) : \Drupal\strata\Journal\Verb|null
The verb the net effect of a pair is described by.
Every pair of foldable verbs has an arm here. The default is unreachable, because collapse() only folds ops isFoldable() accepted, and returning the later verb is the answer that loses the least if a verb is ever added to FOLDABLE_VERBS without an arm.
| \Drupal\strata\Journal\Verb | $earlier | Verb of the survivor of the run so far. |
| \Drupal\strata\Journal\Verb | $later | Verb of the next op on the same key. |
The surviving verb, or NULL when the pair cancels out.
inSequenceOrder(list<\Drupal\strata\Journal\JournalOp> $ops) : list<\Drupal\strata\Journal\JournalOp>
Orders ops the way the journal appended them.
Sorted on sequence, then microtime, and PHP sorts stably, so two ops the journal numbered identically keep the order they arrived in rather than swapping between runs.
| list<\Drupal\strata\Journal\JournalOp> | $ops | The ops, in any order. |
The same ops, by sequence ascending.