wiki.techinc.nl/includes/utils/ArrayUtils.php
Tim Starling e4bcbe722e Introduce includes/utils directory
These are classes that provide facilities for use by any caller, are
independent of user interface, and have a limited set of dependencies on
the rest of MediaWiki. See the README file for a more precise
definition.

These classes cannot go in includes/libs because of a dependency on the
MediaWiki framework, such as wfDebug() or MWException, but they are
otherwise similar. I thought it would be useful to put them in their own
directory, to make them more discoverable, and as part of a general
program of reducing clutter in the base includes/ directory.

I've probably missed a few classes which could be included here, but the
following classes were considered and were rejected for now:

* Fallback: single caller only
* GitInfo: getViewers() has inappropriate dependencies
* HttpFunctions: depends on configuration, $wgTitle
* PoolCounter: depends on configuration
* CacheHelper: depends on IContextSource, wfMemc()

Also moved a couple of classes into libs/ instead, where that seemed to
be more appropriate.

Change-Id: I274cff805b7d694b728a89b764a049cd62d320fe
2013-11-04 11:00:42 +11:00

68 lines
2.1 KiB
PHP

<?php
class ArrayUtils {
/**
* Sort the given array in a pseudo-random order which depends only on the
* given key and each element value. This is typically used for load
* balancing between servers each with a local cache.
*
* Keys are preserved. The input array is modified in place.
*
* Note: Benchmarking on PHP 5.3 and 5.4 indicates that for small
* strings, md5() is only 10% slower than hash('joaat',...) etc.,
* since the function call overhead dominates. So there's not much
* justification for breaking compatibility with installations
* compiled with ./configure --disable-hash.
*
* @param array $array Array to sort
* @param string $key
* @param string $separator A separator used to delimit the array elements and the
* key. This can be chosen to provide backwards compatibility with
* various consistent hash implementations that existed before this
* function was introduced.
*/
public static function consistentHashSort( &$array, $key, $separator = "\000" ) {
$hashes = array();
foreach ( $array as $elt ) {
$hashes[$elt] = md5( $elt . $separator . $key );
}
uasort( $array, function ( $a, $b ) use ( $hashes ) {
return strcmp( $hashes[$a], $hashes[$b] );
} );
}
/**
* Given an array of non-normalised probabilities, this function will select
* an element and return the appropriate key
*
* @param array $weights
* @return bool|int|string
*/
public static function pickRandom( $weights ) {
if ( !is_array( $weights ) || count( $weights ) == 0 ) {
return false;
}
$sum = array_sum( $weights );
if ( $sum == 0 ) {
# No loads on any of them
# In previous versions, this triggered an unweighted random selection,
# but this feature has been removed as of April 2006 to allow for strict
# separation of query groups.
return false;
}
$max = mt_getrandmax();
$rand = mt_rand( 0, $max ) / $max * $sum;
$sum = 0;
foreach ( $weights as $i => $w ) {
$sum += $w;
# Do not return keys if they have 0 weight.
# Note that the "all 0 weight" case is handed above
if ( $w > 0 && $sum >= $rand ) {
break;
}
}
return $i;
}
}