#include "StdAfx.h"
#include "mapmatrix.h"
#include "_log.h"
#include <math.h>

//*************************************************************************************
BOOL CmapMatFloat::lee( char *path, char *ext, BOOL mismosvect/*=TRUE*/)
{
	BOOL mal=FALSE;
	for(int ic=0; ic<(int)dat.size() && !mal; ic++)
	{
		if(!dat[ic].lee(ic,path,ext,(int)dat.size(),mismosvect))
			mal=TRUE;
	}

	return !mal;
}
//*************************************************************************************
BOOL CmapRowFloat::guarda(HeadCostConj hd, int ic, char *path , char *ext, Cgarray<MapDataFloat> *bufer)
{
	HANDLE hfile = INVALID_HANDLE_VALUE;
	int nb, i;
	char file[MAX_PATH];
	
	sprintf_s(file,MAX_PATH,"%s%06d.%s",path,ic,ext);
	//crea archivo-----------------------------------
	hfile = CreateFile(file,  GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
	if (hfile == INVALID_HANDLE_VALUE)
	{
		i=GetLastError();
		return FALSE;
	}
	//graba cabecera------------
	hd.isVect=isVect;
	if(isVect)
	{
		hd.n=(int)datv.size();
	}
	else
	{
		hd.n=(int)dat.size();
	}
	nb = sizeof(hd);
	if (nb != _lwrite((int)hfile, (LPCCH)&hd, nb))
	{
		goto va_mal;
	}

	if(isVect)
	{	
		//guarda las componentes del vector
		nb=sizeof(float);
		for(i=0;i<hd.n;i++)
		{
			if (nb != _lwrite((int)hfile, (LPCCH) &datv[i], nb))
			{
				break;
			}
		}
		if(i<hd.n)
			goto va_mal;
	}
	else
	{
		Cgarray<MapDataFloat> auxbuf;
		Cgarray<MapDataFloat> *buff;
		if(bufer)
			buff = bufer;
		else
			buff = &auxbuf;
		int nbufer= min(hd.n,1000);
		if(!((*buff)+=nbufer))
		{
			goto va_mal;
		}
		buff->n = nbufer;
		//guarda componente a componente del map
		int ii = 0;
		for (std::map<int, float>::iterator it=dat.begin(); it!=dat.end(); ++it)
		{
			//int aux = it->first;
			(*buff)[ii].k =it->first;
			(*buff)[ii].v =it->second;
			ii++;
			if(ii>=buff->n)
			{
				nb = buff->n*sizeof(MapDataFloat);
				if (nb != _lwrite((int)hfile, (LPCCH) buff->ptr, nb))
				{
					goto va_mal;
				}
				ii =0;
			}
			
		}
		if(ii>0)
		{
			nb = ii*sizeof(MapDataFloat);
			if (nb != _lwrite((int)hfile, (LPCCH) buff->ptr, nb))
			{
				goto va_mal;
			}
		}
	}

	CloseHandle(hfile);
	return TRUE;

va_mal:
	CloseHandle(hfile);
	return FALSE;
}
//*************************************************************************************
//ntot solo se usa cuando es map y pasa a vector, porque se necesita cuántos elementos en total tiene que haber
BOOL CmapRowFloat::lee(int ic, char *path , char *ext, int ntot, BOOL mismosvect/*=TRUE*/,  Cgarray<MapDataFloat> *bufer/* = NULL*/)
{
	HANDLE hfile = INVALID_HANDLE_VALUE;
	int nb, i;
	char file[MAX_PATH];
	HeadCostConj hd;
	Cgarray<MapDataFloat> buffaux;

	sprintf_s(file,MAX_PATH,"%s%06d.%s",path,ic,ext);
	//crea archivo-----------------------------------
	hfile = CreateFile(file,  GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
	if (hfile == INVALID_HANDLE_VALUE)
	{
		i=GetLastError();
		return FALSE;
	}

	//lee cabecera------------
	memset(&hd,0,sizeof(HeadCostConj));
	nb = sizeof(hd);
	if (nb != _lread((int)hfile,&hd, nb))
	{
		goto va_mal;
	}
	if(mismosvect)
		isVect=hd.isVect;

	int j=0;
	float d=0;
	nb=sizeof(float);
	dat.clear();		
	datv.clear();

	Cgarray<MapDataFloat> *buff;
	if(bufer)
	{
		bufer->n=0;
		buff = bufer;
	}
	else
		buff =&buffaux;
	int nbufer= min(hd.n,1000);

	if(hd.isVect)
	{	
		if(isVect)
		{
			//vector a vector
			datv.reserve(hd.n);
			/*for (int i = 0; i<hd.n; i++)
			{
				int nad = min(5000, hd.n-i);
				datv.insert(datv.end(),nad,VALNOEXIST_FLOAT);
				i+=nad;
			}*/
			datv.insert(datv.begin(),hd.n,VALNOEXIST_FLOAT);
		
			if (sizeof(float)*hd.n != _lread((int)hfile,&datv[0], sizeof(float)*hd.n))
				goto va_mal;
		}
		else
		{
			//vector a map
			if(!((*buff)+=nbufer))
			{
				goto va_mal;
			}

			//lee componente a componente del map
			int nl =0;
			int nn = 0;			
			for(int i=0;i<hd.n;i+=nn)
			{			
				nn = min(nbufer,hd.n-nl);
				nb = sizeof(float)*nn;
				if (nb != _lread((int)hfile,buff->ptr, nb))
					break;

				for(int ii =0; ii<nn; ii++)
					set(i+ii,((float*)buff->ptr)[ii]);

				nl+=nn;
			}	
		}
	}
	else
	{	
		if(!((*buff)+=nbufer))
		{
			goto va_mal;
		}
		buff->n=0;
		
		//lee componente a componente del map
		int nl =0;
		int nn = 0;
		if(isVect)
			datv.insert(datv.begin(),ntot,VALNOEXIST_FLOAT); 

		for(int i=0;i<hd.n;i+=nn)
		{			
			nn = min(nbufer,hd.n-nl);
			nb = sizeof(MapDataFloat)*nn;
			if (nb != _lread((int)hfile,buff->ptr, nb))
				break;

			for(int ii =0; ii<nn; ii++)
				set((*buff)[ii].k,(*buff)[ii].v);
			
			nl+=nn;
		}		
	}

	CloseHandle(hfile);
	return TRUE;

va_mal:
	CloseHandle(hfile);
	return FALSE;
}
//*************************************************************************************
BOOL CmapRowInt::guarda(HeadCostConj hd, int ic, char *path , char *ext)
{
	HANDLE hfile = INVALID_HANDLE_VALUE;
	int nb, i;
	char file[MAX_PATH];

	sprintf_s(file,MAX_PATH,"%s%06d.%s",path,ic,ext);
	//crea archivo-----------------------------------
	hfile = CreateFile(file,  GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
	if (hfile == INVALID_HANDLE_VALUE)
	{
		i=GetLastError();
		return FALSE;
	}
	//graba cabecera------------
	hd.isVect=isVect;
	if(isVect)
	{
		hd.n=(int)datv.size();
	}
	else
	{
		hd.n=(int)dat.size();
	}
	nb = sizeof(hd);
	if (nb != _lwrite((int)hfile, (LPCCH)&hd, nb))
	{
		goto va_mal;
	}

	if(isVect)
	{	
		//guarda las componentes del vector
		if (datv.size()*sizeof(int) != _lwrite((int)hfile, (LPCCH) &datv[0], datv.size()*sizeof(int)))
		{
			goto va_mal;
		}
		
	}
	else
	{
		Cgarray<MapDataInt> buff;
		int nbufer= min(hd.n,1000);
		if(!(buff+=nbufer))
		{
			goto va_mal;
		}
		buff.n = nbufer;
		//guarda componente a componente del map
		int ii = 0;
		for (std::map<int, int>::iterator it=dat.begin(); it!=dat.end(); ++it)
		{
			//int aux = it->first;
			buff[ii].k=it->first;
			buff[ii].v =it->second;
			ii++;

			if(ii>=buff.n)
			{
				nb = buff.n*sizeof(MapDataInt);

				if (nb != _lwrite((int)hfile, (LPCCH) buff.ptr, nb))
				{
					goto va_mal;
				}
				ii =0;
			}
		}
		if(ii>0)
		{
			nb = ii*sizeof(MapDataInt);
			if (nb != _lwrite((int)hfile, (LPCCH) buff.ptr, nb))
			{
				goto va_mal;
			}
		}
	}

	CloseHandle(hfile);
	return TRUE;

va_mal:
	CloseHandle(hfile);
	return FALSE;
}
//*************************************************************************************
//falta optimizar al estilo CmapRowFloat
BOOL CmapRowInt::lee(int ic, char *path , char *ext, BOOL mismosvect/*=TRUE*/)
{
	HANDLE hfile = INVALID_HANDLE_VALUE;
	int nb, i;
	char file[MAX_PATH];
	HeadCostConj hd;

	sprintf_s(file,MAX_PATH,"%s%06d.%s",path,ic,ext);
	//crea archivo-----------------------------------
	hfile = CreateFile(file,  GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
	if (hfile == INVALID_HANDLE_VALUE)
	{
		i=GetLastError();
		return FALSE;
	}

	//lee cabecera------------
	memset(&hd,0,sizeof(HeadCostConj));
	nb = sizeof(hd);
	if (nb != _lread((int)hfile,&hd, nb))
	{
		goto va_mal;
	}
	if(mismosvect)
		isVect=hd.isVect;//fuerza a que donde lee sea vect o no igual que lo que lee, o no

	int j=0;
	int d=0;
	nb=sizeof(int);
	if(hd.isVect)
	{	
		//lee los componentes del vector
		for(i=0;i<hd.n;i++)
		{					
			if (nb != _lread((int)hfile,&d, nb))
				break;
			set(i,d);
		}
		if(i<hd.n)
			goto va_mal;
	}
	else
	{
		//lee componente a componente del map
		for(i=0;i<hd.n;i++)
		{					
			nb=sizeof(int);
			if (nb != _lread((int)hfile,&j, nb))
				break;
			nb=sizeof(int);
			if (nb != _lread((int)hfile,&d, nb))
				break;
			set(j,d);
		}		
	}
	if(i<hd.n)
		goto va_mal;

	CloseHandle(hfile);
	return TRUE;

va_mal:
	CloseHandle(hfile);
	return FALSE;
}
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
void ThMapMatFloatLee::run()
{
	mal = FALSE;
	C_log::log("ThMapMatFloatLee","Subthr %ld, Conjs %04d a %04d", ithr,ini, fin);

	Cgarray<MapDataFloat> buff;

	for(int ic=ini; ic<fin && !mal; ic++)
	{
		if(!(*pclas)[ic].lee(ic,path,ext,mismosvect, pclas->dat.size(),&buff))
			mal=TRUE;
	}
}
//*************************************************************************************
BOOL CmapMatFloat::leeThread( char *path, char *ext, int nthread, BOOL mismosvect/*=TRUE*/)
{
	ThMapMatFloatLee th[MAX_THREAD_LEE];
	int nth = min(nthread,MAX_THREAD_LEE);
	int n = (int)ceil(dat.size()*1./nth);
	int asig = 0;
	int i=0;
	//C_log::log("leeThread","tot %ld n %ld", dat.size(),n);
	for(i=0; i<nth && asig<(int)dat.size(); i++)
	{
		th[i].ext = ext;
		th[i].mismosvect = mismosvect;
		th[i].path = path;
		th[i].pclas = this;
		th[i].mal = FALSE;
		th[i].ithr=i;
		th[i].ini = i*n;
		th[i].fin = min((i+1)*n,(int)dat.size());
		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;
}