123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 |
- <?php
- namespace refill;
- use Log;
- use mtopcard;
- use algorithm;
- use scope_trace;
- class chctlex
- {
- protected $mSpeedtable;
- protected $mNameMapQuality;
- static $cache_names = [
- ['quality'=> 1,'name' => 'channel-ctl-oil-common-limit'],
- ['quality'=> 2,'name' => 'channel-ctl-oil-fast-limit'],
- ['quality'=> 3,'name' => 'channel-ctl-oil-card-limit'],
- ['quality'=> 5,'name' => 'channel-ctl-oil-slow-limit'],
- ['quality'=> 1,'name' => 'channel-ctl-phone-common-limit'],
- ['quality'=> 2,'name' => 'channel-ctl-phone-fast-limit'],
- ['quality'=> 3,'name' => 'channel-ctl-phone-card-limit'],
- ['quality'=> 4,'name' => 'channel-ctl-phone-third-limit'],
- ['quality'=> 5,'name' => 'channel-ctl-phone-slow-limit'], //24 hour
- ['quality'=> 6,'name' => 'channel-ctl-phone-slow6-limit'], //6 hour
- ['quality'=> 7,'name' => 'channel-ctl-phone-slow2-limit'], //2 hour
- ['quality'=> 8,'name' => 'channel-ctl-phone-slow48-limit'],//48 hour
- ['quality'=> 9,'name' => 'channel-ctl-phone-slow72-limit'] //72 hour
- ];
- public function __construct()
- {
- $this->mSpeedtable = [];
- }
- public function update_price($policy)
- {
- $QPTA = $policy->getQPTA();
- foreach ($this->mSpeedtable as $key => $item)
- {
- $quality = $item->quality();
- $name = $item->name();
- $spec = $item->spec();
- $card_type = $item->card_type();
- $prefix = "{$name}-{$card_type}-{$spec}";
- if(array_key_exists($quality,$QPTA) && array_key_exists($prefix,$QPTA[$quality])) {
- $price = $QPTA[$quality][$prefix]['price'];
- $item->set_price($price);
- }
- }
- }
- public function load($opened_names)
- {
- $this->mSpeedtable = [];
- $this->mNameMapQuality = [];
- foreach (self::$cache_names as $cache)
- {
- $quality = $cache['quality'];
- $cache_name = $cache['name'];
-
- $data = rcache($cache_name,"provider-");
- $data = unserialize($data['data']);
- $cfgs = empty($data) ? [] : $data;
- foreach ($cfgs as $items)
- {
- foreach ($items as $item)
- {
- $name = $item['name'];
- if(!algorithm::binary_search($opened_names,$name)) {
- continue;
- }
- $amount = $item['amount'];
- $card_type = $item['type'];
- $opened = $item['opened'] == 1;
- $sort = $item['sort'];
- $speed = $item['speed'];
- if($opened == false) continue;
- $key = $this->prefix($name,$amount,$card_type,$quality);
- $this->mSpeedtable[$key] = new ctl_itemex($name,$card_type,$amount,$speed,$sort,0,$opened,$quality);
- $this->mNameMapQuality["{$name}-{$card_type}-{$amount}"] = $quality;
- }
- }
- }
- }
- public function update_chctl($params)
- {
- foreach ($params as $key => $val)
- {
- [$name, $spec, $card_type] = explode('-', $key);
- $quality = $this->mNameMapQuality["{$name}-{$card_type}-{$spec}"] ?? 0;
- if($quality <=0) continue;
- $prefix = $this->prefix($name,$spec,$card_type,$quality);
- $ctl = $this->mSpeedtable[$prefix] ?? null;
- if(is_null($ctl)) continue;
- $ctl->update_params($val);
- }
- }
- public function update_maxspeeds($params)
- {
- foreach ($params as $key => $val)
- {
- [$name, $spec, $card_type] = explode('-', $key);
- $quality = $this->mNameMapQuality["{$name}-{$card_type}-{$spec}"] ?? 0;
- if ($quality <= 0) continue;
- $prefix = $this->prefix($name,$spec,$card_type,$quality);
- $ctl = $this->mSpeedtable[$prefix] ?? null;
- if(is_null($ctl)) continue;
- Log::record("update_maxspeeds {$key} speed={$val}",Log::DEBUG);
- $ctl->update_maxspeeds($val);
- }
- }
- public function match($names, int $spec, int $card_type, int $quality, $max_inprice)
- {
- $trace = new scope_trace(__METHOD__);
- if ($card_type == mtopcard\ThirdRefillCard) {
- return $names;
- }
- $pThis = $this;
- $price_filter = function ($names, $spec, $card_type, $quality) use ($pThis, $max_inprice)
- {
- $ctls = [];
- foreach ($names as $name)
- {
- $key = $pThis->prefix($name,$spec,$card_type,$quality);
- if(array_key_exists($key,$pThis->mSpeedtable))
- {
- $item = $pThis->mSpeedtable[$key];
- $inPrice = $item->price();
- if ($max_inprice !== false && $inPrice > $max_inprice) {
- continue;
- } else {
- $ctls[] = $item;
- }
- }
- }
- return $ctls;
- };
- $ctl_items = $price_filter($names,$spec,$card_type,$quality);
- $chooser = function ($ctl_items)
- {
- $usable_items = [];
- foreach ($ctl_items as $item)
- {
- if($item->opened()) {
- $usable_items[] = $item;
- }
- }
- return $usable_items;
- };
- //去掉已经关闭通道
- $usable_items = $chooser($ctl_items);
- //不过载的排在前面
- $ascending = function ($l, $r)
- {
- $lproity = $l->priority();
- $rproity = $r->priority();
- $lover = $l->speed_overload() ? 1 : 0;
- $rover = $r->speed_overload() ? 1 : 0;
- if($lover == $rover)
- {
- if ($lover) {
- return $lproity > $rproity ? -1 : 1; //如果都过载保优先级高的
- } else {
- return $lproity < $rproity ? -1 : 1;
- }
- }
- else {
- return $lover < $rover ? -1 : 1;
- }
- };
- usort($usable_items, $ascending);
- $result = [];
- $over_loads = [];
- foreach ($usable_items as $item)
- {
- $name = $item->name();
- $over_load = $item->speed_overload();
- if($over_load) {
- $over_loads[] = $name;
- } else {
- $result[] = $name;
- }
- }
- $result = array_merge($result, $over_loads);
- return $result;
- }
- private function prefix($name,$spec,$card_type,$quality)
- {
- return "{$name}-{$spec}-{$card_type}-{$quality}";
- }
- public function auto_match($names, int $spec, int $card_type, int $quality, $out_price, $max_inprice, $left_time): array
- {
- $desc_profit = function ($l, $r) use($out_price)
- {
- $lProfit = $out_price - $l->price();
- $rProfit = $out_price - $r->price();
- $lVal = $l->compile_val($lProfit);
- $rVal = $r->compile_val($rProfit);
- Log::record("auto_match desc_profit lname={$l->name()} lval={$lVal} rname={$r->name()} rval={$rVal}",Log::DEBUG);
- if ($lVal == $rVal)
- {
- if($lVal == 0.0)
- {
- $lSubmits = $l->submits();
- $rSubmits = $r->submits();
- if($lSubmits > $rSubmits) {
- return 1;
- }
- elseif ($lSubmits < $rSubmits) {
- return -1;
- }
- else {
- return 0;
- }
- }
- elseif ($lProfit > $rProfit) {
- return -1;
- }
- elseif ($lProfit < $rProfit) {
- return 1;
- }
- else {
- return 0;
- }
- }
- elseif ($lVal > $rVal) {
- return -1;
- }
- else {
- return 1;
- }
- };
- $pThis = $this;
- $price_filter = function ($names,$spec,$card_type,$quality) use($pThis,$max_inprice)
- {
- $ctls = [];
- foreach ($names as $name)
- {
- $key = $pThis->prefix($name,$spec,$card_type,$quality);
- if(array_key_exists($key,$pThis->mSpeedtable))
- {
- $item = $pThis->mSpeedtable[$key];
- $inPrice = $item->price();
- //Log::record("key={$key} inPrice = {$inPrice} max_inprice = {$max_inprice}",Log::DEBUG);
- if ($max_inprice !== false && $inPrice > $max_inprice) {
- continue;
- } else {
- $ctls[] = $item;
- }
- }
- }
- return $ctls;
- };
- $ctl_splitor = function ($ctls)
- {
- $zeros = [];
- $workers = [];
- $overs = [];
- $stops = [];
- foreach ($ctls as $item)
- {
- Log::record("ctl_splitor {$item->name()} speed={$item->cur_speed()} max_speed={$item->max_speed()}",Log::DEBUG);
- if($item->zero_speed()) {
- $zeros[] = $item;
- }
- elseif($item->speed_stoped()) {
- $stops[] = $item;
- }
- elseif($item->speed_overload()) {
- $overs[] = $item;
- }
- else {
- $workers[] = $item;
- }
- }
- return [$zeros, $workers, $overs, $stops];
- };
- $time_map = function ($ctls, $left_time)
- {
- $header = [];
- $ender = [];
- foreach ($ctls as $item)
- {
- if($item->notify_time() <= $left_time + 600) {
- $header[] = $item;
- } else {
- $ender[] = $item;
- }
- }
- return array_merge($header,$ender);
- };
- $header_fun = function (int $spec, int $card_type, int $quality) {
- return "auto_match {$quality}-{$spec}-{$card_type}";
- };
- $header = $header_fun($spec,$card_type,$quality);
- $names_getter = function ($ctls) {
- $names = [];
- foreach ($ctls as $item) {
- $names[] = $item->name();
- }
- return $names;
- };
- $ctlitem_logger = function ($tag, $ctls) use ($header,$names_getter)
- {
- $result = [];
- foreach ($ctls as $item) {
- $result[] = "{$item->name()}: speed={$item->cur_speed()} max_speed={$item->max_speed()} notify={$item->notify_time()}";
- }
- $sname = implode(',', $result);
- Log::record("{$header} {$tag} :{$sname}",Log::DEBUG);
- };
- //end for log
- //working .....
- $names = array_unique($names);
- Log::record("auto_match outprice= {$out_price} max_inprice={$max_inprice} names=" . implode(',', $names), Log::DEBUG);
- $ctls = $price_filter($names, $spec, $card_type, $quality);
- $ctlitem_logger("price filter", $ctls);
- [$zeros, $workers, $overloads, $stops] = $ctl_splitor($ctls);
- $ctlitem_logger("zeros",$zeros);
- $ctlitem_logger("workers",$workers);
- $ctlitem_logger("overloads",$overloads);
- $ctlitem_logger("stops",$stops);
- usort($workers, $desc_profit);
- usort($overloads, $desc_profit);
- usort($stops, $desc_profit);
- $ctlitem_logger("sort workers",$workers);
- $ctlitem_logger("sort overloads",$overloads);
- $ctlitem_logger("sort stops",$stops);
- $ctls = array_merge($zeros, $workers, $overloads, $stops);
- $ctlitem_logger("result merge ctls", $ctls);
- $ctls = $time_map($ctls, $left_time);
- $ctlitem_logger("result time check ctls", $ctls);
- $names = $names_getter($ctls);
- return $names;
- }
- }
|