bindmorecard.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. #ifndef BIND_MORE_CARD_HPP__
  2. #define BIND_MORE_CARD_HPP__
  3. #include <time.h>
  4. #include <thread>
  5. #include <chrono>
  6. #include <functional>
  7. #include <unordered_map>
  8. #include <mutex>
  9. #include <sstream>
  10. #include <map>
  11. #include <functional>
  12. #include "card.h"
  13. #include "zlist.h"
  14. #include "cardMgr.h"
  15. #include "log.h"
  16. #define TIME_WIN_MILLISEC (15*60*1000)
  17. #define TIME_LIM_SEC (3*1000)
  18. struct MyHash
  19. {
  20. typedef uint64_t result_type;
  21. result_type operator ()(uint64_t c1,uint64_t c2) const
  22. {
  23. std::string s;
  24. if(c1<c2)
  25. s = std::to_string(c1) + std::to_string(c2);
  26. else
  27. s = std::to_string(c2) + std::to_string(c1);
  28. result_type st1 = std::hash<std::string>{}(s);
  29. return st1;
  30. }
  31. };
  32. struct Data
  33. {
  34. Data(uint64_t ct)
  35. {
  36. reset();
  37. m_timestamp = ct;
  38. }
  39. void reset()
  40. {
  41. m_index = 0;
  42. m_ct.fill(0);
  43. m_totaldistance = 0;
  44. m_flag = false;
  45. }
  46. bool empty()
  47. {
  48. return m_index==0;
  49. }
  50. void increase(const int index)
  51. {
  52. m_ct[index]++;
  53. }
  54. uint32_t m_index;
  55. std::array<uint16_t,2> m_ct;
  56. double m_totaldistance;
  57. uint64_t m_timestamp;
  58. bool m_flag;
  59. };
  60. struct TcardInterface
  61. {
  62. // TcardInterface()=default;
  63. TcardInterface(std::pair<uint64_t,uint64_t> sp,uint64_t ct,uint64_t owner,int size)
  64. :m_cardid(sp)
  65. ,m_timestamp(ct)
  66. ,m_owner(owner)
  67. ,SIZE(size)
  68. {}
  69. std::tuple<bool,std::string> setindex(uint64_t tsp,const uint64_t cid,const double d=0,bool ctflag =false)
  70. {
  71. bool flag = false;
  72. assert(m_timestamp != 0||tsp != 0);
  73. std::tuple<bool,std::string> stp(flag,"");
  74. if (empty())
  75. grow(tsp);
  76. uint64_t tmp_tsp_min = back(0).m_timestamp;
  77. uint64_t tmp_tsp_max = back(0).m_timestamp + TIME_WIN_MILLISEC;
  78. //assert(tsp >= tmp_tsp_min);
  79. do
  80. {
  81. if(tsp>=tmp_tsp_min && tsp < tmp_tsp_max)
  82. {
  83. if(!ctflag)
  84. {
  85. back(0).m_index++;
  86. back(0).m_totaldistance+=d;
  87. }
  88. else
  89. {
  90. int arrindex = getstrindex(cid);
  91. if(arrindex == -1)
  92. {
  93. log_error("bindmorecard error.not match the cardid");
  94. return stp;
  95. }
  96. back(0).increase(arrindex);
  97. }
  98. break;
  99. }
  100. else if(tsp>=tmp_tsp_max)
  101. {
  102. if(timeout() && !empty_slop())//达到数量,而且最后一个slop是非空的则继续判断,否则,不判断。
  103. {
  104. auto tp = get();
  105. stp = check(std::get<0>(tp),std::get<1>(tp));
  106. skip(1);
  107. }
  108. grow(tsp);
  109. tmp_tsp_min = tsp;
  110. tmp_tsp_max = tsp + TIME_WIN_MILLISEC;
  111. }
  112. else
  113. {
  114. tsp=tmp_tsp_min;
  115. }
  116. }while(1);
  117. return stp;
  118. }
  119. std::tuple<bool,std::string> checkLast()
  120. {
  121. // std::tuple<bool,std::string> stp(false,std::string(""));
  122. // if (!timeout() && size()>=ConfStruct::getCs().remote_slot)
  123. // {
  124. // auto tp = get();
  125. // stp = check(std::get<0>(tp),std::get<1>(tp));
  126. // }
  127. // return stp;
  128. return std::make_tuple(false,"");
  129. }
  130. void skip(int count)
  131. {
  132. for(int i=0;i<count&&i<size();i++)
  133. m_arr.pop_front();
  134. }
  135. bool empty()
  136. {
  137. return m_arr.empty();
  138. }
  139. bool empty_slop()
  140. {
  141. return back(0).empty();
  142. }
  143. int size()
  144. {
  145. return m_arr.size();
  146. }
  147. void grow(uint64_t ct)
  148. {
  149. if(size()&&empty_slop())
  150. {
  151. back(0).reset();
  152. back(0).m_timestamp=ct;
  153. }
  154. else
  155. {
  156. Data d(ct);
  157. m_arr.push_back(d);
  158. }
  159. }
  160. Data &back(int index)
  161. {
  162. assert(index<(int)size() && index >= 0);
  163. return m_arr.at(size()-index-1);
  164. }
  165. std::tuple<int,int,double> get()
  166. {
  167. int total_ix=0,total_ct=0;
  168. double dis = 0;
  169. 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;});
  170. return std::make_tuple(total_ix,total_ct,dis);
  171. }
  172. bool timeout()
  173. {
  174. return size()==SIZE;
  175. }
  176. std::string getInfo_1()
  177. {
  178. std::stringstream ss;
  179. ss<<m_cardid.first<<"&"<<m_cardid.second<<","<<m_arr[0].m_timestamp/1000<<","<<(back(0).m_timestamp+TIME_WIN_MILLISEC)/1000 <<",";
  180. std::for_each(m_arr.begin(),m_arr.end(),[&ss](Data& d){
  181. if (!d.m_flag)
  182. {
  183. ss<<d.m_timestamp/1000<<"&"<<d.m_totaldistance<<"&"<<d.m_index<<",";
  184. d.m_flag = true;
  185. }
  186. });
  187. return ss.str();
  188. }
  189. std::string getInfo()
  190. {
  191. auto tp = get();
  192. std::stringstream ss;
  193. ss<<"{T:"<<std::get<0>(tp)<<","<<std::get<1>(tp)<<","<<std::get<2>(tp)<<"}";
  194. //ss<<"{Total index:"<<std::get<0>(tp)<<","<<std::get<1>(tp)<<"},";
  195. //m_arr.for_each([&ss](const Data&x){
  196. // ss<<"["<<x.m_index<<","<<x.m_ct[0]+x.m_ct[1]<<"]";
  197. //});
  198. return std::move(ss.str());
  199. }
  200. inline std::tuple<bool,std::string> check(int index,int ct)
  201. {
  202. if(index*1.0/ct>=0.72)
  203. {
  204. std::string s = getInfo_1();
  205. return std::make_tuple(true,s);
  206. }
  207. return std::make_tuple(false,std::string(""));
  208. }
  209. inline int getstrindex(const uint64_t cardid)
  210. {
  211. if(m_cardid.first == cardid)
  212. return 0;
  213. else
  214. return 1;
  215. return -1;
  216. }
  217. public:
  218. std::pair<uint64_t,uint64_t> m_cardid;
  219. uint64_t m_timestamp;
  220. uint64_t m_owner;
  221. std::deque<Data> m_arr;
  222. int SIZE;
  223. virtual ~TcardInterface(){}
  224. };
  225. struct CardFactory
  226. {
  227. CardFactory(cardMgr*owner)
  228. :m_owner(owner)
  229. {}
  230. std::map<uint64_t,std::string> setCT(uint64_t cid)
  231. {
  232. std::map<uint64_t,std::string> tmpvec;
  233. auto opcard=card_list::instance()->get(cid);
  234. uint64_t cttime = opcard->time_();
  235. auto vec = m_owner->getcard(cid);
  236. for(const auto cardid:vec)
  237. {
  238. uint64_t id = MyHash{}(cardid,cid);
  239. auto iter = m_map.find(id);
  240. if(iter != m_map.end())
  241. {
  242. std::shared_ptr<TcardInterface> ptr = iter->second;
  243. auto sp = ptr->setindex(cttime,cid,0,true);
  244. if (std::get<0>(sp))
  245. {
  246. tmpvec.insert(std::make_pair(id,std::get<1>(sp)));
  247. }
  248. }
  249. }
  250. handle_event(tmpvec);
  251. return std::move(tmpvec);
  252. }
  253. std::map<uint64_t,std::string> handlecard(const std::vector<uint64_t>& vec,uint64_t cid)
  254. {
  255. std::map<uint64_t,std::string> tempvec;
  256. auto opcard = card_list::instance()->get(cid);
  257. uint64_t cttime = opcard->time_();
  258. std::shared_ptr<TcardInterface> ptr = nullptr;
  259. for(const auto cardid:vec)
  260. {
  261. uint64_t id = MyHash{}(cardid,cid);
  262. auto iter = m_map.find(id);
  263. if(iter != m_map.end())
  264. ptr = iter->second;
  265. else
  266. {
  267. log_info("handlecard..%lu,%d,%d",id,cardid,cid);
  268. ptr = make_shared_(cardid,cid,cttime,id);
  269. m_map.insert({id,ptr});
  270. backup(cid,cardid);
  271. }
  272. auto npcard=card_list::instance()->get(cardid);
  273. double dis = opcard->dist(*npcard);
  274. auto sp=ptr->setindex(cttime,cid,dis);
  275. if (std::get<0>(sp))
  276. {
  277. tempvec.insert(std::make_pair(id,std::get<1>(sp)));
  278. }
  279. }
  280. handle_event(tempvec);
  281. return std::move(tempvec);
  282. }
  283. void erase(uint64_t id)
  284. {
  285. auto it = m_map.find(id);
  286. if(it != m_map.end())
  287. {
  288. std::pair<uint64_t,uint64_t> p = it->second->m_cardid;
  289. m_owner->remove_edge(p.first,p.second);
  290. reset(id);
  291. m_map.erase(it);
  292. }
  293. }
  294. inline std::string InfoMessage()
  295. {
  296. std::stringstream ss;
  297. ss<<"S: "<<m_map.size();
  298. for(auto it : m_map)
  299. {
  300. //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()<<"}";
  301. ss<< "["<<(uint32_t)(it.second->m_cardid.first)<<"]["<<(uint32_t)(it.second->m_cardid.second)<<"]{s:"<<it.second->size()<<","<<it.second->getInfo()<<"}";
  302. }
  303. return std::move(ss.str());
  304. }
  305. virtual std::map<uint64_t,std::string> selectcard(std::vector<uint64_t> &v,uint64_t cid) = 0;
  306. virtual std::shared_ptr<TcardInterface> make_shared_(const uint64_t cid1,const uint64_t cid2,const uint64_t ctime,uint64_t key) = 0;
  307. virtual void backup (uint64_t cid1,uint64_t cid2){}
  308. virtual void reset (uint64_t cid){}
  309. virtual std::tuple<bool,std::string> checkLast(std::shared_ptr<TcardInterface> &ti)=0;
  310. void handle_event(std::map<uint64_t,std::string> m);
  311. virtual void create_event(uint32_t key,double lv,double cv,const std::string &desc)=0;
  312. virtual void write_data(std::vector<std::string> &v,const std::string & card1,const std::string &card2){}
  313. virtual ~CardFactory(){}
  314. public:
  315. std::unordered_map<uint64_t,std::shared_ptr<TcardInterface>> m_map;
  316. cardMgr * m_owner;
  317. };
  318. struct CloserCardFactory : CardFactory
  319. {
  320. CloserCardFactory(cardMgr*);
  321. int m_closer_slot=0;
  322. std::map<uint64_t,int> m_count;
  323. bool getAccess(uint64_t cid1,uint64_t cid2)
  324. {
  325. uint64_t cid = MyHash{}(cid1,cid2);
  326. if(m_count[cid] < 600)
  327. {
  328. m_count[cid]++;
  329. return false;
  330. }
  331. else
  332. return true;
  333. }
  334. void reset(uint64_t id)
  335. {
  336. auto it = m_count.find(id);
  337. if(it != m_count.end())
  338. m_count.erase(it);
  339. }
  340. //查找临近卡数据信息,并进行筛选
  341. virtual std::map<uint64_t,std::string> selectcard(std::vector<uint64_t> &v,uint64_t cid)
  342. {
  343. std::map<uint64_t,std::string> vec;
  344. if(v.empty()) return vec;
  345. std::vector<uint64_t> rc(v.begin(),v.end());
  346. auto opcard=card_list::instance()->get(cid);
  347. //去除俩卡600次临近不计入数据,防止路过
  348. //卡号相同,类型不同得过滤掉
  349. //时间差超过3s得过滤掉
  350. rc.erase(std::remove_if(rc.begin(),rc.end(),[&](uint64_t cardid){
  351. if(!getAccess(cid,cardid))
  352. return true;
  353. if(cardid == cid)
  354. return true;
  355. auto npcard = card_list::instance()->get(cardid);
  356. if(!npcard) return true;
  357. if(npcard->type_()!=opcard->type_())
  358. return true;
  359. uint64_t ct1 = npcard->time_();
  360. uint64_t ct2 = opcard->time_();
  361. uint64_t ct3 = ct1>ct2?ct1-ct2:ct2-ct1;
  362. return ct3 > TIME_LIM_SEC;
  363. }),rc.end());
  364. vec = handlecard(rc,cid);
  365. return std::move(vec);
  366. }
  367. virtual void write_data(std::vector<std::string> &v,const std::string & card1,const std::string &card2);
  368. virtual void backup (uint64_t cid1,uint64_t cid2)
  369. {
  370. m_owner->addVertex(cid1,cid2);
  371. }
  372. virtual std::shared_ptr<TcardInterface> make_shared_(const uint64_t cid1,const uint64_t cid2,const uint64_t ctime,uint64_t key)
  373. {
  374. log_info("handlecard_closer:%d,%d",cid1,cid2);
  375. return std::make_shared<TcardInterface>(std::make_pair(cid1,cid2),ctime,key,m_closer_slot);
  376. }
  377. std::tuple<bool,std::string> checkLast(std::shared_ptr<TcardInterface> &ti)
  378. {
  379. return ti->checkLast();
  380. }
  381. virtual void create_event(uint32_t key,double lv,double cv,const std::string &desc);
  382. };
  383. struct RemoteCardFactory : CardFactory
  384. {
  385. RemoteCardFactory(cardMgr*);
  386. int m_remote_slot=0;
  387. virtual std::map<uint64_t,std::string> selectcard(std::vector<uint64_t> &ov,uint64_t cid)
  388. {
  389. //从boost图中找到与之有过临近记录得卡
  390. auto vcard=m_owner->getcard(cid);
  391. log_info("selectcard_remote.card_id:%d,%d...",cid,vcard.size());
  392. std::sort(vcard.begin(),vcard.end());
  393. std::sort(ov.begin(),ov.end());
  394. std::vector<uint64_t> v(ov.size()+vcard.size());
  395. //找到之前临近卡,现在非临近得卡
  396. auto it = std::set_difference(vcard.begin(),vcard.end(),ov.begin(),ov.end(),v.begin());
  397. v.resize(it-v.begin());
  398. // auto opcard = card_list::instance()->get(cid);
  399. //过滤掉超过3s得卡信息
  400. // v.erase(std::remove_if(v.begin(),v.end(),[&](uint64_t cardid){
  401. // auto npcard = card_list::instance()->get(cardid);
  402. // uint64_t ct1 = opcard->time_();
  403. // uint64_t ct2 = npcard->time_();
  404. // uint64_t ct3 = ct1>ct2?ct1-ct2:ct2-ct1;
  405. // return ct3 > TIME_LIM_SEC;
  406. // }),v.end());
  407. //执行卡
  408. log_info("selectcard_remote.card_id:%d,%d...",cid,v.size());
  409. auto vec = handlecard(v,cid);
  410. return std::move(vec);
  411. }
  412. virtual std::shared_ptr<TcardInterface> make_shared_(const uint64_t cid1,const uint64_t cid2,const uint64_t ctime,uint64_t key)
  413. {
  414. log_info("handlecard_remote:%d,%d",cid1,cid2);
  415. return std::make_shared<TcardInterface>(std::make_pair(cid1,cid2),ctime,key,m_remote_slot);
  416. }
  417. std::tuple<bool,std::string> checkLast(std::shared_ptr<TcardInterface> &ti)
  418. {
  419. return std::make_tuple(false,std::string(""));
  420. }
  421. virtual void create_event(uint32_t key,double lv,double cv,const std::string &desc);
  422. };
  423. #endif