bindmorecard.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  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 "card.h"
  12. #include "zlist.h"
  13. #include "cardMgr.h"
  14. #include "log.h"
  15. #define TIME_WIN_MILLISEC (15*60*1000)
  16. #define TIME_LIM_SEC (3*1000)
  17. struct Data
  18. {
  19. Data(uint64_t ct)
  20. {
  21. reset();
  22. m_timestamp = ct;
  23. }
  24. void reset()
  25. {
  26. m_index = 0;
  27. m_ct.fill(0);
  28. m_totaldistance = 0;
  29. m_flag = false;
  30. }
  31. void increase(const int index)
  32. {
  33. m_ct[index]++;
  34. }
  35. uint32_t m_index;
  36. std::array<uint16_t,2> m_ct;
  37. double m_totaldistance;
  38. uint64_t m_timestamp;
  39. bool m_flag;
  40. };
  41. struct TcardInterface
  42. {
  43. // TcardInterface()=default;
  44. TcardInterface(std::pair<uint64_t,uint64_t> sp,uint64_t ct,uint64_t owner,int size)
  45. :m_cardid(sp)
  46. ,m_timestamp(ct)
  47. ,m_owner(owner)
  48. ,SIZE(size)
  49. {}
  50. std::tuple<bool,std::string> setindex(uint64_t tsp,const uint64_t cid,const double d=0,bool ctflag =false)
  51. {
  52. bool flag = false;
  53. assert(m_timestamp != 0||tsp != 0);
  54. std::tuple<bool,std::string> stp(flag,"");
  55. if (empty())
  56. grow(tsp);
  57. uint64_t tmp_tsp_min = back(0).m_timestamp;
  58. uint64_t tmp_tsp_max = back(0).m_timestamp + TIME_WIN_MILLISEC;
  59. assert(tsp >= tmp_tsp_min);
  60. do
  61. {
  62. if(tsp>=tmp_tsp_min && tsp < tmp_tsp_max)
  63. {
  64. if(!ctflag)
  65. {
  66. back(0).m_index++;
  67. back(0).m_totaldistance+=d;
  68. }
  69. else
  70. {
  71. int arrindex = getstrindex(cid);
  72. if(arrindex == -1)
  73. {
  74. log_error("bindmorecard error.not match the cardid");
  75. return stp;
  76. }
  77. back(0).increase(arrindex);
  78. }
  79. break;
  80. }
  81. else
  82. {
  83. if(timeout())
  84. {
  85. auto tp = get();
  86. stp = check(std::get<0>(tp),std::get<1>(tp));
  87. skip(1);
  88. }
  89. grow(tsp);
  90. tmp_tsp_min = back(0).m_timestamp;
  91. tmp_tsp_max = back(0).m_timestamp + TIME_WIN_MILLISEC;
  92. }
  93. }while(1);
  94. return stp;
  95. }
  96. std::tuple<bool,std::string> checkLast()
  97. {
  98. // std::tuple<bool,std::string> stp(false,std::string(""));
  99. // if (!timeout() && size()>=ConfStruct::getCs().remote_slot)
  100. // {
  101. // auto tp = get();
  102. // stp = check(std::get<0>(tp),std::get<1>(tp));
  103. // }
  104. // return stp;
  105. return std::make_tuple(false,"");
  106. }
  107. void skip(int count)
  108. {
  109. for(int i =0;i<count&&i<size();i++)
  110. m_arr.pop_front();
  111. }
  112. bool empty()
  113. {
  114. return m_arr.empty();
  115. }
  116. int size()
  117. {
  118. return m_arr.size();
  119. }
  120. void grow(uint64_t ct)
  121. {
  122. Data d(ct);
  123. d.reset();
  124. m_arr.push_back(d);
  125. }
  126. Data &back(int index)
  127. {
  128. assert(index<(int)size() && index >= 0);
  129. return m_arr.at(size()-index-1);
  130. }
  131. std::tuple<int,int,double> get()
  132. {
  133. int total_ix=0,total_ct=0;
  134. double dis = 0;
  135. 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;});
  136. return std::make_tuple(total_ix,total_ct,dis);
  137. }
  138. bool timeout()
  139. {
  140. return size() == SIZE-1;
  141. }
  142. std::string getInfo_1()
  143. {
  144. std::stringstream ss;
  145. ss<<m_cardid.first<<"&"<<m_cardid.second<<","<<m_arr[0].m_timestamp/1000<<","<<(back(0).m_timestamp+TIME_WIN_MILLISEC)/1000 <<",";
  146. std::for_each(m_arr.begin(),m_arr.end(),[&ss](Data& d){
  147. if (!d.m_flag)
  148. {
  149. ss<<d.m_timestamp/1000<<"&"<<d.m_totaldistance<<"&"<<d.m_index<<",";
  150. d.m_flag = true;
  151. }
  152. });
  153. return ss.str();
  154. }
  155. std::string getInfo()
  156. {
  157. auto tp = get();
  158. std::stringstream ss;
  159. ss<<"{T:"<<std::get<0>(tp)<<","<<std::get<1>(tp)<<","<<std::get<2>(tp)<<"}";
  160. //ss<<"{Total index:"<<std::get<0>(tp)<<","<<std::get<1>(tp)<<"},";
  161. //m_arr.for_each([&ss](const Data&x){
  162. // ss<<"["<<x.m_index<<","<<x.m_ct[0]+x.m_ct[1]<<"]";
  163. //});
  164. return std::move(ss.str());
  165. }
  166. inline std::tuple<bool,std::string> check(int index,int ct)
  167. {
  168. if(index*1.0/ct>=0.72)
  169. {
  170. std::string s = getInfo_1();
  171. return std::make_tuple(true,s);
  172. }
  173. return std::make_tuple(false,std::string(""));
  174. }
  175. inline int getstrindex(const uint64_t cardid)
  176. {
  177. if(m_cardid.first == cardid)
  178. return 0;
  179. else
  180. return 1;
  181. return -1;
  182. }
  183. public:
  184. std::pair<uint64_t,uint64_t> m_cardid;
  185. uint64_t m_timestamp;
  186. uint64_t m_owner;
  187. std::deque<Data> m_arr;
  188. int SIZE;
  189. virtual ~TcardInterface(){}
  190. };
  191. struct CardFactory
  192. {
  193. CardFactory(cardMgr*owner)
  194. :m_owner(owner)
  195. {}
  196. std::map<uint64_t,std::string> setCT(uint64_t cid)
  197. {
  198. std::map<uint64_t,std::string> tmpvec;
  199. auto opcard=card_list::instance()->get(cid);
  200. uint64_t cttime = opcard->time_();
  201. auto vec = m_owner->getcard(cid);
  202. for(const auto cardid:vec)
  203. {
  204. uint64_t id = cardid+cid;
  205. auto iter = m_map.find(id);
  206. if(iter != m_map.end())
  207. {
  208. std::shared_ptr<TcardInterface> ptr = iter->second;
  209. auto sp = ptr->setindex(cttime,cid,0,true);
  210. if (std::get<0>(sp))
  211. {
  212. tmpvec.insert(std::make_pair(id,std::get<1>(sp)));
  213. }
  214. }
  215. }
  216. return std::move(tmpvec);
  217. }
  218. std::map<uint64_t,std::string> handlecard(const std::vector<uint64_t>& vec,uint64_t cid)
  219. {
  220. std::map<uint64_t,std::string> tempvec;
  221. auto opcard = card_list::instance()->get(cid);
  222. uint64_t cttime = opcard->time_();
  223. std::shared_ptr<TcardInterface> ptr = nullptr;
  224. for(const auto cardid:vec)
  225. {
  226. uint64_t id = cid+cardid;
  227. auto iter = m_map.find(id);
  228. if(iter != m_map.end())
  229. ptr = iter->second;
  230. else
  231. {
  232. ptr = make_shared_(cardid,cid,cttime,id);
  233. m_map.insert({id,ptr});
  234. backup(cid,cardid);
  235. }
  236. auto npcard=card_list::instance()->get(cardid);
  237. double dis = opcard->dist(*npcard);
  238. auto sp=ptr->setindex(cttime,cid,dis);
  239. if (std::get<0>(sp))
  240. {
  241. tempvec.insert(std::make_pair(id,std::get<1>(sp)));
  242. }
  243. }
  244. return std::move(tempvec);
  245. }
  246. void erase(uint64_t id)
  247. {
  248. auto it = m_map.find(id);
  249. if(it != m_map.end())
  250. {
  251. std::pair<uint64_t,uint64_t> p = it->second->m_cardid;
  252. m_owner->remove_edge(p.first,p.second);
  253. reset(id);
  254. m_map.erase(it);
  255. }
  256. }
  257. inline std::string InfoMessage()
  258. {
  259. std::stringstream ss;
  260. ss<<"S: "<<m_map.size();
  261. for(auto it : m_map)
  262. {
  263. //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()<<"}";
  264. ss<< "["<<(uint32_t)(it.second->m_cardid.first)<<"]["<<(uint32_t)(it.second->m_cardid.second)<<"]{s:"<<it.second->size()<<","<<it.second->getInfo()<<"}";
  265. }
  266. return std::move(ss.str());
  267. }
  268. virtual std::map<uint64_t,std::string> selectcard(std::vector<uint64_t> &v,uint64_t cid) = 0;
  269. virtual std::shared_ptr<TcardInterface> make_shared_(const uint64_t cid1,const uint64_t cid2,const uint64_t ctime,uint64_t key) = 0;
  270. virtual void backup (uint64_t cid1,uint64_t cid2){}
  271. virtual void reset (uint64_t cid){}
  272. virtual std::tuple<bool,std::string> checkLast(std::shared_ptr<TcardInterface> &ti)=0;
  273. virtual ~CardFactory(){}
  274. public:
  275. std::unordered_map<uint64_t,std::shared_ptr<TcardInterface>> m_map;
  276. cardMgr * m_owner;
  277. };
  278. struct CloserCardFactory : CardFactory
  279. {
  280. CloserCardFactory(cardMgr*);
  281. int m_closer_slot=0;
  282. std::map<uint64_t,int> m_count;
  283. bool getAccess(uint64_t cid1,uint64_t cid2)
  284. {
  285. uint64_t cid = cid1+cid2;
  286. if(m_count[cid] < 30)
  287. {
  288. m_count[cid]++;
  289. return false;
  290. }
  291. else
  292. return true;
  293. }
  294. void reset(uint64_t id)
  295. {
  296. auto it = m_count.find(id);
  297. if(it != m_count.end())
  298. m_count.erase(it);
  299. }
  300. virtual std::map<uint64_t,std::string> selectcard(std::vector<uint64_t> &v,uint64_t cid)
  301. {
  302. std::map<uint64_t,std::string> vec;
  303. if(v.empty()) return vec;
  304. std::vector<uint64_t> rc(v.begin(),v.end());
  305. auto opcard=card_list::instance()->get(cid);
  306. rc.erase(std::remove_if(rc.begin(),rc.end(),[&](uint64_t cardid){
  307. if(!getAccess(cid,cardid))
  308. return true;
  309. if(cardid == cid)
  310. return true;
  311. auto npcard = card_list::instance()->get(cardid);
  312. if(npcard->type_()!=opcard->type_())
  313. return true;
  314. uint64_t ct1 = npcard->time_();
  315. uint64_t ct2 = opcard->time_();
  316. uint64_t ct3 = ct1>ct2?ct1-ct2:ct2-ct1;
  317. return ct3 > TIME_LIM_SEC;
  318. }),rc.end());
  319. vec = handlecard(rc,cid);
  320. return std::move(vec);
  321. }
  322. virtual void backup (uint64_t cid1,uint64_t cid2)
  323. {
  324. m_owner->addVertex(cid1,cid2);
  325. }
  326. virtual std::shared_ptr<TcardInterface> make_shared_(const uint64_t cid1,const uint64_t cid2,const uint64_t ctime,uint64_t key)
  327. {
  328. return std::make_shared<TcardInterface>(std::make_pair(cid1,cid2),ctime,key,m_closer_slot);
  329. }
  330. std::tuple<bool,std::string> checkLast(std::shared_ptr<TcardInterface> &ti)
  331. {
  332. return ti->checkLast();
  333. }
  334. };
  335. struct RemoteCardFactory : CardFactory
  336. {
  337. RemoteCardFactory(cardMgr*);
  338. int m_remote_slot=0;
  339. virtual std::map<uint64_t,std::string> selectcard(std::vector<uint64_t> &ov,uint64_t cid)
  340. {
  341. auto vcard=m_owner->getcard(cid);
  342. log_info("%d....remote%d",vcard.size(),(vcard.empty()?0:vcard[0]));
  343. std::sort(vcard.begin(),vcard.end());
  344. std::sort(ov.begin(),ov.end());
  345. std::vector<uint64_t> v(ov.size()+vcard.size());
  346. auto it = std::set_difference(vcard.begin(),vcard.end(),ov.begin(),ov.end(),v.begin());
  347. v.resize(it-v.begin());
  348. auto opcard = card_list::instance()->get(cid);
  349. v.erase(std::remove_if(v.begin(),v.end(),[&](uint64_t cardid){
  350. auto npcard = card_list::instance()->get(cardid);
  351. uint64_t ct1 = opcard->time_();
  352. uint64_t ct2 = npcard->time_();
  353. uint64_t ct3 = ct1>ct2?ct1-ct2:ct2-ct1;
  354. return ct3 > TIME_LIM_SEC;
  355. }),v.end());
  356. auto vec = handlecard(v,cid);
  357. return std::move(vec);
  358. }
  359. virtual std::shared_ptr<TcardInterface> make_shared_(const uint64_t cid1,const uint64_t cid2,const uint64_t ctime,uint64_t key)
  360. {
  361. return std::make_shared<TcardInterface>(std::make_pair(cid1,cid2),ctime,key,m_remote_slot);
  362. }
  363. std::tuple<bool,std::string> checkLast(std::shared_ptr<TcardInterface> &ti)
  364. {
  365. return std::make_tuple(false,std::string(""));
  366. }
  367. };
  368. #endif