36 private $activeUpdate;
40 private $queueByStage;
47 private function __construct(
52 $this->activeStage = $activeStage;
53 $this->activeUpdate = $update;
54 $this->parentScope = $parentScope;
55 $this->queueByStage = array_fill_keys( DeferredUpdates::STAGES, [] );
62 return new self(
null,
null, null );
76 return new self( $activeStage, $update, $parentScope );
85 return $this->activeUpdate;
96 $stageEffective = max( $stage, $this->activeStage );
98 $queue =& $this->queueByStage[$stageEffective];
101 $class = get_class( $update );
102 if ( isset( $queue[$class] ) ) {
104 $existingUpdate = $queue[$class];
105 '@phan-var MergeableUpdate $existingUpdate';
106 $existingUpdate->merge( $update );
109 unset( $queue[$class] );
110 $queue[$class] = $existingUpdate;
112 $queue[$class] = $update;
125 return array_sum( array_map(
'count', $this->queueByStage ) );
135 $matchingQueues = [];
136 foreach ( $this->queueByStage as $queueStage => $queue ) {
137 if ( $stage === DeferredUpdates::ALL || $stage === $queueStage ) {
138 $matchingQueues[] = $queue;
142 return array_merge( ...$matchingQueues );
149 $this->queueByStage = array_fill_keys( array_keys( $this->queueByStage ), [] );
161 if ( $stage === DeferredUpdates::ALL ) {
163 $activeStage = DeferredUpdates::STAGES[count( DeferredUpdates::STAGES ) - 1];
166 $activeStage = max( $stage, $this->activeStage );
170 $processed = $this->upmergeUnreadyUpdates( $activeStage );
171 foreach ( range( DeferredUpdates::STAGES[0], $activeStage ) as $queueStage ) {
172 $processed += $this->processStageQueue( $queueStage, $activeStage, $callback );
174 }
while ( $processed > 0 );
187 private function upmergeUnreadyUpdates( $activeStage ) {
190 if ( !$this->parentScope ) {
194 foreach ( $this->queueByStage as $queueStage => $queue ) {
195 foreach ( $queue as $k => $update ) {
196 if ( $update instanceof MergeableUpdate || $queueStage > $activeStage ) {
197 unset( $this->queueByStage[$queueStage][$k] );
198 $this->parentScope->addUpdate( $update, $queueStage );
213 private function processStageQueue( $stage, $activeStage, callable $callback ) {
217 $claimedUpdates = $this->queueByStage[$stage];
218 $this->queueByStage[$stage] = [];
221 while ( $claimedUpdates ) {
227 $claimedDataUpdates = [];
228 $claimedGenericUpdates = [];
229 foreach ( $claimedUpdates as $claimedUpdate ) {
230 if ( $claimedUpdate instanceof DataUpdate ) {
231 $claimedDataUpdates[] = $claimedUpdate;
233 $claimedGenericUpdates[] = $claimedUpdate;
239 foreach ( $claimedDataUpdates as $claimedDataUpdate ) {
240 $callback( $claimedDataUpdate, $activeStage );
242 foreach ( $claimedGenericUpdates as $claimedGenericUpdate ) {
243 $callback( $claimedGenericUpdate, $activeStage );
247 $claimedUpdates = $this->queueByStage[$stage];
248 $this->queueByStage[$stage] = [];