zoukankan      html  css  js  c++  java
  • php实现一致性hash算法

    使用php实现一致性hash算法

    <?php
    
    use FlexihashHasherHasherInterface;
    use FlexihashHasherCrc32Hasher;
    
    use FlexihashException;
    
    /**
     * 参考:https://github.com/pda/flexihash
     * 一致性哈希算法实现
     * Class MyFlexiHash
     * 主要的方法有三个:addTarget、removeTarget、lookupList,其它都是语法糖
     * lookupList(key)的实现方式是在一个有序列表上先搜索大于key的部分,数量不够再从头选取元素进行补充
     */
    class MyFlexiHash {
    
    
        private $replicas = 64;
    
        private $hasher = null;
    
        private $positionTargetMap = array();
    
        private $targetPositionsMap = array();
    
        public function __construct(HasherInterface $hasher = null, $replicas = null)
        {
            $this->hasher = isset($hasher) ? $hasher : new Crc32Hasher();
            isset($replicas) && $this->replicas = $replicas;
        }
    
        public function addTarget($target, $weight = 1) {
            $positions = array();
            $existPositions = array_keys($this->positionTargetMap);
            for ($i = 0; $i < $this->replicas * $weight; $i++) {
                //find an position not in exist positions
                $suffix = '';
                do {
                    $suffix .= $i;
                    $position = $this->hasher->hash($target.''.$suffix);
                } while (in_array($position, $existPositions));
                //record position's target
                $this->positionTargetMap[$position] = $target;
                //collect position
                $positions[] = $position;
            }
            //sort position
            ksort($this->positionTargetMap);
            //record target's positions
            $this->targetPositionsMap[$target] = $positions;
        }
    
        public function removeTarget($target) {
            if (!isset($this->targetPositionsMap[$target])) {
                throw new Exception('remove not exists target: '.$target);
            }
            $positions = $this->targetPositionsMap[$target];
            //remove target's positions
            unset($this->targetPositionsMap[$target]);
            //remove position's target
            foreach ($positions as $position) {
                unset($this->positionTargetMap[$position]);
            }
        }
    
        public function lookup($resource) {
            return $this->lookupList($resource, 1)[0];
        }
    
        public function lookupList($resource, $count) {
            if ($this->isTargetsEmpty()) {
                throw new Exception('lookup targets empty');
            }
            if ($count > count($this->targetPositionsMap)) {
                throw new Exception('lookup targets not enough');
            }
            $targetList = array();
            $hash = $this->hasher->hash($resource);
            //find in the above positions
            foreach ($this->positionTargetMap as $position => $t) {
                if (count($targetList) == $count) {
                    break;
                }
                if ($hash >= $position) {
                    $targetList[] = $t;
                }
            }
            //find in the below positions
            if (count($targetList) < $count) {
                foreach ($this->positionTargetMap as $position => $t) {
                    if (count($targetList) == $count) {
                        break;
                    }
                    $targetList[] = $t;
                }
            }
            return $targetList;
        }
    
        public function isTargetsEmpty() {
            return count($this->targetPositionsMap) == 0;
        }
    
        public function addTargets($targets) {
            foreach ($targets as $target) {
                $this->addTarget($target);
            }
        }
    
        public function removeTargets($targets) {
            foreach ($targets as $target) {
                $this->removeTarget($target);
            }
        }
    }
    

     

  • 相关阅读:
    table表格宽带研究(附带:table表格为什么设置td宽度无效)
    同一天有重复请假
    C#通过SQL 添加,删除,或者修改表名。
    将数据导出到Excel2007格式。
    MRBS, meeting room manager system,会议预定管理系统
    于网站主机,DNS,域名解析,Web服务器关系详解
    关于启明星系统(OA系统,预定系统,请假系统等)开始ASP.NET身份验证
    启明星系统字体的演变
    从网易获取股票每日交易数据的爬虫程序
    如何让Web程序在点击按钮后出现如执行批处理程序般的效果
  • 原文地址:https://www.cnblogs.com/livepeace/p/8952045.html
Copyright © 2011-2022 走看看