|
@@ -0,0 +1,388 @@
|
|
|
|
+#ifndef BIND_MORE_CARD_HPP__
|
|
|
|
+#define BIND_MORE_CARD_HPP__
|
|
|
|
+
|
|
|
|
+#include <time.h>
|
|
|
|
+#include <thread>
|
|
|
|
+#include <chrono>
|
|
|
|
+#include <functional>
|
|
|
|
+#include <unordered_map>
|
|
|
|
+#include <mutex>
|
|
|
|
+#include <sstream>
|
|
|
|
+#include <map>
|
|
|
|
+#include "card.h"
|
|
|
|
+#include "zlist.h"
|
|
|
|
+#include "cardMgr.h"
|
|
|
|
+#include "log.h"
|
|
|
|
+#define TIME_WIN_MILLISEC (15*60*1000)
|
|
|
|
+#define TIME_LIM_SEC (3*1000)
|
|
|
|
+struct Data
|
|
|
|
+{
|
|
|
|
+ Data(uint64_t ct)
|
|
|
|
+ {
|
|
|
|
+ reset();
|
|
|
|
+ m_timestamp = ct;
|
|
|
|
+ }
|
|
|
|
+ void reset()
|
|
|
|
+ {
|
|
|
|
+ m_index = 0;
|
|
|
|
+ m_ct.fill(0);
|
|
|
|
+ m_totaldistance = 0;
|
|
|
|
+ m_flag = false;
|
|
|
|
+ }
|
|
|
|
+ void increase(const int index)
|
|
|
|
+ {
|
|
|
|
+ m_ct[index]++;
|
|
|
|
+ }
|
|
|
|
+ uint32_t m_index;
|
|
|
|
+ std::array<uint16_t,2> m_ct;
|
|
|
|
+ double m_totaldistance;
|
|
|
|
+ uint64_t m_timestamp;
|
|
|
|
+ bool m_flag;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+struct TcardInterface
|
|
|
|
+{
|
|
|
|
+ // TcardInterface()=default;
|
|
|
|
+ TcardInterface(std::pair<uint64_t,uint64_t> sp,uint64_t ct,uint64_t owner,int size)
|
|
|
|
+ :m_cardid(sp)
|
|
|
|
+ ,m_timestamp(ct)
|
|
|
|
+ ,m_owner(owner)
|
|
|
|
+ ,SIZE(size)
|
|
|
|
+ {}
|
|
|
|
+
|
|
|
|
+ std::tuple<bool,std::string> setindex(uint64_t tsp,const uint64_t cid,const double d=0,bool ctflag =false)
|
|
|
|
+ {
|
|
|
|
+ bool flag = false;
|
|
|
|
+ assert(m_timestamp != 0||tsp != 0);
|
|
|
|
+ std::tuple<bool,std::string> stp(flag,"");
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if (empty())
|
|
|
|
+ grow(tsp);
|
|
|
|
+ uint64_t tmp_tsp_min = back(0).m_timestamp;
|
|
|
|
+ uint64_t tmp_tsp_max = back(0).m_timestamp + TIME_WIN_MILLISEC;
|
|
|
|
+ assert(tsp >= tmp_tsp_min);
|
|
|
|
+
|
|
|
|
+ do
|
|
|
|
+ {
|
|
|
|
+ if(tsp>=tmp_tsp_min && tsp < tmp_tsp_max)
|
|
|
|
+ {
|
|
|
|
+ if(!ctflag)
|
|
|
|
+ {
|
|
|
|
+ back(0).m_index++;
|
|
|
|
+ back(0).m_totaldistance+=d;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ int arrindex = getstrindex(cid);
|
|
|
|
+ if(arrindex == -1)
|
|
|
|
+ {
|
|
|
|
+ log_error("bindmorecard error.not match the cardid");
|
|
|
|
+ return stp;
|
|
|
|
+ }
|
|
|
|
+ back(0).increase(arrindex);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if(timeout())
|
|
|
|
+ {
|
|
|
|
+ auto tp = get();
|
|
|
|
+ stp = check(std::get<0>(tp),std::get<1>(tp));
|
|
|
|
+ skip(1);
|
|
|
|
+ }
|
|
|
|
+ grow(tsp);
|
|
|
|
+ tmp_tsp_min = back(0).m_timestamp;
|
|
|
|
+ tmp_tsp_max = back(0).m_timestamp + TIME_WIN_MILLISEC;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }while(1);
|
|
|
|
+ return stp;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ std::tuple<bool,std::string> checkLast()
|
|
|
|
+ {
|
|
|
|
+// std::tuple<bool,std::string> stp(false,std::string(""));
|
|
|
|
+// if (!timeout() && size()>=ConfStruct::getCs().remote_slot)
|
|
|
|
+// {
|
|
|
|
+// auto tp = get();
|
|
|
|
+// stp = check(std::get<0>(tp),std::get<1>(tp));
|
|
|
|
+// }
|
|
|
|
+// return stp;
|
|
|
|
+ return std::make_tuple(false,"");
|
|
|
|
+ }
|
|
|
|
+ void skip(int count)
|
|
|
|
+ {
|
|
|
|
+ for(int i =0;i<count&&i<size();i++)
|
|
|
|
+ m_arr.pop_front();
|
|
|
|
+ }
|
|
|
|
+ bool empty()
|
|
|
|
+ {
|
|
|
|
+ return m_arr.empty();
|
|
|
|
+ }
|
|
|
|
+ int size()
|
|
|
|
+ {
|
|
|
|
+ return m_arr.size();
|
|
|
|
+ }
|
|
|
|
+ void grow(uint64_t ct)
|
|
|
|
+ {
|
|
|
|
+ Data d(ct);
|
|
|
|
+ d.reset();
|
|
|
|
+ m_arr.push_back(d);
|
|
|
|
+ }
|
|
|
|
+ Data &back(int index)
|
|
|
|
+ {
|
|
|
|
+ assert(index<(int)size() && index >= 0);
|
|
|
|
+ return m_arr.at(size()-index-1);
|
|
|
|
+ }
|
|
|
|
+ std::tuple<int,int,double> get()
|
|
|
|
+ {
|
|
|
|
+ int total_ix=0,total_ct=0;
|
|
|
|
+ double dis = 0;
|
|
|
|
+ std::for_each(m_arr.begin(),m_arr.end(),[&total_ix,&total_ct,&dis](const Data &d){total_ix += d.m_index;total_ct+=(d.m_ct[0]+d.m_ct[1]);dis+=d.m_totaldistance;});
|
|
|
|
+ return std::make_tuple(total_ix,total_ct,dis);
|
|
|
|
+ }
|
|
|
|
+ bool timeout()
|
|
|
|
+ {
|
|
|
|
+ return size() == SIZE-1;
|
|
|
|
+ }
|
|
|
|
+ std::string getInfo_1()
|
|
|
|
+ {
|
|
|
|
+ std::stringstream ss;
|
|
|
|
+ ss<<m_cardid.first<<"&"<<m_cardid.second<<","<<m_arr[0].m_timestamp/1000<<","<<(back(0).m_timestamp+TIME_WIN_MILLISEC)/1000 <<",";
|
|
|
|
+ std::for_each(m_arr.begin(),m_arr.end(),[&ss](Data& d){
|
|
|
|
+ if (!d.m_flag)
|
|
|
|
+ {
|
|
|
|
+ ss<<d.m_timestamp/1000<<"&"<<d.m_totaldistance<<"&"<<d.m_index<<",";
|
|
|
|
+ d.m_flag = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ });
|
|
|
|
+ return ss.str();
|
|
|
|
+ }
|
|
|
|
+ std::string getInfo()
|
|
|
|
+ {
|
|
|
|
+ auto tp = get();
|
|
|
|
+ std::stringstream ss;
|
|
|
|
+ ss<<"{T:"<<std::get<0>(tp)<<","<<std::get<1>(tp)<<","<<std::get<2>(tp)<<"}";
|
|
|
|
+ //ss<<"{Total index:"<<std::get<0>(tp)<<","<<std::get<1>(tp)<<"},";
|
|
|
|
+ //m_arr.for_each([&ss](const Data&x){
|
|
|
|
+ // ss<<"["<<x.m_index<<","<<x.m_ct[0]+x.m_ct[1]<<"]";
|
|
|
|
+ //});
|
|
|
|
+ return std::move(ss.str());
|
|
|
|
+ }
|
|
|
|
+ inline std::tuple<bool,std::string> check(int index,int ct)
|
|
|
|
+ {
|
|
|
|
+ if(index*1.0/ct>=0.72)
|
|
|
|
+ {
|
|
|
|
+ std::string s = getInfo_1();
|
|
|
|
+ return std::make_tuple(true,s);
|
|
|
|
+ }
|
|
|
|
+ return std::make_tuple(false,std::string(""));
|
|
|
|
+ }
|
|
|
|
+ inline int getstrindex(const uint64_t cardid)
|
|
|
|
+ {
|
|
|
|
+ if(m_cardid.first == cardid)
|
|
|
|
+ return 0;
|
|
|
|
+ else
|
|
|
|
+ return 1;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+public:
|
|
|
|
+ std::pair<uint64_t,uint64_t> m_cardid;
|
|
|
|
+ uint64_t m_timestamp;
|
|
|
|
+ uint64_t m_owner;
|
|
|
|
+ std::deque<Data> m_arr;
|
|
|
|
+ int SIZE;
|
|
|
|
+ virtual ~TcardInterface(){}
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+struct CardFactory
|
|
|
|
+{
|
|
|
|
+ CardFactory(cardMgr*owner)
|
|
|
|
+ :m_owner(owner)
|
|
|
|
+ {}
|
|
|
|
+ std::map<uint64_t,std::string> setCT(uint64_t cid)
|
|
|
|
+ {
|
|
|
|
+ std::map<uint64_t,std::string> tmpvec;
|
|
|
|
+ auto opcard=card_list::instance()->get(cid);
|
|
|
|
+ uint64_t cttime = opcard->time_();
|
|
|
|
+ auto vec = m_owner->getcard(cid);
|
|
|
|
+ for(const auto cardid:vec)
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ uint64_t id = cardid+cid;
|
|
|
|
+ auto iter = m_map.find(id);
|
|
|
|
+ if(iter != m_map.end())
|
|
|
|
+ {
|
|
|
|
+ std::shared_ptr<TcardInterface> ptr = iter->second;
|
|
|
|
+ auto sp = ptr->setindex(cttime,cid,0,true);
|
|
|
|
+ if (std::get<0>(sp))
|
|
|
|
+ {
|
|
|
|
+ tmpvec.insert(std::make_pair(id,std::get<1>(sp)));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return std::move(tmpvec);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ std::map<uint64_t,std::string> handlecard(const std::vector<uint64_t>& vec,uint64_t cid)
|
|
|
|
+ {
|
|
|
|
+ std::map<uint64_t,std::string> tempvec;
|
|
|
|
+ auto opcard = card_list::instance()->get(cid);
|
|
|
|
+ uint64_t cttime = opcard->time_();
|
|
|
|
+ std::shared_ptr<TcardInterface> ptr = nullptr;
|
|
|
|
+ for(const auto cardid:vec)
|
|
|
|
+ {
|
|
|
|
+ uint64_t id = cid+cardid;
|
|
|
|
+ auto iter = m_map.find(id);
|
|
|
|
+ if(iter != m_map.end())
|
|
|
|
+ ptr = iter->second;
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ ptr = make_shared_(cardid,cid,cttime,id);
|
|
|
|
+ m_map.insert({id,ptr});
|
|
|
|
+ backup(cid,cardid);
|
|
|
|
+ }
|
|
|
|
+ auto npcard=card_list::instance()->get(cardid);
|
|
|
|
+ double dis = opcard->dist(*npcard);
|
|
|
|
+ auto sp=ptr->setindex(cttime,cid,dis);
|
|
|
|
+ if (std::get<0>(sp))
|
|
|
|
+ {
|
|
|
|
+ tempvec.insert(std::make_pair(id,std::get<1>(sp)));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return std::move(tempvec);
|
|
|
|
+ }
|
|
|
|
+ void erase(uint64_t id)
|
|
|
|
+ {
|
|
|
|
+ auto it = m_map.find(id);
|
|
|
|
+ if(it != m_map.end())
|
|
|
|
+ {
|
|
|
|
+ std::pair<uint64_t,uint64_t> p = it->second->m_cardid;
|
|
|
|
+ m_owner->remove_edge(p.first,p.second);
|
|
|
|
+ reset(id);
|
|
|
|
+ m_map.erase(it);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ inline std::string InfoMessage()
|
|
|
|
+ {
|
|
|
|
+ std::stringstream ss;
|
|
|
|
+ ss<<"S: "<<m_map.size();
|
|
|
|
+ for(auto it : m_map)
|
|
|
|
+ {
|
|
|
|
+ //ss<< " hash info["<<it.first <<"]first cardid:["<<it.second->m_cardid.first<<"]second cardid:["<<it.second->m_cardid.second<<"]Info:{total_size:"<<it.second->size()<<","<<it.second->getInfo()<<"}";
|
|
|
|
+ ss<< "["<<(uint32_t)(it.second->m_cardid.first)<<"]["<<(uint32_t)(it.second->m_cardid.second)<<"]{s:"<<it.second->size()<<","<<it.second->getInfo()<<"}";
|
|
|
|
+ }
|
|
|
|
+ return std::move(ss.str());
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ virtual std::map<uint64_t,std::string> selectcard(std::vector<uint64_t> &v,uint64_t cid) = 0;
|
|
|
|
+ virtual std::shared_ptr<TcardInterface> make_shared_(const uint64_t cid1,const uint64_t cid2,const uint64_t ctime,uint64_t key) = 0;
|
|
|
|
+ virtual void backup (uint64_t cid1,uint64_t cid2){}
|
|
|
|
+ virtual void reset (uint64_t cid){}
|
|
|
|
+ virtual std::tuple<bool,std::string> checkLast(std::shared_ptr<TcardInterface> &ti)=0;
|
|
|
|
+ virtual ~CardFactory(){}
|
|
|
|
+public:
|
|
|
|
+ std::unordered_map<uint64_t,std::shared_ptr<TcardInterface>> m_map;
|
|
|
|
+ cardMgr * m_owner;
|
|
|
|
+};
|
|
|
|
+struct CloserCardFactory : CardFactory
|
|
|
|
+{
|
|
|
|
+ CloserCardFactory(cardMgr*);
|
|
|
|
+ int m_closer_slot=0;
|
|
|
|
+ std::map<uint64_t,int> m_count;
|
|
|
|
+ bool getAccess(uint64_t cid1,uint64_t cid2)
|
|
|
|
+ {
|
|
|
|
+ uint64_t cid = cid1+cid2;
|
|
|
|
+ if(m_count[cid] < 30)
|
|
|
|
+ {
|
|
|
|
+ m_count[cid]++;
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ void reset(uint64_t id)
|
|
|
|
+ {
|
|
|
|
+ auto it = m_count.find(id);
|
|
|
|
+ if(it != m_count.end())
|
|
|
|
+ m_count.erase(it);
|
|
|
|
+ }
|
|
|
|
+ virtual std::map<uint64_t,std::string> selectcard(std::vector<uint64_t> &v,uint64_t cid)
|
|
|
|
+ {
|
|
|
|
+ std::map<uint64_t,std::string> vec;
|
|
|
|
+ if(v.empty()) return vec;
|
|
|
|
+ std::vector<uint64_t> rc(v.begin(),v.end());
|
|
|
|
+ auto opcard=card_list::instance()->get(cid);
|
|
|
|
+ rc.erase(std::remove_if(rc.begin(),rc.end(),[&](uint64_t cardid){
|
|
|
|
+ if(!getAccess(cid,cardid))
|
|
|
|
+ return true;
|
|
|
|
+ if(cardid == cid)
|
|
|
|
+ return true;
|
|
|
|
+ auto npcard = card_list::instance()->get(cardid);
|
|
|
|
+ if(npcard->type_()!=opcard->type_())
|
|
|
|
+ return true;
|
|
|
|
+ uint64_t ct1 = npcard->time_();
|
|
|
|
+ uint64_t ct2 = opcard->time_();
|
|
|
|
+ uint64_t ct3 = ct1>ct2?ct1-ct2:ct2-ct1;
|
|
|
|
+ return ct3 > TIME_LIM_SEC;
|
|
|
|
+ }),rc.end());
|
|
|
|
+
|
|
|
|
+ vec = handlecard(rc,cid);
|
|
|
|
+ return std::move(vec);
|
|
|
|
+ }
|
|
|
|
+ virtual void backup (uint64_t cid1,uint64_t cid2)
|
|
|
|
+ {
|
|
|
|
+ m_owner->addVertex(cid1,cid2);
|
|
|
|
+ }
|
|
|
|
+ virtual std::shared_ptr<TcardInterface> make_shared_(const uint64_t cid1,const uint64_t cid2,const uint64_t ctime,uint64_t key)
|
|
|
|
+ {
|
|
|
|
+ return std::make_shared<TcardInterface>(std::make_pair(cid1,cid2),ctime,key,m_closer_slot);
|
|
|
|
+ }
|
|
|
|
+ std::tuple<bool,std::string> checkLast(std::shared_ptr<TcardInterface> &ti)
|
|
|
|
+ {
|
|
|
|
+ return ti->checkLast();
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+struct RemoteCardFactory : CardFactory
|
|
|
|
+{
|
|
|
|
+ RemoteCardFactory(cardMgr*);
|
|
|
|
+ int m_remote_slot=0;
|
|
|
|
+ virtual std::map<uint64_t,std::string> selectcard(std::vector<uint64_t> &ov,uint64_t cid)
|
|
|
|
+ {
|
|
|
|
+ auto vcard=m_owner->getcard(cid);
|
|
|
|
+ log_info("%d....remote%d",vcard.size(),(vcard.empty()?0:vcard[0]));
|
|
|
|
+ std::sort(vcard.begin(),vcard.end());
|
|
|
|
+ std::sort(ov.begin(),ov.end());
|
|
|
|
+ std::vector<uint64_t> v(ov.size()+vcard.size());
|
|
|
|
+
|
|
|
|
+ auto it = std::set_difference(vcard.begin(),vcard.end(),ov.begin(),ov.end(),v.begin());
|
|
|
|
+ v.resize(it-v.begin());
|
|
|
|
+ auto opcard = card_list::instance()->get(cid);
|
|
|
|
+ v.erase(std::remove_if(v.begin(),v.end(),[&](uint64_t cardid){
|
|
|
|
+ auto npcard = card_list::instance()->get(cardid);
|
|
|
|
+ uint64_t ct1 = opcard->time_();
|
|
|
|
+ uint64_t ct2 = npcard->time_();
|
|
|
|
+ uint64_t ct3 = ct1>ct2?ct1-ct2:ct2-ct1;
|
|
|
|
+ return ct3 > TIME_LIM_SEC;
|
|
|
|
+ }),v.end());
|
|
|
|
+
|
|
|
|
+ auto vec = handlecard(v,cid);
|
|
|
|
+ return std::move(vec);
|
|
|
|
+ }
|
|
|
|
+ virtual std::shared_ptr<TcardInterface> make_shared_(const uint64_t cid1,const uint64_t cid2,const uint64_t ctime,uint64_t key)
|
|
|
|
+ {
|
|
|
|
+ return std::make_shared<TcardInterface>(std::make_pair(cid1,cid2),ctime,key,m_remote_slot);
|
|
|
|
+ }
|
|
|
|
+ std::tuple<bool,std::string> checkLast(std::shared_ptr<TcardInterface> &ti)
|
|
|
|
+ {
|
|
|
|
+ return std::make_tuple(false,std::string(""));
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+#endif
|