PageRenderTime 28ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/horails/db.hpp

https://gitlab.com/horails/horails
C++ Header | 586 lines | 466 code | 82 blank | 38 comment | 86 complexity | deae1087831abd38a9e9b7ba98e8bce4 MD5 | raw file
  1. #ifndef _DB_HPP_
  2. #define _DB_HPP_
  3. #include "dateheure.hpp"
  4. #include "utils.hpp"
  5. #define MAXGARES 65536
  6. class gare_t {
  7. public:
  8. gare_t(int gid,const string &s,int i):id(i),code(gid),name(s),level(0),nbrtrains(0) {names.push_back(s);}
  9. int id;
  10. int getid() const {return id;}
  11. int code;
  12. string name;
  13. list<string> names;
  14. bool addname(const string &s) {
  15. list<string>::const_iterator it;
  16. for(it=names.begin();it!=names.end() && (*it)!=s;++it);
  17. if(it!=names.end()) return false;
  18. names.push_back(s);
  19. return true;
  20. }
  21. int level;
  22. int nbrtrains;
  23. };
  24. class gares_t {
  25. int newidgare() {
  26. static int idgare_auto=1;
  27. return idgare_auto++;
  28. }
  29. static int distance(const char *a,const char *b)
  30. {
  31. int la=strlen(a);
  32. int lb=strlen(b);
  33. int dd[(la+1)*(lb+1)];
  34. #define min3(a,b,c) ((a)<=(b)?(a)<=(c)?(a):(c):(b)<=(c)?(b):(c))
  35. #define DD(i,j) dd[(i)*(lb+1)+(j)]
  36. int i,j;
  37. for(j=0;j<=lb;j++) DD(la,j)=(j==lb?0:1);
  38. for(i=0;i<=la;i++) DD(i,lb)=la-i;
  39. for(i=la-1;i>=0;i--)
  40. for(j=lb-1;j>=0;j--)
  41. DD(i,j)=1+min3(DD(i+1,j),DD(i,j+1),DD(i+1,j+1)-(a[i]==b[j]?1:0));
  42. return DD(0,0);
  43. #undef DD
  44. #undef max3
  45. }
  46. public:
  47. map<int,gare_t*> _gare; //map sur id pour dess
  48. map<string,int> _strgare;
  49. map<int,int> _idgare; // map sur code->id
  50. void levelzero() {
  51. map<int,gare_t*>::iterator it=_gare.begin();
  52. for(;it!=_gare.end();++it) { it->second->level=0;}
  53. }
  54. void nbrgareszero() {
  55. map<int,gare_t*>::iterator it=_gare.begin();
  56. for(;it!=_gare.end();++it) { it->second->nbrtrains=0;}
  57. }
  58. void inclevelgares() {
  59. map<int,gare_t*>::iterator it=_gare.begin();
  60. for(;it!=_gare.end();++it) { /*printf("%d\n",it->second->nbrtrains);*/if(it->second->nbrtrains) it->second->level++;}
  61. }
  62. int add(int code,const string &name) {
  63. int gidd=_idgare[code];
  64. int gidd_=_strgare[name];
  65. if(gidd_ && gidd!=gidd_)
  66. _warn("gare %s deja %d!=%d\n",name.c_str(),gidd_,gidd);
  67. if(gidd==0) {
  68. gidd=newidgare();
  69. gare_t *g=new gare_t(code,name,gidd);
  70. _gare[gidd]=g;
  71. _idgare[code]=gidd;
  72. _strgare[name]=gidd;
  73. } else {
  74. gare_t *g=_gare[gidd];
  75. g->addname(name);
  76. _strgare[name]=gidd;
  77. }
  78. return gidd;
  79. }
  80. int getlevel(int i) const {
  81. const gare_t *g=getgare(i);
  82. if(g==NULL) return 0;
  83. return g->level;
  84. }
  85. const gare_t *getgare(int i) const {
  86. map<int,gare_t*>::const_iterator it=_gare.find(i);
  87. if(it==_gare.end()) return NULL;
  88. return it->second;
  89. }
  90. string garestring(int i) const {
  91. const gare_t *t=getgare(i);
  92. if(t==NULL) return "NULL";
  93. return t->name;
  94. }
  95. static string normalize(const string &s) {
  96. return stripspaces(capital(s));
  97. }
  98. int searchexact(const string &s) const {
  99. string ss=normalize(s);
  100. //printf("'%s'\n",ss.c_str());
  101. map<string,int>::const_iterator it=_strgare.find(ss);
  102. if(it!=_strgare.end()) return it->second;
  103. return 0;
  104. }
  105. //list<int> search(const string &s) const {}
  106. struct lala_t {
  107. int d;
  108. string s;
  109. bool operator<(const lala_t&o) const {
  110. return o.d<d;
  111. }
  112. };
  113. list<string> searchstr(const string &s, int max=30) const {
  114. string s2=normalize(s);
  115. priority_queue<lala_t> res;
  116. map<string,int>::const_iterator it;
  117. list<string> res2;
  118. for(it=_strgare.begin();it!=_strgare.end();it++) {
  119. lala_t r;
  120. r.d=distance(s2.c_str(),it->first.c_str());
  121. r.s=it->first;
  122. res.push(r);
  123. }
  124. while(!res.empty() && max>0) {
  125. lala_t r=res.top();res.pop();
  126. printf("%d: '%s'\n",r.d,r.s.c_str());
  127. res2.push_back(r.s);
  128. max--;
  129. }
  130. return res2;
  131. }
  132. string searchbest(const string &s) const {
  133. list<string> l=searchstr(s,1);
  134. return l.front();
  135. }
  136. int searchidbest(const string &s) const {
  137. string l=searchbest(s);
  138. return searchexact(l);
  139. }
  140. };
  141. class dess_t {
  142. public:
  143. dess_t(const heure_t &ha,int a,int bb):gare(bb),arriv(ha),arret(a) {}
  144. short gare;
  145. heure_t arriv; //-> temps ?
  146. short arret;
  147. //bool second;
  148. };
  149. class per_t {
  150. date_t start,end;
  151. int s;
  152. unsigned char *d;
  153. string text;
  154. bool all;
  155. public:
  156. per_t(bool a=true):d(NULL),all(a) {}
  157. per_t(const date_t &da,int ss):start(da),end(da+ss),s(ss),d(NULL),all(false) {
  158. d=new unsigned char[(s+7)/8];
  159. bzero(d,(s+7)/8);
  160. }
  161. ~per_t() {delete d;}
  162. bool test(const date_t &da) const {
  163. //_debug("test: start=%s end=%s s=%d da=%s\n",start.str().c_str(),end.str().c_str(),s,da.str().c_str());
  164. if(all) return true;
  165. if(start>da || da>=end) {
  166. _debug2("test: out!!!\n");
  167. return false;
  168. }
  169. //return true; //FIX!!
  170. int dec=da-start;
  171. //_debug("test: dec=%d ",dec);
  172. //_debug("%s",(d[dec/8])&(1<<(7-(dec%8)))?"oui":"non");
  173. return (d[dec/8])&(1<<(7-(dec%8)));
  174. }
  175. void setper(unsigned char *c) {
  176. memcpy(d,c,(s+7)/8);
  177. }
  178. void print() const {
  179. for(int dec=0;dec<s;dec++) {
  180. if((d[dec/8])&(1<<(7-(dec%8)))) {_debug("1");} else {_debug("0");}
  181. }
  182. _debug("\n");
  183. }
  184. bool operator!=(const per_t &p) const {return !(*this==p);}
  185. bool operator==(const per_t &p) const {
  186. if(start!=p.start || s!=p.s) return false;
  187. return 0==memcmp(d,p.d,(s+7)/8);
  188. }
  189. };
  190. class parcours_t {
  191. protected:
  192. vector<dess_t> dess; //
  193. public:
  194. parcours_t(){}
  195. parcours_t(const parcours_t &t):dess(t.dess) {}
  196. void adddess(const dess_t &d) {dess.push_back(d);}
  197. dess_t &operator[](int i) { return dess[i];}
  198. const dess_t &operator[](int i) const { return dess[i];}
  199. int size() const {return dess.size();}
  200. int posgare(int g) const {
  201. int i=0;
  202. vector<dess_t>::const_iterator it;
  203. for(it=dess.begin();it!=dess.end();++it,++i)
  204. if(it->gare==g)
  205. return i;
  206. return -1;
  207. }
  208. bool cutb(int g) {
  209. vector<dess_t>::iterator it=dess.begin(),it2;
  210. while(it!=dess.end() && it->gare!=g) {
  211. it2=it;
  212. it2++;
  213. dess.erase(it);
  214. }
  215. if(it!=dess.end()) {
  216. //it->arriv+=it->arret;
  217. //it->arret=0;
  218. }
  219. return true;
  220. }
  221. bool cuta(int g) {
  222. vector<dess_t>::iterator it,it2;
  223. for(it=dess.begin();it!=dess.end();++it)
  224. if(it->gare==g) {
  225. //it->arret=0;
  226. it2=it;it2++;
  227. if(it2==dess.end()) return false;
  228. while(it2!=dess.end()) {
  229. dess.erase(it2);
  230. it2=it;
  231. it2++;
  232. }
  233. return true;
  234. }
  235. }
  236. void decale(int dec) {
  237. vector<dess_t>::iterator it;
  238. for(it=dess.begin();it!=dess.end();++it) {
  239. it->arriv+=dec;
  240. }
  241. }
  242. bool insertp(parcours_t *t) {
  243. vector<dess_t>::iterator it=dess.begin(),it2=t->dess.begin(),it3=t->dess.end();
  244. it3--;
  245. if(it->gare==it3->gare) {
  246. if((it->arriv+it->arret)!=(it3->arriv+it3->arret)
  247. && (it->arriv)!=(it3->arriv)) {
  248. _warn("insert: heures discordantes (1) %s %d, %s %d\n",it->arriv.str().c_str(),it->arret,it3->arriv.str().c_str(),it3->arret);
  249. }
  250. dess.insert(it,it2,it3);
  251. return true;
  252. }
  253. for(;it!=dess.end();++it) {
  254. if(it->gare==t->dess[0].gare) {
  255. if((it->arriv+it->arret)!=(it2->arriv+it2->arret)
  256. &&(it->arriv)!=(it2->arriv)) {
  257. _warn("insert: heures discordantes (2) g=%d %s %d, %s %d\n",it->gare,it->arriv.str().c_str(),it->arret,it2->arriv.str().c_str(),it2->arret);
  258. }
  259. ++it;
  260. if(it!=dess.end() && it->gare==it3->gare)
  261. it3--;
  262. it3++;
  263. dess.insert(it,it2,it3);
  264. return true;
  265. }
  266. }
  267. _warn("insert: impossible\n");
  268. return false;
  269. }
  270. protected:
  271. static int cmptrajet(const parcours_t &t1,vector<dess_t>::const_iterator it1,const parcours_t &t2,vector<dess_t>::const_iterator it2,bool cmpheure=true) {
  272. if(it1==t1.dess.end()) {
  273. if(it2==t2.dess.end())
  274. return 0;
  275. else
  276. return 1;
  277. }
  278. if(it2==t2.dess.end())
  279. return -1;
  280. if(it1->gare<it2->gare) return 1;
  281. if(it1->gare>it2->gare) return -1;
  282. if(cmpheure) {
  283. if(it1->arriv<it2->arriv) return 1;
  284. if(it1->arriv>it2->arriv) return -1;
  285. if(it1->arret<it2->arret) return 1;
  286. if(it1->arret>it2->arret) return -1;
  287. }
  288. ++it1;++it2;
  289. return cmptrajet(t1,it1,t2,it2,cmpheure);
  290. }
  291. public:
  292. int cmptrajet(const parcours_t &t) const {
  293. return cmptrajet(*this,this->dess.begin(),t,t.dess.begin(),true);
  294. }
  295. };
  296. class train_t : public parcours_t {
  297. protected:
  298. per_t *per; // -> short ?
  299. //int pid_;
  300. string sid;
  301. int id;
  302. char type;
  303. bool special_;
  304. public:
  305. train_t():per(NULL),special_(false) {}
  306. train_t(const train_t&t):parcours_t(t),per(t.per),sid(t.sid),id(t.id),type(t.type),special_(false) {}
  307. void setsid(const string &s) { sid=s; /*...*/}
  308. string getsid() const { return sid; }
  309. string gettypename(const map<char,string> &m) const {
  310. if(sid.size()==0) return "";
  311. map<char,string>::const_iterator it=m.find(sid[0]);
  312. if(it!=m.end()) return it->second;
  313. return "";
  314. }
  315. string getname(const map<char,string> &m) const {
  316. return gettypename(m)+" " +getsid();
  317. }
  318. void setper(per_t *p) {per=p;}
  319. const per_t *getper() const {return per;}
  320. bool test(const date_t &d) const {
  321. //return true;///FIX
  322. if(!per) return false;
  323. return per->test(d);
  324. }
  325. // si le train est spécial, il ne s'agit pas d'un train existant directement dans la BD (par exemple les passages entre les gares de paris)
  326. void setspecial(bool s=true) { special_=s; }
  327. bool isspecial() const { return special_;}
  328. void insert2(train_t *t) {
  329. parcours_t::insertp(t);
  330. }
  331. void insert2(train_t *t,int g1) {
  332. train_t t1=*t;
  333. t1.cuta(g1);
  334. if(t1.size()>1) insert2(&t1);
  335. t1=*t;
  336. t1.cutb(g1);
  337. if(t1.size()>1) insert2(&t1);
  338. }
  339. void insert(train_t *t,int g1,int g2) {
  340. //if(t->per!=per) {_warn("train::insert: periodes discordantes\n");}
  341. // calcul decalage
  342. int dec=0;
  343. int p=posgare(g1);
  344. int p2=t->posgare(g1);
  345. printf("g1=%d p=%d p2=%d\n",g1,p,p2);
  346. if(p>=0 && p2>=0) dec=(*this)[p].arriv-(*t)[p2].arriv;
  347. else {
  348. p=posgare(g2);
  349. p2=t->posgare(g2);
  350. printf("g2=%d p=%d p2=%d\n",g2,p,p2);
  351. if(p>=0 && p2>=0) dec=(*this)[p].arriv-(*t)[p2].arriv;
  352. else _warn("train::insert erreur dec\n");
  353. }
  354. printf("dec=%d\n",dec); //beurk !
  355. if(dec<12*60 && dec>-12*60) dec=0;
  356. if(dec>=12*60) {dec=1440;t->decale(1440);}
  357. if(dec<=-12*60) {
  358. dec=-1440;
  359. //là ca chie... il faut décaler tout le train en +24h ?
  360. decale(1440);
  361. per=t->per; //décale la période: remplace per par t->per
  362. }
  363. printf("dec'=%d\n",dec); //beurk !
  364. train_t t1=*t;
  365. t1.cuta(g2);
  366. if(t1.size()>1) insert2(&t1,g1);
  367. t1=*t;
  368. t1.cutb(g2);
  369. if(t1.size()>1) insert2(&t1,g1);
  370. delete t;
  371. }
  372. #if 0
  373. public:
  374. int cmptrajet(const train_t &t) const {
  375. return cmptrajet(*this,this->dess.begin(),t,t.dess.begin(),true);
  376. }
  377. // pour tests:
  378. int pid() const {return pid_;}
  379. void setpid(int i) { pid_=i;}
  380. #endif
  381. };
  382. struct sfic2_t { int a,b,c,x,y,z; };
  383. class db_t {
  384. public:
  385. date_t dbstart,dbend;
  386. int dbnbrjours;
  387. bool test(const date_t &d) const { return d>=dbstart && d<dbend; }
  388. //gare_t *findgare(int i) {return NULL; }
  389. gares_t *gares;
  390. map<int,train_t*> _train;
  391. map<string,int> _idtrain;
  392. set<per_t*> per;
  393. int newidtrain() {
  394. static int idtrain_auto=0;
  395. return idtrain_auto++;
  396. }
  397. const train_t *gettrain(int i) const {
  398. map<int,train_t*>::const_iterator it=_train.find(i);
  399. if(it==_train.end()) return NULL;
  400. return it->second;
  401. }
  402. const train_t *gettrain(const string &s) const {
  403. map<string,int>::const_iterator it=_idtrain.find(s);
  404. if(it==_idtrain.end()) return NULL;
  405. return gettrain(it->second);
  406. }
  407. string trainstring(int i) const {
  408. const train_t *t=gettrain(i);
  409. if(t==NULL) return "NULL";
  410. return t->getsid();
  411. }
  412. db_t(gares_t &g){gares=&g;}
  413. void setper(date_t d, int n) {dbstart=d;dbend=d+n;dbnbrjours=n;}
  414. void printtrain(const train_t *t) const {
  415. _log("train %s\n",t->getsid().c_str());
  416. for(int i=0;i<t->size();i++) {
  417. _log("%s\t: %s %s\n",gares->garestring((*t)[i].gare).c_str(),(*t)[i].arriv.str().c_str(),((*t)[i].arriv+(*t)[i].arret).str().c_str());
  418. }
  419. }
  420. map<int,int> gareid_;
  421. map<int,train_t*> train_;
  422. map<int,per_t*> per_;
  423. void printstat() {
  424. _log("%d gares ,%d trains, %d periodes\n",gares->_gare.size(),_train.size(),per.size());
  425. int de=0;
  426. int arcs=0;
  427. map<int,train_t*>::const_iterator it;
  428. int nbrt=0;
  429. for(it=_train.begin();it!=_train.end();++it) {
  430. train_t *t=it->second;
  431. if(t) {
  432. nbrt++;
  433. de+=it->second->size();
  434. arcs+=it->second->size()*(it->second->size()-1);
  435. }
  436. }
  437. _log("%d vrais trains\n",nbrt);
  438. _log("%d dessertes, %d acrs\n",de,arcs);
  439. }
  440. };
  441. class dbs_t {
  442. public:
  443. list<db_t*> dbs;
  444. gares_t gares;
  445. map<int,map<int,int> > pass;
  446. map<int, list<int> > super;
  447. set<int> ssuper;
  448. bool issuper(int a,int b) const {
  449. if(a==b) return true;
  450. set<int>::const_iterator it=ssuper.find(a*MAXGARES+b);
  451. return it!=ssuper.end();
  452. }
  453. void addsuper(int a,int b) {
  454. super[a].push_back(b);
  455. ssuper.insert(a*MAXGARES+b);
  456. }
  457. map<char,string> types;
  458. dbs_t() {}
  459. /*
  460. void inclevelgares() {
  461. gares.nbrgareszero();
  462. list<db_t*>::iterator it;
  463. for(it=dbs.begin();it!=dbs.end();++it)
  464. inclevelgares(**it);
  465. gares.inclevelgares();
  466. }
  467. */
  468. /*
  469. void inclevelgares(db_t &db) {
  470. map<int,train_t*>::const_iterator it;
  471. for(it=db._train.begin();it!=db._train.end();++it) {
  472. for(int i=0;i<it->second->size();i++) {
  473. printf("%d: %d\n",i,(*(it->second))[i].gare);
  474. gares._gare[(*(it->second))[i].gare]->nbrtrains++;
  475. }
  476. }
  477. }
  478. */
  479. void add(db_t &db) {
  480. dbs.push_back(&db);
  481. }
  482. db_t *getdb(const date_t &d) {
  483. list<db_t*>::iterator it;
  484. for(it=dbs.begin();it!=dbs.end();it++)
  485. if((*it)->test(d)) return *it;
  486. return NULL;
  487. }
  488. const db_t *getdb(const date_t &d) const {
  489. list<db_t*>::const_iterator it;
  490. for(it=dbs.begin();it!=dbs.end();it++)
  491. if((*it)->test(d)) return *it;
  492. return NULL;
  493. }
  494. list<const train_t*> gettrains(const string &s) const {
  495. list<db_t*>::const_iterator it;
  496. list<const train_t*> r;
  497. for(it=dbs.begin();it!=dbs.end();it++) {
  498. const train_t *t=(*it)->gettrain(s);
  499. if(t) r.push_back(t);
  500. }
  501. return r;
  502. }
  503. };
  504. #endif