22 private $activeUpdate;
26 private $queueByStage;
33 private function __construct(
38 $this->activeStage = $activeStage;
39 $this->activeUpdate = $update;
40 $this->parentScope = $parentScope;
41 $this->queueByStage = array_fill_keys( DeferredUpdates::STAGES, [] );
48 return new self(
null,
null, null );
62 return new self( $activeStage, $update, $parentScope );
71 return $this->activeUpdate;
82 $stageEffective = max( $stage, $this->activeStage );
84 $queue =& $this->queueByStage[$stageEffective];
87 $class = get_class( $update );
88 if ( isset( $queue[$class] ) ) {
90 $existingUpdate = $queue[$class];
91 '@phan-var MergeableUpdate $existingUpdate';
92 $existingUpdate->merge( $update );
95 unset( $queue[$class] );
96 $queue[$class] = $existingUpdate;
98 $queue[$class] = $update;
111 return array_sum( array_map(
'count', $this->queueByStage ) );
121 $matchingQueues = [];
122 foreach ( $this->queueByStage as $queueStage => $queue ) {
123 if ( $stage === DeferredUpdates::ALL || $stage === $queueStage ) {
124 $matchingQueues[] = $queue;
128 return array_merge( ...$matchingQueues );
135 $this->queueByStage = array_fill_keys( array_keys( $this->queueByStage ), [] );
147 if ( $stage === DeferredUpdates::ALL ) {
149 $activeStage = DeferredUpdates::STAGES[count( DeferredUpdates::STAGES ) - 1];
152 $activeStage = max( $stage, $this->activeStage );
156 $processed = $this->upmergeUnreadyUpdates( $activeStage );
157 foreach ( range( DeferredUpdates::STAGES[0], $activeStage ) as $queueStage ) {
158 $processed += $this->processStageQueue( $queueStage, $activeStage, $callback );
160 }
while ( $processed > 0 );
173 private function upmergeUnreadyUpdates( $activeStage ) {
176 if ( !$this->parentScope ) {
180 foreach ( $this->queueByStage as $queueStage => $queue ) {
181 foreach ( $queue as $k => $update ) {
182 if ( $update instanceof MergeableUpdate || $queueStage > $activeStage ) {
183 unset( $this->queueByStage[$queueStage][$k] );
184 $this->parentScope->addUpdate( $update, $queueStage );
199 private function processStageQueue( $stage, $activeStage, callable $callback ) {
203 $claimedUpdates = $this->queueByStage[$stage];
204 $this->queueByStage[$stage] = [];
207 while ( $claimedUpdates ) {
213 $claimedDataUpdates = [];
214 $claimedGenericUpdates = [];
215 foreach ( $claimedUpdates as $claimedUpdate ) {
216 if ( $claimedUpdate instanceof DataUpdate ) {
217 $claimedDataUpdates[] = $claimedUpdate;
219 $claimedGenericUpdates[] = $claimedUpdate;
225 foreach ( $claimedDataUpdates as $claimedDataUpdate ) {
226 $callback( $claimedDataUpdate, $activeStage );
228 foreach ( $claimedGenericUpdates as $claimedGenericUpdate ) {
229 $callback( $claimedGenericUpdate, $activeStage );
233 $claimedUpdates = $this->queueByStage[$stage];
234 $this->queueByStage[$stage] = [];