/**
* Flexihash - PHP 的簡單一致雜湊實作。
*
* MIT 許可證
*
* 版權所有(c) 2008 Paul Annesley
*
* 特此授予任何取得副本的人免費授予許可
*
* 特此授予任何取得副本的人提供免費許可
*
* 特此授予任何取得副本的人提供免費許可
* 本「軟體」和相關的文件,受限地處理
* 本軟體,包括但不限於使用、複製、修改、合併、發布、分發、再授權和/或出售
* 本軟體的副本,並允許接受本軟體
* 的人員這樣做,但須符合以下條件:
*
* 上述版權聲明和本許可聲明應包含在
* 所有副本中或軟體的大部分。
*
* 本軟體是「原樣」提供,不提供任何形式的明示或暗示保證,包括但不限於適銷性、
* 針對特定用途的適用性和非侵權。在任何情況下,
* 作者或版權持有者均不對任何索賠、損害或其他
* 責任負責,無論是合約、侵權或其他行為,
* 由本軟體或本軟體或使用
* 軟體或進行其他交易。
*
* @author Paul Annesley
* @link http://paul.annesley.cc/
* @copyright Paul Annesley,2008
* @comment by MyZ (http:/ /blogblog.)/*/
/**
* 使用可插拔雜湊演算法的簡單一致性雜湊實作。
*
* @author Paul Annesley
* @package Flexihash
* @licence http://www.opensource.org/licenses/mit-license.php
*/
class Flexihash
{
/**
* The number of positions to hash each target to.
*
* @var int
* @comment 虛擬節點數,解決節點分佈不均的問題
*/
private $_replicas = 64;
/**
* 雜湊演算法,封裝在 Flexihash_Hasher 實作中。
* @var object Flexihash_Hasher
* @comment 使用的雜湊方法:md5,crc32
*/
private $_hasher;
/**
* Internal counter for current number of targets.
* @var int
* @comment 節點記數器
*/
private $_targetCount = 0;
/**
* Internal map of positions (hash outputs) to targets
* @var array { position => target, ... }
* @comment 位置對應節點,用於lookup中根據位置決定要存取的節點
*/
private $_positionToTarget = array();
/**
* Internal map of targets to lists of positions that target is hashed to.
* @var array { target => [ position, position, ... ], ... }
* @comment 節點對應位置,用於刪除節點
* /
private $_targetToPositions = array();
/**
* 位置到目標的內部映射是否已經排序。
* @var boolean
* @comment 是否已排序
*/
private $_positionToTargetSorted = false;
/**
* Constructor
* @param object $hasher Flexihash_Hasher
* @param int $replicas Amount of positions to hash each target to.
* @comment 建構子,決定要使用的hash方法和需擬節點數,虛擬節點數越數多,分佈越均勻,但程式的分佈式運算越慢
*/
public function __construct(Flexihash_Hasm =Flex)
{
$this->_hasher = $hasher ? $hasher : new Flexihash_Crc32Hasher();
if (!empty($replicas)) $this->_replicas = $replicas;
}
/****
* Add a target.
* @param string $target
* @chainable
* @comment 新增節點,根據虛擬節點數,將節點分佈到多個虛擬位置上
/****
* 新增目標清單。
* @param array $targets
* @chainable
public function addTarget($target){
if (isset($this->_targetToPositions[$target]))
{
拋出新的Flexihash_
Exception
("目標'$target' 已經存在。
}
$this->_targetToPositions[$target ] = array();
// 將目標雜湊到多個位置
for ($i = 0; $i _replicas; $i++)
{
$position = $this->_hasher- >hash($target . $i);
$this->_positionToTarget[$position] = $target; // 尋找
$this->_targetToPositions[$target] []= $position; // 移除目標
}
$this->_positionToTargetSorted = false;
$this->_targetCount++;
return $this;
}
/**&*/
public function addTargets($targets)
{
foreach ($targets as $target)
{
$this->addTarget($target);
}
return $this;🎜}
/**
* 刪除目標。
* @param string $target
* @chainable
*/
公用函數removeTarget($target)
{
if (!isset($this->_targetToPositions[$target]))
{
拋出新的Flexihash_((() ' $target'不存在。 this->_targetToPositions[$target]);
$this->_targetCount--;
return $this;
}
/**
* 所有潛在目標的清單
* @return array
*/
public function getAllTargets()
{
returnm >_targetToPositions);
}
/**
* 找出給定資源的目標。
* @param string $resource
* @return string
*/
公用函數查找($resource)
{
$targets = $this->lookupList($resource, 1);
if ( empty($targets)) throw new Flexihash_
Exception
('不存在目標');
return $targets[0];
}
/**
* Get a list of targets for the resource, in order of precedence.* Up to $requestedCount targets are returned, less if there are fewer in total.*
* @param string $re The length of the list to return
* @return array List of targets
* @comment 查找當前的資源對應的節點,
* 節點為空則返回空白, hash,對所有的位置進行排序,在有序的位置列上尋找當前資源的位置
* 當全部沒有找到的時候,將資源的位置確定為有序位置的第一個(形成一個環)
*返回所找到的節點
*/
public functionlookupList($resource, $requestedCount)
(
ifif requestedCount)
拋出new Flexihash_
Exception
('請求的計數無效');
//不處理任何目標
if (empty($this->_positionToTarget))
return array();
// 優化單一目標
if ($this->_targetCount == 1)
return array_unique(array_values($this->_positionToTarget));// 將資源哈希到某個位置$resourcePosition = $this->; _hasher->; ($resource);
$results = array();
$collect = false;
$this->_sortPositionTargets();
//搜尋resourcePosition
上方的值foreach ($this->; _position//搜尋resourcePosition
上方的值 =foreach ($this->; _position/Target as $key =To ; $value)
{
//傳遞資源位置後開始收集目標
if (!$collect && $key > $resourcePosition)
{
$collect = true;
}
//只收集任何目標的第一個實例
if ($collect && !in_array($value, $results))
{
$results []= $value;
}
//結果足夠時返回,或列表耗盡
if (count($results) == $requestedCount || count($results) == $this->_targetCount)
{
return $results;
}
}
//循環開始- 搜尋resourcePosition
下面的值foreach ($this->_positionToTarget as $key => $value)
{
if (!in_array($value, $results))
{
$results []= $value;
}
//當結果足夠時返回,或者列表耗盡
if (count($results) == $requestedCount || count($results) == $this->_targetCount)
{
return $results;
}
}
// 迭代兩個「部分」後回傳結果
return $results;
}
public function __toString()
{
return sprintf(
'%s{targets:[%s]}',
get_class($this),
implode(',', $this-> ; getAllTargets())
);
}
// ------------------------------------- - --
// 私有方法
/**
* 依位置對內部映射(位置到目標)進行排序
*/
私有函數_sortPositionTargets()
{
// 如果還沒有的話,按鍵(位置)排序
if (!$this->_positionToTargetSorted)
{
ksort($this->_positionToTarget, SORT_REGULAR);
$this->_positionToTargetSorted = true;
}
}
}
/**
* 將給定值雜湊到可排序的固定大小位址空間。
*
* @author Paul Annesley
* @package Flexihash
* @licence http://www.opensource.org/licenses/mit-license.php
*/
接口
公用函數雜湊($string);
}
/**
* 使用 CRC32 將數值雜湊到有符號的 32 位元 int 位址空間。
* 在 32 位元 PHP 下,此(安全)溢到負整數。
*
* @author Paul Annesley
* @package Flexihash
* @licence http:// /www.opensource.org/licenses/mit-license.php
*/
class Flexihash_Crc32Hasher
implements Flexihash_Hasher
{
/* (non-phpdoc)
* @see Flexihash_Hasher::hash()
*/
* @see Flexihash_Hasher::hash()
*/
crc32($string);
}
}
/**
* 使用 CRC32 將值雜湊到 32 位元二進位字串資料位址空間。
*
* @author Paul Annesley
* @package Flexihash
* @licence http://www.opensource.org/licenses/mit-license。 php
*/
class Flexihash_Md5Hasher
implements Flexihash_Hasher
{
/* (non-phpdoc)
* @see Flexe_Hasheree function hash($string)
{
return substr(md5($string), 0, 8); // 8 hexits = 32bit
// 4 bytes of binary md5 data could also be used, but
/ performance toform be the same.
}
}
/**
* Flexihash 拋出的
異常
。 * * @author Paul Annesley
* @package Flexihash
* @licence http://www.opensource.org/licenses/mit-license.php
*/
class Flexihash_
Exception
extends Exception{}
以上就介紹了一致性hash - php,包括了Exception方面的內容,希望對PHP教程有興趣的朋友有幫助。