blob: 14e876993a34ca012a0ca4bbcb298993825d516e [file] [log] [blame]
/**CFile****************************************************************
FileName [hopTable.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Minimalistic And-Inverter Graph package.]
Synopsis [Structural hashing table.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - May 11, 2006. ]
Revision [$Id: hopTable.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
***********************************************************************/
#include "hop.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// hashing the node
static unsigned long Hop_Hash( Hop_Obj_t * pObj, int TableSize )
{
unsigned long Key = Hop_ObjIsExor(pObj) * 1699;
Key ^= Hop_ObjFanin0(pObj)->Id * 7937;
Key ^= Hop_ObjFanin1(pObj)->Id * 2971;
Key ^= Hop_ObjFaninC0(pObj) * 911;
Key ^= Hop_ObjFaninC1(pObj) * 353;
return Key % TableSize;
}
// returns the place where this node is stored (or should be stored)
static Hop_Obj_t ** Hop_TableFind( Hop_Man_t * p, Hop_Obj_t * pObj )
{
Hop_Obj_t ** ppEntry;
assert( Hop_ObjChild0(pObj) && Hop_ObjChild1(pObj) );
assert( Hop_ObjFanin0(pObj)->Id < Hop_ObjFanin1(pObj)->Id );
for ( ppEntry = p->pTable + Hop_Hash(pObj, p->nTableSize); *ppEntry; ppEntry = &(*ppEntry)->pNext )
if ( *ppEntry == pObj )
return ppEntry;
assert( *ppEntry == NULL );
return ppEntry;
}
static void Hop_TableResize( Hop_Man_t * p );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Checks if a node with the given attributes is in the hash table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Hop_Obj_t * Hop_TableLookup( Hop_Man_t * p, Hop_Obj_t * pGhost )
{
Hop_Obj_t * pEntry;
assert( !Hop_IsComplement(pGhost) );
assert( Hop_ObjChild0(pGhost) && Hop_ObjChild1(pGhost) );
assert( Hop_ObjFanin0(pGhost)->Id < Hop_ObjFanin1(pGhost)->Id );
if ( p->fRefCount && (!Hop_ObjRefs(Hop_ObjFanin0(pGhost)) || !Hop_ObjRefs(Hop_ObjFanin1(pGhost))) )
return NULL;
for ( pEntry = p->pTable[Hop_Hash(pGhost, p->nTableSize)]; pEntry; pEntry = pEntry->pNext )
{
if ( Hop_ObjChild0(pEntry) == Hop_ObjChild0(pGhost) &&
Hop_ObjChild1(pEntry) == Hop_ObjChild1(pGhost) &&
Hop_ObjType(pEntry) == Hop_ObjType(pGhost) )
return pEntry;
}
return NULL;
}
/**Function*************************************************************
Synopsis [Adds the new node to the hash table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Hop_TableInsert( Hop_Man_t * p, Hop_Obj_t * pObj )
{
Hop_Obj_t ** ppPlace;
assert( !Hop_IsComplement(pObj) );
assert( Hop_TableLookup(p, pObj) == NULL );
if ( (pObj->Id & 0xFF) == 0 && 2 * p->nTableSize < Hop_ManNodeNum(p) )
Hop_TableResize( p );
ppPlace = Hop_TableFind( p, pObj );
assert( *ppPlace == NULL );
*ppPlace = pObj;
}
/**Function*************************************************************
Synopsis [Deletes the node from the hash table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Hop_TableDelete( Hop_Man_t * p, Hop_Obj_t * pObj )
{
Hop_Obj_t ** ppPlace;
assert( !Hop_IsComplement(pObj) );
ppPlace = Hop_TableFind( p, pObj );
assert( *ppPlace == pObj ); // node should be in the table
// remove the node
*ppPlace = pObj->pNext;
pObj->pNext = NULL;
}
/**Function*************************************************************
Synopsis [Count the number of nodes in the table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Hop_TableCountEntries( Hop_Man_t * p )
{
Hop_Obj_t * pEntry;
int i, Counter = 0;
for ( i = 0; i < p->nTableSize; i++ )
for ( pEntry = p->pTable[i]; pEntry; pEntry = pEntry->pNext )
Counter++;
return Counter;
}
/**Function*************************************************************
Synopsis [Resizes the table.]
Description [Typically this procedure should not be called.]
SideEffects []
SeeAlso []
***********************************************************************/
void Hop_TableResize( Hop_Man_t * p )
{
Hop_Obj_t * pEntry, * pNext;
Hop_Obj_t ** pTableOld, ** ppPlace;
int nTableSizeOld, Counter, nEntries, i;
abctime clk;
clk = Abc_Clock();
// save the old table
pTableOld = p->pTable;
nTableSizeOld = p->nTableSize;
// get the new table
p->nTableSize = Abc_PrimeCudd( 2 * Hop_ManNodeNum(p) );
p->pTable = ABC_ALLOC( Hop_Obj_t *, p->nTableSize );
memset( p->pTable, 0, sizeof(Hop_Obj_t *) * p->nTableSize );
// rehash the entries from the old table
Counter = 0;
for ( i = 0; i < nTableSizeOld; i++ )
for ( pEntry = pTableOld[i], pNext = pEntry? pEntry->pNext : NULL; pEntry; pEntry = pNext, pNext = pEntry? pEntry->pNext : NULL )
{
// get the place where this entry goes in the table
ppPlace = Hop_TableFind( p, pEntry );
assert( *ppPlace == NULL ); // should not be there
// add the entry to the list
*ppPlace = pEntry;
pEntry->pNext = NULL;
Counter++;
}
nEntries = Hop_ManNodeNum(p);
assert( Counter == nEntries );
// printf( "Increasing the structural table size from %6d to %6d. ", nTableSizeOld, p->nTableSize );
// ABC_PRT( "Time", Abc_Clock() - clk );
// replace the table and the parameters
ABC_FREE( pTableOld );
}
/**Function********************************************************************
Synopsis [Profiles the hash table.]
Description []
SideEffects []
SeeAlso []
******************************************************************************/
void Hop_TableProfile( Hop_Man_t * p )
{
Hop_Obj_t * pEntry;
int i, Counter;
for ( i = 0; i < p->nTableSize; i++ )
{
Counter = 0;
for ( pEntry = p->pTable[i]; pEntry; pEntry = pEntry->pNext )
Counter++;
if ( Counter )
printf( "%d ", Counter );
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END