123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- #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 <functional>
- #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<c2)
- s = std::to_string(c1) + std::to_string(c2);
- else
- s = std::to_string(c2) + std::to_string(c1);
- result_type st1 = std::hash<std::string>{}(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<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(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<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();
- }
- bool empty_slop()
- {
- return back(0).empty();
- }
- int size()
- {
- return m_arr.size();
- }
- void grow(uint64_t ct)
- {
- if(size()&&empty_slop())
- {
- back(0).reset();
- back(0).m_timestamp=ct;
- }
- else
- {
- Data d(ct);
- 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;
- }
- 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 = MyHash{}(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)));
- }
- }
- }
- handle_event(tmpvec);
- 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 = 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<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;
- void handle_event(std::map<uint64_t,std::string> m);
- virtual void create_event(uint32_t key,double lv,double cv,const std::string &desc)=0;
- virtual void write_data(std::vector<std::string> &v,const std::string & card1,const std::string &card2){}
- 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 = 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<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);
- //去除俩卡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<std::string> &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<TcardInterface> 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<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();
- }
- 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<uint64_t,std::string> selectcard(std::vector<uint64_t> &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<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);
- //过滤掉超过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<TcardInterface> 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<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(""));
- }
- virtual void create_event(uint32_t key,double lv,double cv,const std::string &desc);
- };
- #endif
|