bindmorecard.h 10.0 KB

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