/horails/db.hpp
C++ Header | 586 lines | 466 code | 82 blank | 38 comment | 86 complexity | deae1087831abd38a9e9b7ba98e8bce4 MD5 | raw file
- #ifndef _DB_HPP_
- #define _DB_HPP_
- #include "dateheure.hpp"
- #include "utils.hpp"
- #define MAXGARES 65536
- class gare_t {
- public:
- gare_t(int gid,const string &s,int i):id(i),code(gid),name(s),level(0),nbrtrains(0) {names.push_back(s);}
- int id;
- int getid() const {return id;}
- int code;
-
- string name;
- list<string> names;
- bool addname(const string &s) {
- list<string>::const_iterator it;
- for(it=names.begin();it!=names.end() && (*it)!=s;++it);
- if(it!=names.end()) return false;
- names.push_back(s);
- return true;
- }
-
- int level;
- int nbrtrains;
- };
- class gares_t {
- int newidgare() {
- static int idgare_auto=1;
- return idgare_auto++;
- }
- static int distance(const char *a,const char *b)
- {
- int la=strlen(a);
- int lb=strlen(b);
- int dd[(la+1)*(lb+1)];
- #define min3(a,b,c) ((a)<=(b)?(a)<=(c)?(a):(c):(b)<=(c)?(b):(c))
- #define DD(i,j) dd[(i)*(lb+1)+(j)]
- int i,j;
- for(j=0;j<=lb;j++) DD(la,j)=(j==lb?0:1);
- for(i=0;i<=la;i++) DD(i,lb)=la-i;
- for(i=la-1;i>=0;i--)
- for(j=lb-1;j>=0;j--)
- DD(i,j)=1+min3(DD(i+1,j),DD(i,j+1),DD(i+1,j+1)-(a[i]==b[j]?1:0));
- return DD(0,0);
- #undef DD
- #undef max3
- }
- public:
- map<int,gare_t*> _gare; //map sur id pour dess
- map<string,int> _strgare;
- map<int,int> _idgare; // map sur code->id
- void levelzero() {
- map<int,gare_t*>::iterator it=_gare.begin();
- for(;it!=_gare.end();++it) { it->second->level=0;}
- }
- void nbrgareszero() {
- map<int,gare_t*>::iterator it=_gare.begin();
- for(;it!=_gare.end();++it) { it->second->nbrtrains=0;}
- }
- void inclevelgares() {
- map<int,gare_t*>::iterator it=_gare.begin();
- for(;it!=_gare.end();++it) { /*printf("%d\n",it->second->nbrtrains);*/if(it->second->nbrtrains) it->second->level++;}
- }
- int add(int code,const string &name) {
- int gidd=_idgare[code];
- int gidd_=_strgare[name];
- if(gidd_ && gidd!=gidd_)
- _warn("gare %s deja %d!=%d\n",name.c_str(),gidd_,gidd);
- if(gidd==0) {
- gidd=newidgare();
- gare_t *g=new gare_t(code,name,gidd);
- _gare[gidd]=g;
- _idgare[code]=gidd;
- _strgare[name]=gidd;
- } else {
- gare_t *g=_gare[gidd];
- g->addname(name);
- _strgare[name]=gidd;
- }
- return gidd;
- }
- int getlevel(int i) const {
- const gare_t *g=getgare(i);
- if(g==NULL) return 0;
- return g->level;
- }
- const gare_t *getgare(int i) const {
- map<int,gare_t*>::const_iterator it=_gare.find(i);
- if(it==_gare.end()) return NULL;
- return it->second;
- }
-
- string garestring(int i) const {
- const gare_t *t=getgare(i);
- if(t==NULL) return "NULL";
- return t->name;
- }
- static string normalize(const string &s) {
- return stripspaces(capital(s));
- }
-
- int searchexact(const string &s) const {
- string ss=normalize(s);
- //printf("'%s'\n",ss.c_str());
- map<string,int>::const_iterator it=_strgare.find(ss);
- if(it!=_strgare.end()) return it->second;
- return 0;
- }
-
- //list<int> search(const string &s) const {}
- struct lala_t {
- int d;
- string s;
- bool operator<(const lala_t&o) const {
- return o.d<d;
- }
- };
-
- list<string> searchstr(const string &s, int max=30) const {
- string s2=normalize(s);
- priority_queue<lala_t> res;
- map<string,int>::const_iterator it;
- list<string> res2;
- for(it=_strgare.begin();it!=_strgare.end();it++) {
- lala_t r;
- r.d=distance(s2.c_str(),it->first.c_str());
- r.s=it->first;
- res.push(r);
- }
- while(!res.empty() && max>0) {
- lala_t r=res.top();res.pop();
- printf("%d: '%s'\n",r.d,r.s.c_str());
- res2.push_back(r.s);
- max--;
- }
- return res2;
- }
-
- string searchbest(const string &s) const {
- list<string> l=searchstr(s,1);
- return l.front();
- }
-
- int searchidbest(const string &s) const {
- string l=searchbest(s);
- return searchexact(l);
- }
- };
- class dess_t {
- public:
- dess_t(const heure_t &ha,int a,int bb):gare(bb),arriv(ha),arret(a) {}
- short gare;
- heure_t arriv; //-> temps ?
- short arret;
- //bool second;
- };
- class per_t {
- date_t start,end;
- int s;
- unsigned char *d;
- string text;
- bool all;
- public:
- per_t(bool a=true):d(NULL),all(a) {}
- per_t(const date_t &da,int ss):start(da),end(da+ss),s(ss),d(NULL),all(false) {
- d=new unsigned char[(s+7)/8];
- bzero(d,(s+7)/8);
- }
- ~per_t() {delete d;}
- bool test(const date_t &da) const {
- //_debug("test: start=%s end=%s s=%d da=%s\n",start.str().c_str(),end.str().c_str(),s,da.str().c_str());
- if(all) return true;
- if(start>da || da>=end) {
- _debug2("test: out!!!\n");
- return false;
- }
- //return true; //FIX!!
- int dec=da-start;
- //_debug("test: dec=%d ",dec);
- //_debug("%s",(d[dec/8])&(1<<(7-(dec%8)))?"oui":"non");
- return (d[dec/8])&(1<<(7-(dec%8)));
- }
- void setper(unsigned char *c) {
- memcpy(d,c,(s+7)/8);
- }
- void print() const {
- for(int dec=0;dec<s;dec++) {
- if((d[dec/8])&(1<<(7-(dec%8)))) {_debug("1");} else {_debug("0");}
- }
- _debug("\n");
- }
- bool operator!=(const per_t &p) const {return !(*this==p);}
- bool operator==(const per_t &p) const {
- if(start!=p.start || s!=p.s) return false;
- return 0==memcmp(d,p.d,(s+7)/8);
- }
- };
- class parcours_t {
- protected:
- vector<dess_t> dess; //
- public:
- parcours_t(){}
- parcours_t(const parcours_t &t):dess(t.dess) {}
- void adddess(const dess_t &d) {dess.push_back(d);}
- dess_t &operator[](int i) { return dess[i];}
- const dess_t &operator[](int i) const { return dess[i];}
- int size() const {return dess.size();}
- int posgare(int g) const {
- int i=0;
- vector<dess_t>::const_iterator it;
- for(it=dess.begin();it!=dess.end();++it,++i)
- if(it->gare==g)
- return i;
- return -1;
- }
- bool cutb(int g) {
- vector<dess_t>::iterator it=dess.begin(),it2;
- while(it!=dess.end() && it->gare!=g) {
- it2=it;
- it2++;
- dess.erase(it);
- }
- if(it!=dess.end()) {
- //it->arriv+=it->arret;
- //it->arret=0;
- }
- return true;
- }
- bool cuta(int g) {
- vector<dess_t>::iterator it,it2;
- for(it=dess.begin();it!=dess.end();++it)
- if(it->gare==g) {
- //it->arret=0;
- it2=it;it2++;
- if(it2==dess.end()) return false;
- while(it2!=dess.end()) {
- dess.erase(it2);
- it2=it;
- it2++;
- }
- return true;
- }
- }
-
- void decale(int dec) {
- vector<dess_t>::iterator it;
- for(it=dess.begin();it!=dess.end();++it) {
- it->arriv+=dec;
- }
- }
- bool insertp(parcours_t *t) {
- vector<dess_t>::iterator it=dess.begin(),it2=t->dess.begin(),it3=t->dess.end();
- it3--;
- if(it->gare==it3->gare) {
- if((it->arriv+it->arret)!=(it3->arriv+it3->arret)
- && (it->arriv)!=(it3->arriv)) {
- _warn("insert: heures discordantes (1) %s %d, %s %d\n",it->arriv.str().c_str(),it->arret,it3->arriv.str().c_str(),it3->arret);
- }
- dess.insert(it,it2,it3);
- return true;
- }
- for(;it!=dess.end();++it) {
- if(it->gare==t->dess[0].gare) {
- if((it->arriv+it->arret)!=(it2->arriv+it2->arret)
- &&(it->arriv)!=(it2->arriv)) {
- _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);
- }
- ++it;
- if(it!=dess.end() && it->gare==it3->gare)
- it3--;
- it3++;
- dess.insert(it,it2,it3);
- return true;
- }
- }
- _warn("insert: impossible\n");
- return false;
- }
- protected:
- 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) {
- if(it1==t1.dess.end()) {
- if(it2==t2.dess.end())
- return 0;
- else
- return 1;
- }
- if(it2==t2.dess.end())
- return -1;
- if(it1->gare<it2->gare) return 1;
- if(it1->gare>it2->gare) return -1;
- if(cmpheure) {
- if(it1->arriv<it2->arriv) return 1;
- if(it1->arriv>it2->arriv) return -1;
- if(it1->arret<it2->arret) return 1;
- if(it1->arret>it2->arret) return -1;
- }
- ++it1;++it2;
- return cmptrajet(t1,it1,t2,it2,cmpheure);
- }
-
- public:
- int cmptrajet(const parcours_t &t) const {
- return cmptrajet(*this,this->dess.begin(),t,t.dess.begin(),true);
- }
- };
- class train_t : public parcours_t {
-
- protected:
- per_t *per; // -> short ?
- //int pid_;
- string sid;
- int id;
- char type;
- bool special_;
- public:
- train_t():per(NULL),special_(false) {}
- train_t(const train_t&t):parcours_t(t),per(t.per),sid(t.sid),id(t.id),type(t.type),special_(false) {}
- void setsid(const string &s) { sid=s; /*...*/}
- string getsid() const { return sid; }
- string gettypename(const map<char,string> &m) const {
- if(sid.size()==0) return "";
- map<char,string>::const_iterator it=m.find(sid[0]);
- if(it!=m.end()) return it->second;
- return "";
- }
- string getname(const map<char,string> &m) const {
- return gettypename(m)+" " +getsid();
- }
- void setper(per_t *p) {per=p;}
- const per_t *getper() const {return per;}
- bool test(const date_t &d) const {
- //return true;///FIX
- if(!per) return false;
- return per->test(d);
- }
- // 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)
- void setspecial(bool s=true) { special_=s; }
- bool isspecial() const { return special_;}
- void insert2(train_t *t) {
- parcours_t::insertp(t);
- }
-
- void insert2(train_t *t,int g1) {
- train_t t1=*t;
- t1.cuta(g1);
- if(t1.size()>1) insert2(&t1);
- t1=*t;
- t1.cutb(g1);
- if(t1.size()>1) insert2(&t1);
- }
-
- void insert(train_t *t,int g1,int g2) {
- //if(t->per!=per) {_warn("train::insert: periodes discordantes\n");}
- // calcul decalage
- int dec=0;
- int p=posgare(g1);
- int p2=t->posgare(g1);
- printf("g1=%d p=%d p2=%d\n",g1,p,p2);
- if(p>=0 && p2>=0) dec=(*this)[p].arriv-(*t)[p2].arriv;
- else {
- p=posgare(g2);
- p2=t->posgare(g2);
- printf("g2=%d p=%d p2=%d\n",g2,p,p2);
- if(p>=0 && p2>=0) dec=(*this)[p].arriv-(*t)[p2].arriv;
- else _warn("train::insert erreur dec\n");
- }
-
- printf("dec=%d\n",dec); //beurk !
- if(dec<12*60 && dec>-12*60) dec=0;
- if(dec>=12*60) {dec=1440;t->decale(1440);}
- if(dec<=-12*60) {
- dec=-1440;
- //là ca chie... il faut décaler tout le train en +24h ?
- decale(1440);
- per=t->per; //décale la période: remplace per par t->per
- }
- printf("dec'=%d\n",dec); //beurk !
-
- train_t t1=*t;
- t1.cuta(g2);
- if(t1.size()>1) insert2(&t1,g1);
- t1=*t;
- t1.cutb(g2);
- if(t1.size()>1) insert2(&t1,g1);
- delete t;
- }
- #if 0
- public:
- int cmptrajet(const train_t &t) const {
- return cmptrajet(*this,this->dess.begin(),t,t.dess.begin(),true);
- }
- // pour tests:
- int pid() const {return pid_;}
- void setpid(int i) { pid_=i;}
- #endif
- };
-
- struct sfic2_t { int a,b,c,x,y,z; };
- class db_t {
- public:
- date_t dbstart,dbend;
- int dbnbrjours;
- bool test(const date_t &d) const { return d>=dbstart && d<dbend; }
-
- //gare_t *findgare(int i) {return NULL; }
- gares_t *gares;
- map<int,train_t*> _train;
- map<string,int> _idtrain;
-
- set<per_t*> per;
-
- int newidtrain() {
- static int idtrain_auto=0;
- return idtrain_auto++;
- }
-
- const train_t *gettrain(int i) const {
- map<int,train_t*>::const_iterator it=_train.find(i);
- if(it==_train.end()) return NULL;
- return it->second;
- }
-
- const train_t *gettrain(const string &s) const {
- map<string,int>::const_iterator it=_idtrain.find(s);
- if(it==_idtrain.end()) return NULL;
- return gettrain(it->second);
- }
-
- string trainstring(int i) const {
- const train_t *t=gettrain(i);
- if(t==NULL) return "NULL";
- return t->getsid();
- }
- db_t(gares_t &g){gares=&g;}
-
- void setper(date_t d, int n) {dbstart=d;dbend=d+n;dbnbrjours=n;}
-
- void printtrain(const train_t *t) const {
- _log("train %s\n",t->getsid().c_str());
- for(int i=0;i<t->size();i++) {
- _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());
- }
- }
- map<int,int> gareid_;
- map<int,train_t*> train_;
- map<int,per_t*> per_;
-
- void printstat() {
- _log("%d gares ,%d trains, %d periodes\n",gares->_gare.size(),_train.size(),per.size());
- int de=0;
- int arcs=0;
- map<int,train_t*>::const_iterator it;
- int nbrt=0;
- for(it=_train.begin();it!=_train.end();++it) {
- train_t *t=it->second;
- if(t) {
- nbrt++;
- de+=it->second->size();
- arcs+=it->second->size()*(it->second->size()-1);
- }
- }
- _log("%d vrais trains\n",nbrt);
- _log("%d dessertes, %d acrs\n",de,arcs);
- }
-
- };
- class dbs_t {
- public:
- list<db_t*> dbs;
- gares_t gares;
- map<int,map<int,int> > pass;
-
- map<int, list<int> > super;
- set<int> ssuper;
- bool issuper(int a,int b) const {
- if(a==b) return true;
- set<int>::const_iterator it=ssuper.find(a*MAXGARES+b);
- return it!=ssuper.end();
- }
- void addsuper(int a,int b) {
- super[a].push_back(b);
- ssuper.insert(a*MAXGARES+b);
- }
- map<char,string> types;
-
- dbs_t() {}
- /*
- void inclevelgares() {
- gares.nbrgareszero();
- list<db_t*>::iterator it;
- for(it=dbs.begin();it!=dbs.end();++it)
- inclevelgares(**it);
- gares.inclevelgares();
- }
- */
- /*
- void inclevelgares(db_t &db) {
- map<int,train_t*>::const_iterator it;
- for(it=db._train.begin();it!=db._train.end();++it) {
- for(int i=0;i<it->second->size();i++) {
- printf("%d: %d\n",i,(*(it->second))[i].gare);
- gares._gare[(*(it->second))[i].gare]->nbrtrains++;
- }
- }
- }
- */
- void add(db_t &db) {
- dbs.push_back(&db);
- }
-
- db_t *getdb(const date_t &d) {
- list<db_t*>::iterator it;
- for(it=dbs.begin();it!=dbs.end();it++)
- if((*it)->test(d)) return *it;
- return NULL;
- }
-
- const db_t *getdb(const date_t &d) const {
- list<db_t*>::const_iterator it;
- for(it=dbs.begin();it!=dbs.end();it++)
- if((*it)->test(d)) return *it;
- return NULL;
- }
- list<const train_t*> gettrains(const string &s) const {
- list<db_t*>::const_iterator it;
- list<const train_t*> r;
- for(it=dbs.begin();it!=dbs.end();it++) {
- const train_t *t=(*it)->gettrain(s);
- if(t) r.push_back(t);
- }
- return r;
- }
- };
- #endif