private function getRedis($key, $type = 'master') { // 查找$key所对应的hashkey $key = $this->getHashKey($key); // 通过oHash找到所在节点 $keyNode = $this->oHash->lookup($key); if (!isset($this->hostList[$keyNode])) { throw new \Exception('not found the key:' . $keyNode . ' in hostlist'); } // 找到节点的ip port信息 $hostInfo = $this->hostList[$keyNode]; $hostInfo = isset($hostInfo[$type]) ? $hostInfo[$type] : ''; // 如果找不到slave,则找master if ($type == 'slave') { if (!$hostInfo) { $hostInfo = isset($hostInfo['master']) ? $hostInfo['master'] : ''; } else { // 随机从所有slave中抽取一台作为访问 $hostInfo = $hostInfo[array_rand($hostInfo)]; } } if (!$hostInfo) { throw new \Exception('not found redis host'); } if (!$this->getInstance($hostInfo)) { throw new \Exception('can\'t connect to ' . $hostInfo); } // 如果开启了multi模式,则将开启事务的实例放入另外一个sets if ($this->multi) { if (!isset($this->multiInstanceList[$hostInfo])) { $this->multiInstanceList[$hostInfo] = $this->instanceList[$hostInfo]->multi($this->multi); } $this->multiKeyList[] = $key; // 保存对该key的调用顺序,不支持对单个key的多次调用 if (!isset($this->mapMultiHostToKey[$hostInfo])) { $this->mapMultiHostToKey[$hostInfo] = array(); } $this->mapMultiHostToKey[$hostInfo][] = $key; } return $this->instanceList[$hostInfo]; }
/** * Someone please explain this * * @param string $tmpl * @param string $_escape * @return string */ public function parse_link_template($tmpl, $_escape = "url_escape") { global $config; // don't bother hitting the database if it won't be used... $tags = ""; if (strpos($tmpl, '$tags') !== false) { // * stabs dynamically typed languages with a rusty spoon * $tags = $this->get_tag_list(); $tags = str_replace("/", "", $tags); $tags = preg_replace("/^\\.+/", "", $tags); } $base_href = $config->get_string('base_href'); $fname = $this->get_filename(); $base_fname = strpos($fname, '.') ? substr($fname, 0, strrpos($fname, '.')) : $fname; $tmpl = str_replace('$id', $this->id, $tmpl); $tmpl = str_replace('$hash_ab', substr($this->hash, 0, 2), $tmpl); $tmpl = str_replace('$hash_cd', substr($this->hash, 2, 2), $tmpl); $tmpl = str_replace('$hash', $this->hash, $tmpl); $tmpl = str_replace('$tags', $_escape($tags), $tmpl); $tmpl = str_replace('$base', $base_href, $tmpl); $tmpl = str_replace('$ext', $this->ext, $tmpl); $tmpl = str_replace('$size', "{$this->width}x{$this->height}", $tmpl); $tmpl = str_replace('$filesize', to_shorthand_int($this->filesize), $tmpl); $tmpl = str_replace('$filename', $_escape($base_fname), $tmpl); $tmpl = str_replace('$title', $_escape($config->get_string("title")), $tmpl); $tmpl = str_replace('$date', $_escape(autodate($this->posted, false)), $tmpl); // nothing seems to use this, sending the event out to 50 exts is a lot of overhead if (!SPEED_HAX) { $plte = new ParseLinkTemplateEvent($tmpl, $this); send_event($plte); $tmpl = $plte->link; } static $flexihash = null; static $fh_last_opts = null; $matches = array(); if (preg_match("/(.*){(.*)}(.*)/", $tmpl, $matches)) { $pre = $matches[1]; $opts = $matches[2]; $post = $matches[3]; if ($opts != $fh_last_opts) { $fh_last_opts = $opts; $flexihash = new Flexihash(); foreach (explode(",", $opts) as $opt) { $parts = explode("=", $opt); $parts_count = count($parts); $opt_val = ""; $opt_weight = 0; if ($parts_count === 2) { $opt_val = $parts[0]; $opt_weight = $parts[1]; } elseif ($parts_count === 1) { $opt_val = $parts[0]; $opt_weight = 1; } $flexihash->addTarget($opt_val, $opt_weight); } } $choice = $flexihash->lookup($pre . $post); $tmpl = $pre . $choice . $post; } return $tmpl; }
function formatKml($kmldata, $f) { $topicArr = explode(',', getconfig('kafkaTopic')); $hash = new Flexihash(); $hash->addTargets($topicArr); $msgs = []; if (!empty($kmldata)) { foreach ($kmldata as $k => $kml) { $msg = array('DIANHAO' => $kml['storeId'], 'FENPEI' => $kml['distribution'], 'RTHUOHAO' => $kml['rtNum'], 'CREATE_TIME' => $kml['createTime'], 'DOC_TIME' => $kml['docTime'], 'KML_FILE' => $f); $key = $hash->lookup($kml['storeId'] . $kml['rtNum']); $msgs[$key][] = $msg; } return $msgs; } }
public function testHashDistributionWithCrc32Hasher() { $hashSpace = new Flexihash(new Flexihash_Crc32Hasher()); foreach (range(1, $this->_targets) as $i) { $hashSpace->addTarget("target{$i}"); } $results = array(); foreach (range(1, $this->_lookups) as $i) { $results[$i] = $hashSpace->lookup("t{$i}"); } $distribution = array(); foreach ($hashSpace->getAllTargets() as $target) { $distribution[$target] = count(array_keys($results, $target)); } $this->dump(sprintf("Distribution of %d lookups per target (min/max/median/avg): %d/%d/%d/%d", $this->_lookups / $this->_targets, min($distribution), max($distribution), round($this->_median($distribution)), round(array_sum($distribution) / count($distribution)))); }
public function testFallbackPrecedenceWhenServerRemoved() { $mockHasher = new MockHasher(); $hashSpace = new Flexihash($mockHasher, 1); $mockHasher->setHashValue(10); $hashSpace->addTarget("t1"); $mockHasher->setHashValue(20); $hashSpace->addTarget("t2"); $mockHasher->setHashValue(30); $hashSpace->addTarget("t3"); $mockHasher->setHashValue(15); $this->assertEqual($hashSpace->lookup('resource'), 't2'); $this->assertEqual($hashSpace->lookupList('resource', 3), array('t2', 't3', 't1')); $hashSpace->removeTarget('t2'); $this->assertEqual($hashSpace->lookup('resource'), 't3'); $this->assertEqual($hashSpace->lookupList('resource', 3), array('t3', 't1')); $hashSpace->removeTarget('t3'); $this->assertEqual($hashSpace->lookup('resource'), 't1'); $this->assertEqual($hashSpace->lookupList('resource', 3), array('t1')); }