PHPhash consistency-PHP source code

Source: Internet
Author: User
PHPhash consistency jump

_ Hasher = $ hasher? $ Hasher: new FlexiHash_Crc32Hasher (); // number of virtual nodes if (! Empty ($ replicas) {$ this-> _ replicas = $ replicas;}/*** add nodes based on the number of virtual nodes, distribute nodes to more virtual locations */public function addTarget ($ target) {if (isset ($ this-> _ targetToPositions [$ target]) {throw new FlexiHash_Exception ("Target $ target already exists. ") ;}$ this-> _ targetToPositions [$ target] = array (); for ($ I = 0; $ I <$ this-> _ replicas; $ I ++) {// hash $ position = $ this-> _ hasher-> hash ($ target. $ I); // The actual node corresponding to the virtual node $ this-> _ PositionToTarget [$ position] = $ target; // virtual node included in the real node $ this-> _ targetToPositions [$ target] [] = $ position ;} $ this-> _ positionToTargetSorted = false; // number of real nodes $ this-> _ targetCount ++; return $ this ;} /*** add multiple nodes **/public function addTargets ($ targets) {foreach ($ targets as $ target) {$ this-> addTarget ($ target );} return $ this;}/*** remove a node **/public function removeTarget ($ target) {if (! Isset ($ this-> _ targetToPositions [$ target]) {throw new FlexiHash_Exception ("target $ target does not exist \ n ");} foreach ($ this-> _ targetToPositions [$ target] as $ position) {unset ($ this-> _ positionToTarget [$ position]);} unset ($ this-> _ targetToPositions [$ target]); $ this-> _ targetCount --; return $ this ;} /*** get all nodes **/public function getAllTargets () {return array_keys ($ this-> _ targetToPositions);}/*** search for hash by key Real node **/public function lookup ($ resource) {$ targets = $ this-> lookupList ($ resource, 1); if (empty ($ targets )) {throw new FlexiHash_Exception ("no targets exist");} return $ targets [0];}/*** find the node where the resource exists ** description: based on the required quantity, returns the node with the value equal to or greater than $ resource hash and the smallest value. if the value does not exist or the number is insufficient, then one or more */public function lookupList ($ resource, $ requestedCount) {if (! $ RequestedCount) {throw new FlexiHash_Exception ('invalid count requested');} if (empty ($ this-> _ positionToTarget) {return array ();} // if ($ this-> _ targetCount = 1) {return array_unique (array_values ($ this-> _ positionToTarget ));} // obtain the value of the current key after hash $ resourcePosition = $ this-> _ hasher-> hash ($ resource); $ results = array (); $ collect = false; $ this-> _ sortPositionTargets (); // The search is equal to or equal to $ resourcePosition. It is large and the smallest number is foreach ($ this-> _ positionToTarget as $ key => $ value) {if (! $ Collect & $ key> $ resourcePosition) {$ collect = true;} if ($ collect &&! In_array ($ value, $ results) {$ results [] = $ value;} // find $ requestedCount or the number is the same as the actual number of nodes if (count ($ results) ==$ requestedCount | count ($ results) =$ this-> _ targetCount) {return $ results ;}// if the quantity is not enough or it is not found, starting from the first one, $ requestedCount-count ($ results) before $ results does not exist ), set to the desired node foreach ($ this-> _ positionToTarget as $ key => $ value) {if (! In_array ($ value, $ results) {$ results [] = $ value;} if (count ($ results) = $ requestedCount | count ($ results) ==$ this-> _ targetCount) {return $ results;}/*** sort by virtual node */private function _ sortPositionTargets () {if (! $ This-> _ positionToTargetSorted) {ksort ($ this-> _ positionToTarget, SORT_REGULAR); $ this-> _ positionToTargetSorted = true ;}}} // end class/*** hash mode */interface FlexiHash_Hasher {public function hash ($ string);} class FlexiHash_Crc32Hasher implements FlexiHash_Hasher {public function hash ($ string) {return sprintf ("% u", crc32 ($ string) ;}} class FlexiHash_Md5Hasher implements FlexiHash_Hasher {public function has H ($ string) {return substr (md5 ($ string), 0, 8 );}} class FlexiHash_Exception extends Exception {}$ runData ['In in _ time'] = microtime (true); for ($ I = 0; $ iaddTargets ($ targetsArray ); $ key = md5 (mt_rand (); $ targets = $ flexiHashObj-> lookup ($ key); // var_dump ($ targets);} echo "consistent hash :"; var_dump (number_format (microtime (true)-$ runData ['In in _ time'], 6); $ runData ['In in _ time'] = microtime (true ); $ m = new Memcache; $ M-> connect ('2017. 0.0.1 ', 11211); for ($ I = 0; $ iset ($ key, time (), 0, 10);} echo "single machine :"; var_dump (number_format (microtime (true)-$ runData ['In in _ time'], 6);?>

2. [Code]Hash consistency of virtual nodes
$ Value) {for ($ I = 0; $ I <$ this-> _ virtualNodeNum; $ I ++) {$ this-> _ node [sprintf ("% u", crc32 ($ value. "#". $ I)] = $ value. "#". $ I ;}// sort ksort ($ this-> _ node); // print_r ($ this-> _ node );} // Singleton mode static public function getInstance () {static $ memcacheObj = null; if (! Is_object ($ memcacheObj) {$ memcacheObj = new self ();} return $ memcacheObj;} private function _ connectMemcache ($ key) {$ this-> _ nodeData = array_keys ($ this-> _ node); // echo "all node: \ n "; // print_r ($ this-> _ nodeData); $ this-> _ keyNode = sprintf ("% u", crc32 ($ key )); // $ this-> _ keyNode = 1803717635; // var_dump ($ this-> _ keyNode ); // Obtain the nearest node corresponding to the key value $ nodeKey = $ this-> _ findServerNode (0, count ($ this-> _ nodeD Ata)-1); // var_dump ($ nodeKey); // echo "$ this-> _ keyNode: search node: $ nodeKey IP: {$ this-> _ node [$ nodeKey]} \ n "; // obtain the corresponding real ip list ($ config, $ num) = explode ("#", $ this-> _ node [$ nodeKey]); if (empty ($ config) {throw new Exception ("serach ip config error");} if (! Isset ($ this-> _ memcache [$ config]) {$ this-> _ memcache [$ config] = new Memcache; list ($ host, $ port) = explode (":", $ config); $ this-> _ memcache [$ config]-> connect ($ host, $ port );} return $ this-> _ memcache [$ config];} /*** query the nearest node from the virtual memcache node using the bipartite method * @ param int $ low start position * @ param int $ high end position */private function _ findServerNode ($ low, $ high) {// The start subscript is smaller than the end subscript if ($ low <$ high) {$ avg = intval ($ low + $ high)/2 ); if ($ this-> _ nodeData [$ avg] =$ this-> _ keyNode) {return $ this-> _ nodeData [$ avg];} elseif ($ this-> _ keyNode <$ this-> _ nodeData [$ avg]) {return $ this-> _ findServerNode ($ low, $ AVG-1 );} else {return $ this-> _ findServerNode ($ avg + 1, $ high) ;}} else if ($ low ==$ high )) {// if ($ low = 0 | $ low = count ($ this-> _ nodeData)-1) {return $ this-> _ nodeData [$ low];} // var_dump ($ low ); if ($ this-> _ nodeData [$ low] <$ this-> _ keyNode) {if (abs ($ this-> _ nodeData [$ low]-$ this-> _ keyNode) <abs ($ this-> _ nodeData [$ low + 1]-$ this-> _ keyNode) {return $ this-> _ nodeData [$ low];} else {return $ this-> _ nodeData [$ low + 1] ;}} else {if (abs ($ this-> _ nodeData [$ low]-$ this-> _ keyNode) <abs ($ this-> _ nodeData [$ low-1]-$ this-> _ keyNode) {return $ this-> _ nodeData [$ low];} else {return $ this-> _ nodeData [$ low-1] ;}} else {if ($ low = 0) & ($ high <0 )) {return $ this-> _ nodeData [$ low];} if (abs ($ this-> _ nodeData [$ low]-$ this-> _ keyNode) <abs ($ this-> _ nodeData [$ high]-$ this-> _ keyNode) {return $ this-> _ nodeData [$ low];} else {return $ this-> _ nodeData [$ high] ;}} public function set ($ key, $ value, $ expire = 0) {// var_dump ($ key); return $ this-> _ connectMemcache ($ key)-> set ($ key, json_encode ($ value), 0, $ expire );} public function add ($ key, $ vakue, $ expire = 0) {return $ this-> _ connectMemcache ($ key)-> add ($ key, json_encode ($ value ), 0, $ expire);} public function get ($ key) {return $ this-> _ connectMemcache ($ key)-> get ($ key, true );} public function delete ($ key) {return $ this-> _ connectMemcache ($ key)-> delete ($ key );}} $ runData ['In in _ time'] = microtime (true); // Test 10 thousand sets plus get for ($ I = 0; $ iset ($ key, TIME (), 10);} echo "consistent hash:"; var_dump (number_format (microtime (true)-$ runData ['In in _ time'], 6 )); $ runData ['In in _ time'] = microtime (true); $ m = new Memcache; $ m-> connect ('2017. 127. 0.0.1 ', 11211); for ($ I = 0; $ iset ($ key, time (), 0, 10);} echo "single machine :"; var_dump (number_format (microtime (true)-$ runData ['In in _ time'], 6 ));

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.