<?phphash函数就是把变长的字符转化成定长,是一种压缩映射,hash值空间小于输入空间。hash函数使每个关键字都能均匀分布到hash表,关键字不冲突,常用算法有,直接取余、乘积取整和经典的Times33算法。hash表结构时间复杂度是O(1),实现方法是创建固定大小数组存数据,设计hash函数,通过hash函数把关键字映射到数组===========简单hash ============<?phpclass HashTable {private $buckets ;private $size = 10 ;public function __construct (){$this -> buckets = array (); //创建一个数组存放数据}private function hashFunc ( $key ){$strlen = strlen ( $key );$hashval = 0 ;for ( $i = 0 ; $i < $strlen ; $i ++ ){$hashval += ord ( $key { $i }); //取得$key字符串第$i个字符的ASCII值,然后累加}return $hashval % $this -> size ;}//有了hash函数,就可以实现插入和查找,插入数据时先通过hash函数计算关键字所在hash表的位置//然后把数据保存在此位置即可public function insert ( $key , $value ){$index = $this -> hashFunc ( $key );$this -> buckets [ $index ] = $value ;}//查找数据方法与插入数据类似,先通过hash函数计算关键字所在hash表的位置//然后返回此位置的数据即可public function find ( $key ){$index = $this -> hashFunc ( $key );return $this -> buckets [ $index ];}}//至此,一个简单的hash表编写完成,下面测试$ht = new HashTable ();$ht -> insert ( 'key1' , 'value1' ); //插入key1=>value1$ht -> insert ( 'key12' , 'value12' ); //插入key2=>value2echo $ht -> find ( 'key1' ), "<br />" ; //查找key1对应的数据echo $ht -> find ( 'key12' ); //查找key2对应的数据
=========== 拉链法 ===========<?php//拉链法就是递归存取对象,然后获取值class HashTable {private $bucekts ;private $size = 10 ;public function __construct (){$this -> buckets = new SplFixedArray ( $this -> size );}private function hashfunc ( $key ){$strlen = strlen ( $key );$hashval = 0 ;for ( $i = 0 ; $i < $strlen ; $i ++ {$hashval += ord ( $key ( $i ));}return $hashval % $this -> size ;}public function insert ( $key , $val ){$index = $this -> hashfunc ( $key );$this -> buckets [ $index ] = $val ;}public function find ( $key ){$index = $this -> hashfunc ( $key );return $this -> buckets [ $index ];}}?><?php$ht = new HashTable ();$ht -> insert ( 'key1' , 'value1' );$ht -> insert ( 'key1' , 'value1' );echo $ht -> find ( 'key1' );echo $ht -> find ( 'key2' );拉链法解决 key 值在 hash 上的值重复,就是把相同 hash 值的关键字节点用链表连接起来,比较链表中的每个元素关键字与查找的关键字是否相等class HashNode {public $key ;public $value ;public $nextNode ;public function __construct ( $key , $value , $nextNode = NULL ){$this -> key = $key ;$this -> value = $value ;$this -> nextNode = $nextNode ;}public function insert ( $key , $value ){$index = $this -> hashfunc ( $key );if ( isset ( $this -> buckets [ $index ])){$newNode = new HashNode ( $key , $value , $this -> buckets [ $index ]);} else {$newNode = new HashNode ( $key , $value , NULL );}$this -> buckets [ $index ] = $newNode ;}public function find ( $key ){$index = $this -> hashfunc ( $key );$current = $this -> bucekts [ $index ];while ( isset ( $current )){if ( $curent -> key == $key ){return $current -> value ;}$current = $current -> nextNode ;}return NULL ;}}?><?php$ht = new HashTable ();$ht -> insert ( 'key1' , 'value1' );$ht -> insert ( 'key12' , 'value12' );echo $ht -> find ( 'key1' );echo $ht -> find ( 'key12' );?>================ 一致性hash ================//逆向映射,也就是key 的hash值大于server 的,然后映射上去class Flexihash {private $serverList = array ();private $isSorted = FALSE ;function addServer ( $server ){$hash = mHash ( $server );if ( ! isset ( $this -> serverList [ $hash ])){$this -> serverList [ $hash ] = $server ;}$this -> isSorted = FALSE ;return TRUE ;}function removeServer ( $server ){$hash = mHash ( $server );if ( isset ( $this -> serverList [ $hash ])){unset ( $this -> serverList [ $hash ]);}$this -> isSorted = FALSE ;return TRUE ;}function lookup ( $key ){$hash = mHash ( $key );if ( ! $this -> isSorted ){krsort ( $this -> serverList , SORT_NUMERIC );$this -> isSorted = TRUE ;}foreach ( $this -> serverList as $pos => $server ){if ( $hash >= $pos ) return $server ;}return $this -> serverList [ $count ( $this -> serverList ) - 1 ];}function mHash ( $key ){$md5 = substr ( md5 (( $key ), 0 , 8 ));$seed = 3 ;$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' );echo "save key1 inserver:" . $hserver -> lookup ( 'key1' );echo "save key1 inserver:" . $hserver -> lookup ( 'key2' );$hserver -> removeServer ( '192.168.1.4' );echo "save key1 inserver:" . $hserver -> lookup ( 'key1' );echo "save key1 inserver:" . $hserver -> lookup ( 'key2' );$hserver -> removeServer ( '192.168.1.6' );echo "save key1 inserver:" . $hserver -> lookup ( 'key1' );echo "save key1 inserver:" . $hserver -> lookup ( 'key2' );$memcached = new Memcached (( $serverlist [ $mash ]));$memcached -> set ( $key , $value );
hash_consistent
最新推荐文章于 2021-07-29 10:10:17 发布