/**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