I know there are many similar questions here, but I am having trouble implementing it correctly in my code.
I am pulling in id, ip, port and weight from a database and from there I want to be able to select a random ip that has a very low weight (not used recently).
Here is a subset of a result set. The full list is here.
id ip port weight tries
174 127.0.0.1 3128 906 0
101 127.0.0.1 8080 629 2
123 127.0.0.1 3128 433 3
226 127.0.0.1 3128 393 1
82 127.0.0.1 8080 333 2
252 127.0.0.1 8080 276 3
253 127.0.0.1 3128 209 0
240 127.0.0.1 3129 204 1
249 127.0.0.1 3128 190 0
261 127.0.0.1 8888 165 1
120 127.0.0.1 3128 161 3
188 127.0.0.1 8080 149 0
265 127.0.0.1 8080 108 1
275 127.0.0.1 8080 104 0
63 127.0.0.1 8080 95 2
196 127.0.0.1 8080 79 2
248 127.0.0.1 8080 73 1
223 127.0.0.1 8000 72 3
88 127.0.0.1 3128 69 3
422 127.0.0.1 8080 47 0
Going down the list I have many ip's that just aren't being selected and with a majority few being used over and over again.
Thanks to Yaniro, I came up with a better solution.
My code:
private function _weighted_random_simple($proxies)
{
foreach ($proxies as $proxy) {
$weight[] = $proxy['weight'];
}
array_multisort($weight, SORT_ASC, $proxies);
// Define the custom sort function
$proxie = array(
'id' => $proxies[0]['id'],
'ip' => $proxies[0]['ip'],
'port' => $proxies[0]['port'],
'weight' => $proxies[0]['weight'],
'tries' => $proxies[0]['tries']
);
return $proxie;
}
Can anyone offer a better piece of code?
Thanks
You could sort the array by the weight in ascending order and then select the first element which will guarantee the selection of the least busy server.
You code seems fine and you could also use: usort()
or uasort()
like so:
function cmp( $a, $b )
{
if ( $a[ 'weight' ] == $b[ 'weight' ] )
{
return 0;
}
return ( $a[ 'weight' ] < $b[ 'weight' ] ) ? -1 : 1;
}
usort( $fruits, "cmp" );
If you want the comparison function to be a part of you class do something like this:
class YourClass
{
static function cmp( $a, $b )
{
if ( $a[ 'weight' ] == $b[ 'weight' ] )
{
return 0;
}
return ( $a[ 'weight' ] < $b[ 'weight' ] ) ? -1 : 1;
}
private function _weighted_random_simple( $proxies )
{
usort( $proxies, array( "YourClass", "cmp" ) );
return $proxies[ 0 ];
}
}
Or just loop through the array, find the lowest weight and return its index:
$lowest = -1;
$index = 0;
for ( $i = 0; $i < count( $proxies ); ++$i )
{
if ( $proxies[ $i ][ 'weight' ] < $lowest || $lowest == -1 )
{
$lowest = $proxies[ $i ][ 'weight' ];
$index = $i;
}
}
return $proxies[ $index ];