<?php
class FlexiHash{
private $serverList = array();
private $isSorted = FALSE;
public function addServer($server){
$hash = $this->mHash($server);
if(!isset($this->serverList[$hash])){
$this->serverList[$hash] = $server;
}
$this->isSorted = FALSE;
return TRUE;
}
public function removeServer($server){
$hash = $this->mHash($server);
if(isset($this->serverList[$hash])){
unset($this->serverList[$hash]);
}
$this->isSorted = FALSE;
return TRUE;
}
public function lookup($key){
$hash = $this->mHash($key);
if(!$this->isSorted){
ksort($this->serverList, SORT_NUMERIC);
$this->isSorted = TRUE;
}
foreach($this->serverList as $pos => $server){
if($hash >= $pos) return $server;
}
rsort($this->serverList);
$this->isSorted = FALSE;
foreach($this->serverList as $pos => $server){
return $server;
}
}
public function mHash($key){
$md5 = substr(md5($key), 0, 8);
$seed = 31;
$hash = 0;
for($i = 0; $i < 8; $i++){
$hash = $hash *$seed + ord($md5{$i});
$i ++;
}
return $hash & 0x7FFFFFFF;
}
}
$hserver = new FlexiHash();
$hserver->addServer("192.168.1.1");
$hserver->addServer("192.168.1.2");
$hserver->addServer("192.168.1.3");
$hserver->addServer("192.168.1.4");
$hserver->addServer("192.168.1.5");
$hserver->addServer("192.168.1.10");
echo "save key1 in server:", $hserver->lookup('esfjslfjsljfiosjdf');
echo "save key2 in server:", $hserver->lookup('dfrertketjsdflfsld');
echo "<hr>";
$hserver->removeServer("192.168.1.5");
echo "save key1 in server:", $hserver->lookup('esfjslfjsljfiosjdf');
echo "save key2 in server:", $hserver->lookup('dfrertketjsdflfsld');
echo "<hr>";
$hserver->addServer("192.168.1.6");
echo "save key1 in server:", $hserver->lookup('esfjslfjsljfiosjdf');
echo "save key2 in server:", $hserver->lookup('dfrertketjsdflfsld');
echo "<hr>";