497 lines
13 KiB
C++
497 lines
13 KiB
C++
#include "StdAfx.h"
|
||
#include "OlvTaskProcess.h"
|
||
#include "olivia_def.h"
|
||
#include <sstream>
|
||
#include <string>
|
||
#include "olv_task.h"
|
||
|
||
#define MODULO "OlvTaskProcess"
|
||
|
||
std::string to_string(double& d)
|
||
{
|
||
char dig[256];
|
||
dig[0]=0;
|
||
return dig;
|
||
}
|
||
|
||
//*******************************************************************************************************
|
||
OlvTaskProcess::OlvTaskProcess(void)
|
||
{
|
||
costes.clear();
|
||
va_mal=FALSE;
|
||
angs=NULL;
|
||
}
|
||
OlvTaskProcess::~OlvTaskProcess( void )
|
||
{
|
||
costes.clear();
|
||
if(angs)
|
||
{
|
||
for(int i=0;i<info.n;i++)
|
||
{
|
||
angs[i].libera();
|
||
}
|
||
free(angs);
|
||
angs=NULL;
|
||
}
|
||
ia.clear();
|
||
cost_amb.clear();
|
||
}
|
||
//*******************************************************************************************************
|
||
void OlvTaskProcess::preTask()
|
||
{
|
||
//pilla informacion de socket necesaria
|
||
//el tread no esta currando
|
||
//presentacion-----------------------------------------
|
||
int aux[2];
|
||
aux[0]= PETICION_GENERAL_PRESENTA;
|
||
aux[1]=ithr;
|
||
if(!envia(aux,sizeof(aux)))
|
||
{
|
||
C_log::log(MODULO, "error al enviar presentacion");
|
||
cancela();
|
||
return;
|
||
}
|
||
int nb;
|
||
void *data = recibe(&nb);
|
||
if(nb < sizeof(int) || (*(int*)data)!=PETICION_GENERAL_OK)
|
||
{
|
||
C_log::log(MODULO, "error al recibir contestacion de presentacion");
|
||
cancela();
|
||
return;
|
||
}
|
||
data = recibe(&nb);
|
||
if(nb<sizeof(InfoIniTask))
|
||
{
|
||
C_log::log(MODULO, "error al recibir contestacion de presentacion");
|
||
cancela();
|
||
return;
|
||
}
|
||
memcpy(&info,data,sizeof(InfoIniTask));
|
||
//------------------------------------------------------
|
||
}
|
||
//*******************************************************************************************************
|
||
void OlvTaskProcess::inTask()
|
||
{
|
||
//envia sigue vivo----------------------
|
||
|
||
int aux = PETICION_GENERAL_OK;
|
||
if(!envia(&aux,sizeof(aux)))
|
||
{
|
||
C_log::log(MODULO, "error al enviar Ok");
|
||
cancela();
|
||
return;
|
||
}
|
||
int nb;
|
||
void *data = recibe(&nb);
|
||
if(nb<sizeof(int))
|
||
{
|
||
C_log::log(MODULO, "error al recibir contestacion ok");
|
||
cancela();
|
||
return;
|
||
}
|
||
//mira contstacion------------------------
|
||
switch(*(int*)data)
|
||
{
|
||
case(PETICION_GENERAL_OK):
|
||
break;
|
||
default://PETICION_GENERAL_NO
|
||
C_log::log(MODULO, "Recibida peticion de cancelacion");
|
||
cancela();
|
||
}
|
||
//envia log
|
||
enviaLog();
|
||
}
|
||
void OlvTaskProcess::enviaLog()
|
||
{
|
||
StrArray msgs;
|
||
if(OlvApp.colaLog.dame(msgs))
|
||
{
|
||
char buf[1028];
|
||
int *id =(int*) buf;
|
||
char* msg = (char*)&id[1];
|
||
*id = PETICION_GENERAL_DAME_LOG;
|
||
for (int i = 0; i<msgs.n_i; i++)
|
||
{
|
||
strcpy(msg,msgs.get(i));
|
||
|
||
if(!envia(&buf,(int)(sizeof(int)+strlen(msg)+1)))
|
||
{
|
||
C_log::log(MODULO, "error al enviar Log");
|
||
cancela();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//*******************************************************************************************************
|
||
void OlvTaskProcess::postTask()
|
||
{
|
||
enviaLog();
|
||
int aux[2];
|
||
aux[0]= PETICION_GENERAL_FIN;
|
||
if(va_mal)
|
||
{
|
||
aux[1]=PETICION_GENERAL_NO; //dependiendo del estado
|
||
}
|
||
else
|
||
{
|
||
aux[1]=PETICION_GENERAL_OK; //dependiendo del estado
|
||
C_log::log(MODULO,"Task %ld, Enviando final feliz",ithr);
|
||
|
||
}
|
||
if(!envia(aux,sizeof(aux)))
|
||
{
|
||
C_log::log(MODULO, "Task %ld, Error al enviar terminado",ithr);
|
||
cancela();
|
||
}
|
||
int nb;
|
||
void *data = recibe(&nb);
|
||
if(nb<sizeof(int)|| *(int*)data != PETICION_GENERAL_FIN)
|
||
{
|
||
C_log::log(MODULO, "Task %ld, Error al recibir fin",ithr);
|
||
}
|
||
}
|
||
//*******************************************************************************************************
|
||
void OlvTaskProcess::run()
|
||
{
|
||
//tarea a realizar
|
||
//lee archivos de costes, angulos e informacion asociada
|
||
//si !usa_angs, angs=NULL;
|
||
if(!lee_mats())
|
||
{
|
||
C_log::log(MODULO,"Task %ld,Error en lee_mats", ithr);
|
||
|
||
va_mal=TRUE;
|
||
goto sal;
|
||
}
|
||
|
||
if(!calcula_cost_ambThr())
|
||
{
|
||
C_log::log(MODULO,"Task %ld,Error en calcula_cost_amb_sub", ithr);
|
||
|
||
va_mal=TRUE;
|
||
goto sal;
|
||
}
|
||
|
||
//guarda mat de cost_amb
|
||
if(!guarda_cost_amb())
|
||
{
|
||
C_log::log(MODULO,"Task %ld,Error en guarda_cost_amb", ithr);
|
||
|
||
va_mal=TRUE;
|
||
goto sal;
|
||
}
|
||
sal:
|
||
C_log::log(MODULO, "Task de tarea saliendo %ld %s",ithr, va_mal ? "Mal" : "Bien");
|
||
|
||
}
|
||
//*******************************************************************************************************
|
||
BOOL OlvTaskProcess::calcula_cost_ambThr()
|
||
{
|
||
//inicializa archivo----------------------
|
||
char p[MAX_PATH];
|
||
BOOL mal=FALSE;
|
||
|
||
sprintf_s(p,MAX_PATH,"%s\\%s",info.path_temp,NOMB_ARCH_DIJ_DEF);
|
||
if(!arch_dj.inicia(p, TRUE,FALSE, info.n))
|
||
{
|
||
C_log::log(MODULO,"Task %ld,Error %ld no se ha podido crear ndj", ithr,GetLastError());
|
||
mal = TRUE;
|
||
goto final;
|
||
}
|
||
//C_log::log(MODULO,"sizeof %ld %ld %ld %ld", sizeof(Head_dj_arch),sizeof(Djkt_nodo), sizeof(Djkt_ids_pdr), arch_dj.sizn);
|
||
if(!arch_dj.inicia_inf_amb(&ia,info.namb,info.KK,info.id_instal, info.id_planta))
|
||
{
|
||
C_log::log(MODULO,"Task %ld,Error %ld no se ha podido crear info de ambitos", ithr,GetLastError());
|
||
mal = TRUE;
|
||
goto final;
|
||
|
||
}
|
||
//pilla memoria necesaria para coste de ambitos--------------
|
||
if(!cost_amb.inicia(info.namb,info.namb))
|
||
{
|
||
C_log::log(MODULO,"Task %ld,Error %ld no se ha podido iniciar cost_amb, sin memoria", ithr,GetLastError());
|
||
|
||
//sin memoria
|
||
mal = TRUE;
|
||
goto final;
|
||
|
||
}
|
||
for(int i = 0; i<info.namb; i++)
|
||
for(int j = 0; j<info.namb; j++)
|
||
cost_amb[i][j] = (float)MAYUSCULO;
|
||
|
||
//////////////////////////////////////
|
||
//lanza los threads
|
||
mal=lanza_thr_calc();
|
||
//////////////////////////////////////
|
||
|
||
//termina de guardar
|
||
if(!mal && !arch_dj.graba_dis(ithr))
|
||
{
|
||
C_log::log(MODULO,"Task %ld,Error %ld no se ha podido guardar la info de ambitos", ithr,GetLastError());
|
||
mal = TRUE;
|
||
}
|
||
|
||
final:
|
||
return !mal;
|
||
}
|
||
//*******************************************************************************************************
|
||
BOOL OlvTaskProcess::lanza_thr_calc()
|
||
{
|
||
ThCalcCostes th[MAX_THREAD_LEE];
|
||
int nth = min(info.nthr,MAX_THREAD_LEE);
|
||
int ntsk=(int)ceil(info.namb*1./(info.ntsks));
|
||
int n = (int)ceil(ntsk*1./(nth));
|
||
int asig = 0;
|
||
int i=0;
|
||
for(i=0; i<nth && asig<info.namb; i++)
|
||
{
|
||
th[i].ithr = i;
|
||
th[i].pclas = this;
|
||
th[i].mal = FALSE;
|
||
th[i].ini = i*n+ithr*ntsk;
|
||
th[i].fin = min((i+1)*n+ithr*ntsk,info.namb);
|
||
asig=th[i].fin;
|
||
th[i].lanza();
|
||
}
|
||
BOOL mal=FALSE;
|
||
for(int ic=0; ic<i; ic++)
|
||
{
|
||
th[ic].join();
|
||
mal|=th[ic].mal;
|
||
}
|
||
return mal;
|
||
}
|
||
//*******************************************************************************************************
|
||
void ThCalcCostes::run()
|
||
{
|
||
mal = FALSE;
|
||
if(!pclas->calcula_cost_amb_sub(ini,fin,ithr))
|
||
mal=TRUE;
|
||
}
|
||
//*******************************************************************************************************
|
||
BOOL OlvTaskProcess::calcula_cost_amb_sub(int amb_ini,int amb_fin, int ith)
|
||
{
|
||
int na,i,k;
|
||
int seg;
|
||
Djkt_nodo *costes_nodos;
|
||
BOOL mal=FALSE;
|
||
|
||
//----------------------------------------
|
||
////////////////
|
||
int na_desp = amb_fin-amb_ini;
|
||
costes_nodos=NULL;
|
||
////////////////
|
||
FlagsArray visto_ang;//buffer de flags
|
||
|
||
C_log::log(MODULO,"Subthr %ld, Ambs %04d a %04d, numero ambitos totales %ld", ith,amb_ini, amb_fin, info.namb);
|
||
|
||
seg = GetTickCount();
|
||
/////////////////////////////////////
|
||
//Bucle por cada <20>mbito de los que le tocan a este thread
|
||
/////////////////////////////////////
|
||
//el coste de un <20>mbito a s<> mismo es el de trabajar ese <20>mbito,
|
||
//que es el coste de ir de su conj inicial a la final
|
||
//na=na_ini;
|
||
/////////////////////////////////////
|
||
for(na=amb_ini;na<amb_fin && !pirate; na++)
|
||
{
|
||
//En olv_limp->ias[i].ic_ini est<73> almacenado el <20>ndice de la conjunci<63>n del nodo inicial del <20>mbito
|
||
//y en olv_limp->ias[i].ic_fin el del final. Se puede acceder con i directamente al array ias porque
|
||
//la info asociada est<73> a<>adida por orden, primero los <20>mbitos
|
||
/////////////////////////////////////////////
|
||
//calcula el coste m<>ximo del <20>mbito na a todos los dem<65>s
|
||
//los a<>ade a la fila na de la matriz de costes
|
||
//es coste m<>ximo porque hace el m<>ximo de:
|
||
//inicio(na)->inicio(ni), inicio(na)->final(ni), final(na)->inicio(ni), final(na)->final(ni)
|
||
/////////////////////////////////////////////
|
||
//k==0, calcula las distancias del nodo inicial de ese <20>mbito a todas las dem<65>s conjunciones
|
||
//k==1, calucla las distancias del nodo final
|
||
|
||
for(k=0;k<info.KK;k++)
|
||
{
|
||
costes_nodos=NULL;
|
||
if(!DijkstraUtiles::dijkstra_ang_inv_ok(costes, angs, info.n,
|
||
(1-k)*ia.get(na,0)+k*ia.get(na,1),
|
||
&costes_nodos, &visto_ang))
|
||
{
|
||
C_log::log(MODULO,"Subthr %ld,Error en dijkstra_ang_inv_ok", ith);
|
||
|
||
mal=TRUE;
|
||
break;
|
||
}
|
||
|
||
|
||
//recorre todos los dem<65>s <20>mbitos buscando el coste a ellos en el array de costes devuelto, y los almacena
|
||
//almacena el coste a su nodo inicial y a su nodo final
|
||
if(ia.getFlags(na) & OLV_LIMP_FLG_AMB_NO)
|
||
{
|
||
for (i=0; i<info.n; i++)
|
||
{
|
||
costes_nodos[i].dis=(float)MAYUSCULO;
|
||
costes_nodos[i].id_padre=-1;
|
||
costes_nodos[i].ids_ady.nady=0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for(i=0;i<info.namb;i++)
|
||
{
|
||
if(ia.getFlags(i) & OLV_LIMP_FLG_AMB_NO)
|
||
continue;
|
||
if(na==i)
|
||
{
|
||
//el coste de un <20>mbito a s<> mismo es el de trabajar ese <20>mbito
|
||
cost_amb[na][na]=costes[ia.get(na,0)][ia.get(na,1)];
|
||
continue;
|
||
}
|
||
|
||
if(cost_amb[i][na]>costes_nodos[ia.get(i,0)].dis)
|
||
cost_amb[i][na]=costes_nodos[ia.get(i,0)].dis;
|
||
if(info.KK==OLV_AMB_LIN)
|
||
{
|
||
if(cost_amb[i][na]>costes_nodos[ia.get(i,1)].dis)
|
||
cost_amb[i][na]=costes_nodos[ia.get(i,1)].dis;
|
||
}
|
||
}
|
||
}
|
||
if(!arch_dj.add_b(costes_nodos, na, k, TRUE))
|
||
{
|
||
C_log::log(MODULO,"Subthr %ld,Error %ld no se ha podido guardar dj iref: %ld k: %ld", ith,
|
||
GetLastError(),na,k);
|
||
}
|
||
}
|
||
if(mal)
|
||
break;
|
||
//avisa de progreso
|
||
if(((na-amb_ini)%20==0))
|
||
{
|
||
C_log::log(MODULO,"Subthr %ld, Rellenando matriz de dist entre ambs %ld de %ld", ith,
|
||
(na-amb_ini+1),na_desp);
|
||
|
||
}
|
||
}
|
||
|
||
if(mal || pirate)
|
||
{
|
||
C_log::log(MODULO,"Subthr %ld, Error en c<>lculo de matriz de distancias entre <20>mbitos", ith);
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
C_log::log(MODULO,"Subthr %ld, Fin Matriz de dist entre ambs, %.3f seg", ith, 1.0*(GetTickCount()-seg)/1000);
|
||
|
||
return TRUE;
|
||
|
||
/////////////////////////////////////
|
||
}
|
||
//*******************************************************************************************************
|
||
BOOL OlvTaskProcess::lee_mats()
|
||
{
|
||
//lee archivos de costes, angulos e informacion asociada
|
||
//si !usa_angs, angs=NULL;
|
||
|
||
BOOL mal=FALSE;
|
||
CoptiMemo oo(TRUE);
|
||
C_log::log(MODULO,"Task %ld, Memo disp %I64d",ithr, oo.memo);
|
||
int nvect=oo.calc_nvect_multi(info.n,info.nthr,sizeof(Djkt_elem_cola));
|
||
if(nvect<0)
|
||
{
|
||
C_log::log(MODULO,"Task %ld, Error sin memoria al calcular nvect",ithr);
|
||
goto va_mal;
|
||
}
|
||
C_log::log(MODULO,"Task %ld, Calculando con nvect %ld de %ld",ithr, nvect,info.n);
|
||
//inicializa los arrays
|
||
costes.inicializa(info.n,info.nthr,nvect);
|
||
|
||
C_log::log(MODULO,"Task %ld, Lee matriz de costes",ithr);
|
||
if(!costes.leeThread(info.path_cconj,info.ext,info.nthr,FALSE)) //el false es para forzar a que todos sean vect, que no los haga igual que los archivos
|
||
{
|
||
C_log::log(MODULO,"Task %ld, Error al leer matriz de costes: %s",ithr, info.path_cconj );
|
||
goto va_mal;
|
||
}
|
||
|
||
C_log::log(MODULO,"Task %ld, Lee matriz de angulos",ithr);
|
||
if(info.usa_angs)
|
||
{
|
||
angs = new Djkt_ang_ady[info.n];
|
||
if(!angs)
|
||
{
|
||
C_log::log(MODULO,"Task %ld, Error lee_mat sin memoria para %ld Djkt_ang_ady",ithr, info.n);
|
||
|
||
mal=TRUE;
|
||
}
|
||
for(int ic=0; ic<info.n && !mal; ic++)
|
||
{
|
||
if(!angs[ic].lee(ic,info.path_ang,info.ext))
|
||
{
|
||
C_log::log(MODULO,"Task %ld,Error en lee_mats", ithr);
|
||
|
||
mal=TRUE;
|
||
}
|
||
}
|
||
if(mal)
|
||
{
|
||
C_log::log(MODULO,"Task %ld, Error al leer matriz de angulos: %s",ithr, info.path_ang );
|
||
goto va_mal;
|
||
}
|
||
}
|
||
|
||
C_log::log(MODULO,"Task %ld, Lee informacion asociada",ithr);
|
||
if(!ia.leeFile(info.file_iaso))
|
||
{
|
||
C_log::log(MODULO,"Proceso %ld, Error al leer matriz de info aso: %s",ithr, info.file_iaso );
|
||
|
||
goto va_mal;
|
||
}
|
||
|
||
return TRUE;
|
||
|
||
va_mal:
|
||
return FALSE;
|
||
}
|
||
//*******************************************************************************************************
|
||
BOOL OlvTaskProcess::guarda_cost_amb()
|
||
{
|
||
C_log::log(MODULO,"Task %ld, Guardando costes entre ambitos",ithr);
|
||
char path[MAX_PATH];
|
||
|
||
sprintf_s(path,MAX_PATH,"%s%02d.%s",info.path_costamb,ithr,info.ext);
|
||
|
||
if(!Cdir_manager::crea_dir(info.path_costamb)||!cost_amb.graba(path))
|
||
{
|
||
C_log::log(MODULO,"Task %ld, Error al guardar matriz de costes de ambitos: %s",ithr,path);
|
||
|
||
return FALSE;
|
||
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
//*******************************************************************************************************
|
||
void OlvTaskProcess::desconecta()
|
||
{
|
||
OlvApp.isConnected = FALSE;
|
||
TaskProcess::desconecta();
|
||
}
|
||
//*******************************************************************************************************
|
||
|
||
BOOL InfoIndiceEx::leeFile( char* path )
|
||
{
|
||
Cb_file file;
|
||
dat.borra();
|
||
if(!file.abre(path,1,FALSE,TRUE))
|
||
{
|
||
C_log::log(MODULO,"Error en apertura de archivo InfoIndiceEx::leeFile: %s", path);
|
||
|
||
return false;
|
||
}
|
||
if(!dat.leer(&file))
|
||
{
|
||
C_log::log(MODULO,"Error en lectura de archivo InfoIndiceEx::leeFile: %s", path);
|
||
|
||
return false;
|
||
}
|
||
return TRUE;
|
||
}
|
||
//*******************************************************************************************************
|