|
@@ -0,0 +1,587 @@
|
|
|
|
+<?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_item($name,$card_type,$amount,$speed,$sort,0,$opened,$quality);
|
|
|
|
+ $this->mNameMapQuality["{$name}-{$card_type}-{$amount}"] = $quality;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function update_chctl($params)
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function update_ratios($ratios)
|
|
|
|
+ {
|
|
|
|
+ foreach ($ratios as $key => $ratio)
|
|
|
|
+ {
|
|
|
|
+ if(array_key_exists($key,$this->mSpeedtable)) {
|
|
|
|
+ $item = $this->mSpeedtable[$key];
|
|
|
|
+ $item->set_ratio($ratio);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function update_speeds($speeds)
|
|
|
|
+ {
|
|
|
|
+ foreach ($speeds as $key => $speed)
|
|
|
|
+ {
|
|
|
|
+ if(array_key_exists($key,$this->mSpeedtable)) {
|
|
|
|
+ $item = $this->mSpeedtable[$key];
|
|
|
|
+ $item->set_speed($speed);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ 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();
|
|
|
|
+// Log::record("max_price = {$max_inprice},in_price={$inPrice}",Log::DEBUG);
|
|
|
|
+ if ($max_inprice !== false && $inPrice > $max_inprice) {
|
|
|
|
+ continue;
|
|
|
|
+ } else {
|
|
|
|
+ $ctls[] = $item;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+// Log::record("auto_match speed table key={$key} is empty.",Log::DEBUG);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ 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;
|
|
|
|
+ $item->calc_speed(); //此处必须先计算速率,因为usort函数里面不能使用协程。
|
|
|
|
+ } else {
|
|
|
|
+// $key = $item->prefix();
|
|
|
|
+// Log::record("key={$key} has not opened",Log::DEBUG);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return $usable_items;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ //去掉已经关闭通道
|
|
|
|
+ $usable_items = $chooser($ctl_items);
|
|
|
|
+
|
|
|
|
+ //不过载的排在前面
|
|
|
|
+ $ascending = function ($l, $r)
|
|
|
|
+ {
|
|
|
|
+ $lproity = $l->priority();
|
|
|
|
+ $rproity = $r->priority();
|
|
|
|
+
|
|
|
|
+ //usort 函数内部,不可使用协程等待之类的代码.
|
|
|
|
+ $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[] = $item;
|
|
|
|
+ } else {
|
|
|
|
+ $result[] = $name;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(!empty($over_loads))
|
|
|
|
+ {
|
|
|
|
+ $assigner = new overload_assigner();
|
|
|
|
+ $assigner->add($over_loads);
|
|
|
|
+ $over_loads = $assigner->assign();
|
|
|
|
+
|
|
|
|
+ foreach ($over_loads as $item) {
|
|
|
|
+ $result[] = $item->name();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return $result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private function prefix($name,$spec,$card_type,$quality)
|
|
|
|
+ {
|
|
|
|
+ return "{$name}-{$spec}-{$card_type}-{$quality}";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const feed_minorder = 1;
|
|
|
|
+ const sleep_ratio = 0.005;
|
|
|
|
+
|
|
|
|
+ const max_sleep_time = 120;
|
|
|
|
+ const sleep_count = 5;
|
|
|
|
+
|
|
|
|
+ const wakeup_commit_count = 10;
|
|
|
|
+ const sleep_commit_count = 15;
|
|
|
|
+ const sleep_notify_count = 15;
|
|
|
|
+
|
|
|
|
+ const profit_count = 90;
|
|
|
|
+ const avg_order_time = 120;
|
|
|
|
+
|
|
|
|
+ private function knockout($ctls,$amount)
|
|
|
|
+ {
|
|
|
|
+ $waker = function ($items,$max_sleep_time)
|
|
|
|
+ {
|
|
|
|
+ $workers = [];
|
|
|
|
+ $wakeups = [];
|
|
|
|
+ $sleeps = [];
|
|
|
|
+
|
|
|
|
+ foreach ($items as $item)
|
|
|
|
+ {
|
|
|
|
+ [$fSleep,$time] = $item->sleeping();
|
|
|
|
+ if($fSleep)
|
|
|
|
+ {
|
|
|
|
+ if(time() > $time + $max_sleep_time) {
|
|
|
|
+ $item->wakeup();
|
|
|
|
+ $wakeups[] = $item;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ $sleeps[] = $item;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ $workers[] = $item;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return [$sleeps,$wakeups,$workers];
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ $sleeper = function($sleeps,$wakeups,$workers)
|
|
|
|
+ {
|
|
|
|
+ foreach ($workers as $item)
|
|
|
|
+ {
|
|
|
|
+ [$notify_count, $ratio] = $item->notify_ratio();
|
|
|
|
+ [$commit_count, $commit_succ] = $item->commit_statics();
|
|
|
|
+
|
|
|
|
+ if ($commit_succ >= self::sleep_commit_count && $notify_count >= self::sleep_notify_count && $ratio < self::sleep_ratio) {
|
|
|
|
+ $item->sleep();
|
|
|
|
+ $sleeps[] = $item;
|
|
|
|
+ } else {
|
|
|
|
+ $wakeups[] = $item;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return [$sleeps,$wakeups];
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ $desc_profit = function ($l, $r) use($amount)
|
|
|
|
+ {
|
|
|
|
+ [$lCount,$lRatio] = $l->notify_ratio();
|
|
|
|
+ [$rCount,$rRatio] = $r->notify_ratio();
|
|
|
|
+
|
|
|
|
+ $lProfit = $amount - $l->price();
|
|
|
|
+ $rRrofit = $amount - $r->price();
|
|
|
|
+
|
|
|
|
+ $lProfitRatio = $lProfit * $lRatio;
|
|
|
|
+ $rRrofitRatio = $rRrofit * $rRatio;
|
|
|
|
+
|
|
|
|
+ if($lProfitRatio > $rRrofitRatio) return -1;
|
|
|
|
+ elseif($lProfitRatio < $rRrofitRatio) return 1;
|
|
|
|
+ else return 0;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ [$sleeps,$wakeups,$workers] = $waker($ctls,self::max_sleep_time);
|
|
|
|
+ usort($workers, $desc_profit);
|
|
|
|
+
|
|
|
|
+ return $sleeper($sleeps,$wakeups,$workers);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private function feed_as_lazy_speed($ctls)
|
|
|
|
+ {
|
|
|
|
+ //当前提交量计算喂订单
|
|
|
|
+ $asc_speed = function ($l, $r) {
|
|
|
|
+ $lspeed = $l->lazy_speed();
|
|
|
|
+ $rspeed = $r->lazy_speed();
|
|
|
|
+ return $lspeed < $rspeed ? -1 : 1;
|
|
|
|
+ };
|
|
|
|
+ usort($ctls, $asc_speed);
|
|
|
|
+
|
|
|
|
+ $feeds = [];
|
|
|
|
+ $profits = [];
|
|
|
|
+ foreach ($ctls as $item)
|
|
|
|
+ {
|
|
|
|
+ $name = $item->name();
|
|
|
|
+ [$count,$ratio] = $item->notify_ratio();
|
|
|
|
+ $lazy_spped = $item->lazy_speed();
|
|
|
|
+
|
|
|
|
+// Log::record("auto_match channel {$name} count = {$count} ratio={$ratio} speed={$lazy_spped}",Log::DEBUG);
|
|
|
|
+ if($lazy_spped < self::feed_minorder) {
|
|
|
|
+ $feeds[] = $item;
|
|
|
|
+ } else {
|
|
|
|
+ $profits[] = $item;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return [$feeds,$profits];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function feed_as_commit($ctls)
|
|
|
|
+ {
|
|
|
|
+ //当前提交量计算喂订单
|
|
|
|
+ $ascer = function ($l, $r) {
|
|
|
|
+ [$lCount,$lSucc] = $l->commit_statics();
|
|
|
|
+ [$rCount,$rSucc] = $r->commit_statics();
|
|
|
|
+ return $lSucc < $rSucc ? -1 : 1;
|
|
|
|
+ };
|
|
|
|
+ usort($ctls, $ascer);
|
|
|
|
+
|
|
|
|
+ $feeds = [];
|
|
|
|
+ $profits = [];
|
|
|
|
+ foreach ($ctls as $item)
|
|
|
|
+ {
|
|
|
|
+ $name = $item->name();
|
|
|
|
+ [$comit_count,$commit_succ] = $item->commit_statics();
|
|
|
|
+ [$notify_count,$notify_succ] = $item->notify_statics();
|
|
|
|
+ $speed = $item->lazy_speed();
|
|
|
|
+
|
|
|
|
+ if($comit_count < self::wakeup_commit_count && $speed < self::feed_minorder) {
|
|
|
|
+ $feeds[] = $item;
|
|
|
|
+ $state = 'feed';
|
|
|
|
+ } else {
|
|
|
|
+ $profits[] = $item;
|
|
|
|
+ $state = 'profit';
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+// Log::record("auto_match channel {$name} state={$state} comit_succ={$commit_succ} count={$comit_count} notify_count={$notify_count} notify_succ={$notify_succ} speed={$speed}", Log::DEBUG);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return [$feeds,$profits];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function auto_match($names, int $spec, int $card_type, int $quality, $out_price, $max_inprice, $left_time): array
|
|
|
|
+ {
|
|
|
|
+ $formater = function ($val) {
|
|
|
|
+ return number_format($val,10,'.','');
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ $desctor = function ($item) use($out_price,$formater,$card_type,$spec) {
|
|
|
|
+ $name = $item->name();
|
|
|
|
+
|
|
|
|
+ [$notify_count,$ratio] = $item->notify_ratio();
|
|
|
|
+ [$commit_count,$commit_succ] = $item->commit_statics();
|
|
|
|
+
|
|
|
|
+ $prifit = $out_price - $item->price();
|
|
|
|
+ $profit_ratio = $formater($prifit * $ratio);
|
|
|
|
+
|
|
|
|
+ [$fSleep,$time] = $item->sleeping();
|
|
|
|
+ if($fSleep) {
|
|
|
|
+ $state = "sleeping";
|
|
|
|
+ $time = $time + 120 - time();
|
|
|
|
+ } else {
|
|
|
|
+ $state = "waking";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return "{$card_type}-{$spec} {$name} {$state} time={$time} commit_count={$commit_count} notify_count={$notify_count} ratio={$ratio} profit_ratio={$profit_ratio}";
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ $left_times = intval($left_time / self::avg_order_time);
|
|
|
|
+ $left_times = $left_times <= 0 ? 1 : $left_times;
|
|
|
|
+ Log::record("left_times = {$left_times}",Log::DEBUG);
|
|
|
|
+
|
|
|
|
+ $desc_profit = function ($l, $r) use($out_price,$formater,$left_times)
|
|
|
|
+ {
|
|
|
|
+ [$lCount,$lRatio] = $l->notify_ratio();
|
|
|
|
+ [$rCount,$rRatio] = $r->notify_ratio();
|
|
|
|
+
|
|
|
|
+ $lProfit = $out_price - $l->price();
|
|
|
|
+ $rRrofit = $out_price - $r->price();
|
|
|
|
+
|
|
|
|
+ $lProfitRatio = $lProfit * $lRatio;
|
|
|
|
+ $rRrofitRatio = $rRrofit * $rRatio;
|
|
|
|
+
|
|
|
|
+ $lProfit = $formater($lProfit);
|
|
|
|
+ $rRrofit = $formater($rRrofit);
|
|
|
|
+ $lProfitRatio = $formater($lProfitRatio);
|
|
|
|
+ $rRrofitRatio = $formater($rRrofitRatio);
|
|
|
|
+ $lRatio = $formater($lRatio);
|
|
|
|
+ $rRatio = $formater($rRatio);
|
|
|
|
+
|
|
|
|
+ $lRatios = intval($lRatio * $left_times + 0.05);
|
|
|
|
+ $rRatios = intval($rRatio * $left_times + 0.05);
|
|
|
|
+ $lRatios = $lRatios > 1 ? 1 : $lRatios;
|
|
|
|
+ $rRatios = $rRatios > 1 ? 1 : $rRatios;
|
|
|
|
+
|
|
|
|
+ if($lRatios == $rRatios && $lRatios == 1) { //次数大概率成功,按利润优先
|
|
|
|
+ if($lProfit > $rRrofit) return -1;
|
|
|
|
+ elseif($lProfit < $rRrofit) return 1;
|
|
|
|
+ else return 0;
|
|
|
|
+ }
|
|
|
|
+ elseif($lProfitRatio > $rRrofitRatio) return -1;
|
|
|
|
+ elseif($lProfitRatio < $rRrofitRatio) return 1;
|
|
|
|
+ elseif($lProfitRatio == 0) //利润获得概率为0,说明成功率或者利润可能性为0
|
|
|
|
+ {
|
|
|
|
+ if($lCount > $rCount) //此时优先喂单
|
|
|
|
+ {
|
|
|
|
+ if($rCount >= self::profit_count) //单量都大于阈值,优先利润
|
|
|
|
+ {
|
|
|
|
+ if($lProfit > $rRrofit) return -1;
|
|
|
|
+ elseif($lProfit < $rRrofit) return 1;
|
|
|
|
+ else return 0;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ elseif($lCount < $rCount)
|
|
|
|
+ {
|
|
|
|
+ if($lCount >= self::profit_count) //单量都大于阈值,优先利润
|
|
|
|
+ {
|
|
|
|
+ if($lProfit > $rRrofit) return -1;
|
|
|
|
+ elseif($lProfit < $rRrofit) return 1;
|
|
|
|
+ else return 0;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ $count = $lCount;
|
|
|
|
+ if($count >= self::profit_count) //单量都大于阈值,优先利润
|
|
|
|
+ {
|
|
|
|
+ if($lProfit > $rRrofit) return -1;
|
|
|
|
+ elseif($lProfit < $rRrofit) return 1;
|
|
|
|
+ else return 0;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ elseif ($lRatio > $rRatio) return -1; //以下是利润概率相等,优先成功率保障
|
|
|
|
+ elseif ($lRatio < $rRatio) return 1;
|
|
|
|
+ else return 0;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ $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];
|
|
|
|
+ $item->calc_speed();
|
|
|
|
+
|
|
|
|
+ $inPrice = $item->price();
|
|
|
|
+ if ($max_inprice !== false && $inPrice > $max_inprice) {
|
|
|
|
+ continue;
|
|
|
|
+ } else {
|
|
|
|
+ $ctls[] = $item;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ Log::record("auto_match speed table key={$key} is empty.",Log::DEBUG);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return $ctls;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ $logger = function ($items,$label) use ($desctor)
|
|
|
|
+ {
|
|
|
|
+ foreach ($items as $item) {
|
|
|
|
+ $msg = $desctor($item);
|
|
|
|
+ Log::record("auto_match {$label} = {$msg}",Log::DEBUG);
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ $names = array_unique($names);
|
|
|
|
+ Log::record("auto_match outprice= {$out_price} names=" . implode(',', $names), Log::DEBUG);
|
|
|
|
+
|
|
|
|
+ $can_feed = true;
|
|
|
|
+ $ctls = $price_filter($names,$spec,$card_type,$quality);
|
|
|
|
+ [$sleeps,$wakeups] = $this->knockout($ctls,$out_price);
|
|
|
|
+
|
|
|
|
+ $logger($sleeps,'sleeps');
|
|
|
|
+ $logger($wakeups,'wakeups');
|
|
|
|
+
|
|
|
|
+ if(empty($wakeups)) {
|
|
|
|
+ $ctls = $sleeps;
|
|
|
|
+ $sleeps = [];
|
|
|
|
+ } else {
|
|
|
|
+ $ctls = $wakeups;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //找出需要喂单
|
|
|
|
+ [$feeds,$profits] = $this->feed_as_commit($ctls);
|
|
|
|
+ usort($feeds, $desc_profit);
|
|
|
|
+
|
|
|
|
+ $profits = array_merge($profits, $sleeps);
|
|
|
|
+ usort($profits, $desc_profit);
|
|
|
|
+
|
|
|
|
+ $normals = [];
|
|
|
|
+ $overloads = [];
|
|
|
|
+ foreach ($profits as $item)
|
|
|
|
+ {
|
|
|
|
+ if($item->speed_overload()) {
|
|
|
|
+ $overloads[] = $item;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ $normals[] = $item;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(!empty($overloads)) {
|
|
|
|
+ $assigner = new overload_assigner();
|
|
|
|
+ $assigner->add($overloads);
|
|
|
|
+ $overloads = $assigner->assign();
|
|
|
|
+ }
|
|
|
|
+ $profits = array_merge($normals, $overloads);
|
|
|
|
+
|
|
|
|
+ $feed_names = [];
|
|
|
|
+ foreach ($feeds as $item) {
|
|
|
|
+ $feed_names[] = $item->name();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $profit_names = [];
|
|
|
|
+ foreach ($profits as $item) {
|
|
|
|
+ $profit_names[] = $item->name();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ($can_feed) {
|
|
|
|
+ $result = array_merge($feed_names, $profit_names);
|
|
|
|
+ } else {
|
|
|
|
+ $result = array_merge($profit_names,$feed_names);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $scan_feed = $can_feed ? 'true' : 'false';
|
|
|
|
+ $logger($feeds,'feeds');
|
|
|
|
+ $logger($profits,'profits');
|
|
|
|
+
|
|
|
|
+ Log::record("auto_match {$card_type}-{$spec} can_feed = {$scan_feed} result =" . implode(',',$result),Log::DEBUG);
|
|
|
|
+ return $result;
|
|
|
|
+ }
|
|
|
|
+}
|