Merge "Add ss_active_users in SiteStats::isSane"
[mediawiki.git] / includes / ArrayUtils.php
blob985271f70997ab1e58885e04e0142d194bb7dbae
1 <?php
3 class ArrayUtils {
4 /**
5 * Sort the given array in a pseudo-random order which depends only on the
6 * given key and each element value. This is typically used for load
7 * balancing between servers each with a local cache.
9 * Keys are preserved. The input array is modified in place.
11 * Note: Benchmarking on PHP 5.3 and 5.4 indicates that for small
12 * strings, md5() is only 10% slower than hash('joaat',...) etc.,
13 * since the function call overhead dominates. So there's not much
14 * justification for breaking compatibility with installations
15 * compiled with ./configure --disable-hash.
17 * @param $array The array to sort
18 * @param $key The string key
19 * @param $separator A separator used to delimit the array elements and the
20 * key. This can be chosen to provide backwards compatibility with
21 * various consistent hash implementations that existed before this
22 * function was introduced.
24 public static function consistentHashSort( &$array, $key, $separator = "\000" ) {
25 $hashes = array();
26 foreach ( $array as $elt ) {
27 $hashes[$elt] = md5( $elt . $separator . $key );
29 uasort( $array, function ( $a, $b ) use ( $hashes ) {
30 return strcmp( $hashes[$a], $hashes[$b] );
31 } );
34 /**
35 * Given an array of non-normalised probabilities, this function will select
36 * an element and return the appropriate key
38 * @param $weights array
40 * @return bool|int|string
42 public static function pickRandom( $weights ) {
43 if ( !is_array( $weights ) || count( $weights ) == 0 ) {
44 return false;
47 $sum = array_sum( $weights );
48 if ( $sum == 0 ) {
49 # No loads on any of them
50 # In previous versions, this triggered an unweighted random selection,
51 # but this feature has been removed as of April 2006 to allow for strict
52 # separation of query groups.
53 return false;
55 $max = mt_getrandmax();
56 $rand = mt_rand( 0, $max ) / $max * $sum;
58 $sum = 0;
59 foreach ( $weights as $i => $w ) {
60 $sum += $w;
61 # Do not return keys if they have 0 weight.
62 # Note that the "all 0 weight" case is handed above
63 if ( $w > 0 && $sum >= $rand ) {
64 break;
67 return $i;