mediawiki-extensions-Echo/includes/iterator/MultipleIterator.php
Erik Bernhardson 1667e25854 Use batch queries for users-watching-title
The new locateUsersWatchingTitle implementation could end up returning
thousands of users, currently on enwiki there are 25 titles with more
than 10k subscribed users and aprox 550 titles with more than 1k subscribed
users.

This switches the user collection to an iterator based implementation so that
we no longer need to have the entire users list at any one time.

Change-Id: I3d3fa9328f348bb48682d3658622952ce82d3925
2014-08-15 10:44:55 -07:00

68 lines
1.5 KiB
PHP

<?php
/**
* Presents a list of iterators as a single stream of results
* when wrapped with the RecursiveIteratorIterator.
*
* This differs from the SPL MultipleIterator in the following ways:
* * Does not return null for non-valid child iterators
* * implements RecursiveIterator
* * Lots less features(e.g. simple!)
*/
class EchoMultipleIterator implements RecursiveIterator {
protected $active = array();
protected $children;
protected $key = 0;
public function __construct( array $children ) {
$this->children = $children;
}
public function rewind() {
$this->active = $this->children;
$this->key = 0;
foreach ( $this->active as $key => $it ) {
$it->rewind();
if ( !$it->valid() ) {
unset( $this->active[$key] );
}
}
}
public function valid() {
return (bool)$this->active;
}
public function next() {
$this->key++;
foreach ( $this->active as $key => $it ) {
$it->next();
if ( !$it->valid() ) {
unset( $this->active[$key] );
}
}
}
public function current() {
$result = array();
foreach ( $this->active as $it ) {
$result[] = $it->current();
}
return $result;
}
public function key() {
return $this->key;
}
public function hasChildren() {
return (bool)$this->active;
}
public function getChildren() {
// The NotRecursiveIterator is used rather than a RecursiveArrayIterator
// so that nested arrays dont get recursed.
return new EchoNotRecursiveIterator( new ArrayIterator( $this->current() ) );
}
}