#ifndef BIND_MORE_CARD_HPP__ #define BIND_MORE_CARD_HPP__ #include #include #include #include #include #include #include #include #include #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 MyHash { typedef uint64_t result_type; result_type operator ()(uint64_t c1,uint64_t c2) const { std::string s; if(c1{}(s); return st1; } }; 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; } bool empty() { return m_index==0; } void increase(const int index) { m_ct[index]++; } uint32_t m_index; std::array m_ct; double m_totaldistance; uint64_t m_timestamp; bool m_flag; }; struct TcardInterface { // TcardInterface()=default; TcardInterface(std::pair sp,uint64_t ct,uint64_t owner,int size) :m_cardid(sp) ,m_timestamp(ct) ,m_owner(owner) ,SIZE(size) {} std::tuple 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 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(tsp>=tmp_tsp_max) { if(timeout() && !empty_slop())//达到数量,而且最后一个slop是非空的则继续判断,否则,不判断。 { auto tp = get(); stp = check(std::get<0>(tp),std::get<1>(tp)); skip(1); } grow(tsp); tmp_tsp_min = tsp; tmp_tsp_max = tsp + TIME_WIN_MILLISEC; } else { tsp=tmp_tsp_min; } }while(1); return stp; } std::tuple checkLast() { // std::tuple 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= 0); return m_arr.at(size()-index-1); } std::tuple 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; } std::string getInfo_1() { std::stringstream ss; ss<(tp)<<","<(tp)<<","<(tp)<<"}"; //ss<<"{Total index:"<(tp)<<","<(tp)<<"},"; //m_arr.for_each([&ss](const Data&x){ // ss<<"["< 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 m_cardid; uint64_t m_timestamp; uint64_t m_owner; std::deque m_arr; int SIZE; virtual ~TcardInterface(){} }; struct CardFactory { CardFactory(cardMgr*owner) :m_owner(owner) {} std::map setCT(uint64_t cid) { std::map 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 = MyHash{}(cardid,cid); auto iter = m_map.find(id); if(iter != m_map.end()) { std::shared_ptr 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))); } } } handle_event(tmpvec); return std::move(tmpvec); } std::map handlecard(const std::vector& vec,uint64_t cid) { std::map tempvec; auto opcard = card_list::instance()->get(cid); uint64_t cttime = opcard->time_(); std::shared_ptr ptr = nullptr; for(const auto cardid:vec) { uint64_t id = MyHash{}(cardid,cid); auto iter = m_map.find(id); if(iter != m_map.end()) ptr = iter->second; else { log_info("handlecard..%lu,%d,%d",id,cardid,cid); 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))); } } handle_event(tempvec); return std::move(tempvec); } void erase(uint64_t id) { auto it = m_map.find(id); if(it != m_map.end()) { std::pair 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_cardid.first<<"]second cardid:["<m_cardid.second<<"]Info:{total_size:"<size()<<","<getInfo()<<"}"; ss<< "["<<(uint32_t)(it.second->m_cardid.first)<<"]["<<(uint32_t)(it.second->m_cardid.second)<<"]{s:"<size()<<","<getInfo()<<"}"; } return std::move(ss.str()); } virtual std::map selectcard(std::vector &v,uint64_t cid) = 0; virtual std::shared_ptr 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 checkLast(std::shared_ptr &ti)=0; void handle_event(std::map m); virtual void create_event(uint32_t key,double lv,double cv,const std::string &desc)=0; virtual void write_data(std::vector &v,const std::string & card1,const std::string &card2){} virtual ~CardFactory(){} public: std::unordered_map> m_map; cardMgr * m_owner; }; struct CloserCardFactory : CardFactory { CloserCardFactory(cardMgr*); int m_closer_slot=0; std::map m_count; bool getAccess(uint64_t cid1,uint64_t cid2) { uint64_t cid = MyHash{}(cid1,cid2); if(m_count[cid] < 600) { 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 selectcard(std::vector &v,uint64_t cid) { std::map vec; if(v.empty()) return vec; std::vector rc(v.begin(),v.end()); auto opcard=card_list::instance()->get(cid); //去除俩卡600次临近不计入数据,防止路过 //卡号相同,类型不同得过滤掉 //时间差超过3s得过滤掉 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) return true; 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 write_data(std::vector &v,const std::string & card1,const std::string &card2); virtual void backup (uint64_t cid1,uint64_t cid2) { m_owner->addVertex(cid1,cid2); } virtual std::shared_ptr make_shared_(const uint64_t cid1,const uint64_t cid2,const uint64_t ctime,uint64_t key) { log_info("handlecard_closer:%d,%d",cid1,cid2); return std::make_shared(std::make_pair(cid1,cid2),ctime,key,m_closer_slot); } std::tuple checkLast(std::shared_ptr &ti) { return ti->checkLast(); } virtual void create_event(uint32_t key,double lv,double cv,const std::string &desc); }; struct RemoteCardFactory : CardFactory { RemoteCardFactory(cardMgr*); int m_remote_slot=0; virtual std::map selectcard(std::vector &ov,uint64_t cid) { //从boost图中找到与之有过临近记录得卡 auto vcard=m_owner->getcard(cid); log_info("selectcard_remote.card_id:%d,%d...",cid,vcard.size()); std::sort(vcard.begin(),vcard.end()); std::sort(ov.begin(),ov.end()); std::vector 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); //过滤掉超过3s得卡信息 // 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()); //执行卡 log_info("selectcard_remote.card_id:%d,%d...",cid,v.size()); auto vec = handlecard(v,cid); return std::move(vec); } virtual std::shared_ptr make_shared_(const uint64_t cid1,const uint64_t cid2,const uint64_t ctime,uint64_t key) { log_info("handlecard_remote:%d,%d",cid1,cid2); return std::make_shared(std::make_pair(cid1,cid2),ctime,key,m_remote_slot); } std::tuple checkLast(std::shared_ptr &ti) { return std::make_tuple(false,std::string("")); } virtual void create_event(uint32_t key,double lv,double cv,const std::string &desc); }; #endif