/*--------------------------------------------------------------------------
   la table de hachage dr factorisation 
   la version du 27.3.91 
  -------------------------------------------------------------------------- */
#include<stdio.h>
#include MUT_H
#include LOG_H
#include"fact.h"

/* les fonction de l'utilisateurs :
   ------------------------------

   initialisation au depart des pointeurs de factor a NULL.
   Les fonctions qui utilisent le hachage peuvent renvoye DDBTABLE_PLEINE
   si la table est trop remplie.
   Il n'y a pas de destruction possible d'un element.

   a. creation de table 

   pTabFact createTabFact(len)
   int len;

   b. destruction de la table

   destroyTabFact(pTab)
   pTabFact pTab;

   c. re-allocation d'une table de hachage
   
   reAllocTabFact(pTab)
   pTabFact pTab;
   
   d. recherche d'un element

   pFact searchTabFact(pTab,g,h,r)
   pTabFact pTab;
   pNode g,h,r;

   e. ajout d'un element

   int addTabFact(pTab,g,h,r,fact)
   pTabFact pTab;
   pFact fact;
   pNode g,h,r;

   f. affichage total d'une table 

   void displayFact(pTab)
   pTabFact pTab;


*/

/*-------------------- la fonction de hachage ---------------------------- */

int hashFact(g,h,r)
pNode g ;
pFact h,r;
{
  return(abs(g->index +
             (((int) g) >> 4) + (((int) h) >> 5) + (((int) r) >> 6) + 
             (int) g + (int) h + (int) r));
}

/* la fonction de creation de table de hachage pour les Fact .
   On alloue en premier lieu une structure TABLE, puis une table
   qui n'est rien d'autre qu'un tableau de pointeurs de Fact. Il est
   donc possible de travailler avec plusieurs table a la fois. */

pTabFact createTabFact(len)
int len;
{
pTabFact pTab;
pFact fact;
int i;

pTab = (pTabFact) mbkalloc (sizeof (struct tabfactor)) ;
pTab->lenTable=len;

fact = (pFact) mbkalloc (len * sizeof(struct factor)) ;
pTab->tetFact = fact; 
for (i=0;i<len;i++) 
    {
    fact->g = (pNode)VIDE;   /* -1 */
    fact->h = (pFact)VIDE;   /* -1 */
    fact->r = (pFact)VIDE;   /* -1 */
    fact++;
    }
pTab->counter=0;
return(pTab);
}

   /* destruction d'une table de hachage */

void destroyTabFact(pTab)
pTabFact pTab;
{
#ifndef ARCHI_PC
destroyFact(pTab) ;
mbkfree(pTab) ;
#endif
}


void destroyFact(pTab)
pTabFact pTab;
{
int i ;
pFact teteFact ;

teteFact = pTab->tetFact ;
#ifndef ARCHI_PC
	mbkfree(teteFact) ;
#endif
}


  /* reallocation d'une table plus grande */ 
void reallocFact(pTab)
pTabFact pTab ;
{
pFact fact;
pTabFact newTab ;
int i;
void displayTabHashFact() ;

newTab = createTabFact(5 * (pTab->lenTable)) ;
fact = pTab->tetFact ;
for(i = 0; i<pTab->lenTable; i++)
	{
	if(fact->g != (pNode)VIDE)
		addTabFact(newTab,fact->g,fact->h,fact->r) ;
	fact++ ;
	}

mbkfree(pTab->tetFact) ;
pTab->lenTable = newTab->lenTable ;
pTab->tetFact = newTab->tetFact ;

mbkfree(newTab) ;

/*printf("taille : %d\n",pTab->lenTable) ;*/
}

pFact searchHashTabFact(pTab,g,h,r,cptr)
pTabFact pTab;
pNode g ;
pFact h,r;
int cptr ;
{
pFact factCur;
int indice;

if(cptr > NUMBER_MAX_ACCES)
	return(NULL) ;
     /* un seul acces permis */
indice = hashFact(g,h + cptr,r + cptr) % pTab->lenTable;
factCur = (pTab->tetFact)+indice;
if(factCur->g != (pNode)VIDE)
	if (g == factCur->g && h  == factCur->h && r == factCur->r)
      		return(factCur);
	else
		return(searchHashTabFact(pTab,g,h,r,cptr + 1)) ;
else
	return(NULL);
}


pFact searchTabFact(pTab,g,h,r)
pTabFact pTab;
pNode g ;
pFact h,r;
{
return(searchHashTabFact(pTab,g,h,r,0)) ;
}

pFact addHashTabFact(pTab,g,h,r,cptr)
pTabFact pTab;
pNode g ;
pFact h,r ;
int cptr ;
{
pFact factCur;
int indice;

if(cptr > NUMBER_MAX_ACCES)
	{
	/*printf("hash table is full, reallocation ....\n") ;
	printf("table size : %d, number of GF nodes : %d\n",pTab->lenTable,								 pTab->counter);*/
	reallocFact(pTab) ;
	addHashTabFact(pTab,g,h,r,0) ;
	}
     /* un seul acces permis */

indice = (hashFact(g,h + cptr,r + cptr)) % pTab->lenTable;
factCur = (pTab->tetFact)+indice;
/*printf("g : %d\n",factCur->g) ;*/
if(factCur->g == (pNode)VIDE)
	{
	factCur->g = g;
	factCur->h = h;
	factCur->r = r;
	}
else
	factCur = addHashTabFact(pTab,g,h,r,cptr + 1) ;
	
return(factCur);      /* retourne la place utilisee */
}

 /* ajout d'un element a la table */


pFact addTabFact(pTab,g,h,r)
pTabFact pTab;
pNode g ;
pFact h,r ;
{
     /* un seul acces permis */
pTab->counter++ ;
return(addHashTabFact(pTab,g,h,r,0));      /* retourne la place utilisee */
}

/*------------------------------------------------------------------------------
displayTabHashFact	: visualise la table de hashage des fact .
-------------------------------------------------------
parametres 	 	: pointeur sur la table .
-------------------------------------------------------
return 		 :rien.
------------------------------------------------------------------------------*/
void displayTabHashFact(pTab)
pTabFact pTab ;
{
int i,j  ;
pFact factCur ;

j = 0 ;
for(i = 0; i < pTab->lenTable; i++)
	{
	factCur = pTab->tetFact + i ;
	if(factCur->g != (pNode)VIDE)
		{
		printf("indice : %d, g : %d, h : %d, r : %d\n",i,factCur->g,
							factCur->h,factCur->r) ;
		j++ ;
		}
	}
printf("number of Fact in hash table : %d\n",j) ;
}
