| /**CFile**************************************************************** |
| |
| FileName [fxuHeapD.c] |
| |
| PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] |
| |
| Synopsis [The priority queue for double cube divisors.] |
| |
| Author [MVSIS Group] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - February 1, 2003.] |
| |
| Revision [$Id: fxuHeapD.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "fxuInt.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| #define FXU_HEAP_DOUBLE_WEIGHT(pDiv) ((pDiv)->Weight) |
| #define FXU_HEAP_DOUBLE_CURRENT(p, pDiv) ((p)->pTree[(pDiv)->HNum]) |
| #define FXU_HEAP_DOUBLE_PARENT_EXISTS(p, pDiv) ((pDiv)->HNum > 1) |
| #define FXU_HEAP_DOUBLE_CHILD1_EXISTS(p, pDiv) (((pDiv)->HNum << 1) <= p->nItems) |
| #define FXU_HEAP_DOUBLE_CHILD2_EXISTS(p, pDiv) ((((pDiv)->HNum << 1)+1) <= p->nItems) |
| #define FXU_HEAP_DOUBLE_PARENT(p, pDiv) ((p)->pTree[(pDiv)->HNum >> 1]) |
| #define FXU_HEAP_DOUBLE_CHILD1(p, pDiv) ((p)->pTree[(pDiv)->HNum << 1]) |
| #define FXU_HEAP_DOUBLE_CHILD2(p, pDiv) ((p)->pTree[((pDiv)->HNum << 1)+1]) |
| #define FXU_HEAP_DOUBLE_ASSERT(p, pDiv) assert( (pDiv)->HNum >= 1 && (pDiv)->HNum <= p->nItemsAlloc ) |
| |
| static void Fxu_HeapDoubleResize( Fxu_HeapDouble * p ); |
| static void Fxu_HeapDoubleSwap( Fxu_Double ** pDiv1, Fxu_Double ** pDiv2 ); |
| static void Fxu_HeapDoubleMoveUp( Fxu_HeapDouble * p, Fxu_Double * pDiv ); |
| static void Fxu_HeapDoubleMoveDn( Fxu_HeapDouble * p, Fxu_Double * pDiv ); |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Fxu_HeapDouble * Fxu_HeapDoubleStart() |
| { |
| Fxu_HeapDouble * p; |
| p = ABC_ALLOC( Fxu_HeapDouble, 1 ); |
| memset( p, 0, sizeof(Fxu_HeapDouble) ); |
| p->nItems = 0; |
| p->nItemsAlloc = 10000; |
| p->pTree = ABC_ALLOC( Fxu_Double *, p->nItemsAlloc + 1 ); |
| p->pTree[0] = NULL; |
| return p; |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_HeapDoubleResize( Fxu_HeapDouble * p ) |
| { |
| p->nItemsAlloc *= 2; |
| p->pTree = ABC_REALLOC( Fxu_Double *, p->pTree, p->nItemsAlloc + 1 ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_HeapDoubleStop( Fxu_HeapDouble * p ) |
| { |
| ABC_FREE( p->pTree ); |
| ABC_FREE( p ); |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_HeapDoublePrint( FILE * pFile, Fxu_HeapDouble * p ) |
| { |
| Fxu_Double * pDiv; |
| int Counter = 1; |
| int Degree = 1; |
| |
| Fxu_HeapDoubleCheck( p ); |
| fprintf( pFile, "The contents of the heap:\n" ); |
| fprintf( pFile, "Level %d: ", Degree ); |
| Fxu_HeapDoubleForEachItem( p, pDiv ) |
| { |
| assert( Counter == p->pTree[Counter]->HNum ); |
| fprintf( pFile, "%2d=%3d ", Counter, FXU_HEAP_DOUBLE_WEIGHT(p->pTree[Counter]) ); |
| if ( ++Counter == (1 << Degree) ) |
| { |
| fprintf( pFile, "\n" ); |
| Degree++; |
| fprintf( pFile, "Level %d: ", Degree ); |
| } |
| } |
| fprintf( pFile, "\n" ); |
| fprintf( pFile, "End of the heap printout.\n" ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_HeapDoubleCheck( Fxu_HeapDouble * p ) |
| { |
| Fxu_Double * pDiv; |
| Fxu_HeapDoubleForEachItem( p, pDiv ) |
| { |
| assert( pDiv->HNum == p->i ); |
| Fxu_HeapDoubleCheckOne( p, pDiv ); |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_HeapDoubleCheckOne( Fxu_HeapDouble * p, Fxu_Double * pDiv ) |
| { |
| int Weight1, Weight2; |
| if ( FXU_HEAP_DOUBLE_CHILD1_EXISTS(p,pDiv) ) |
| { |
| Weight1 = FXU_HEAP_DOUBLE_WEIGHT(pDiv); |
| Weight2 = FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD1(p,pDiv) ); |
| assert( Weight1 >= Weight2 ); |
| } |
| if ( FXU_HEAP_DOUBLE_CHILD2_EXISTS(p,pDiv) ) |
| { |
| Weight1 = FXU_HEAP_DOUBLE_WEIGHT(pDiv); |
| Weight2 = FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD2(p,pDiv) ); |
| assert( Weight1 >= Weight2 ); |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_HeapDoubleInsert( Fxu_HeapDouble * p, Fxu_Double * pDiv ) |
| { |
| if ( p->nItems == p->nItemsAlloc ) |
| Fxu_HeapDoubleResize( p ); |
| // put the last entry to the last place and move up |
| p->pTree[++p->nItems] = pDiv; |
| pDiv->HNum = p->nItems; |
| // move the last entry up if necessary |
| Fxu_HeapDoubleMoveUp( p, pDiv ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_HeapDoubleUpdate( Fxu_HeapDouble * p, Fxu_Double * pDiv ) |
| { |
| //printf( "Updating divisor %d.\n", pDiv->Num ); |
| |
| FXU_HEAP_DOUBLE_ASSERT(p,pDiv); |
| if ( FXU_HEAP_DOUBLE_PARENT_EXISTS(p,pDiv) && |
| FXU_HEAP_DOUBLE_WEIGHT(pDiv) > FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_PARENT(p,pDiv) ) ) |
| Fxu_HeapDoubleMoveUp( p, pDiv ); |
| else if ( FXU_HEAP_DOUBLE_CHILD1_EXISTS(p,pDiv) && |
| FXU_HEAP_DOUBLE_WEIGHT(pDiv) < FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD1(p,pDiv) ) ) |
| Fxu_HeapDoubleMoveDn( p, pDiv ); |
| else if ( FXU_HEAP_DOUBLE_CHILD2_EXISTS(p,pDiv) && |
| FXU_HEAP_DOUBLE_WEIGHT(pDiv) < FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD2(p,pDiv) ) ) |
| Fxu_HeapDoubleMoveDn( p, pDiv ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_HeapDoubleDelete( Fxu_HeapDouble * p, Fxu_Double * pDiv ) |
| { |
| FXU_HEAP_DOUBLE_ASSERT(p,pDiv); |
| // put the last entry to the deleted place |
| // decrement the number of entries |
| p->pTree[pDiv->HNum] = p->pTree[p->nItems--]; |
| p->pTree[pDiv->HNum]->HNum = pDiv->HNum; |
| // move the top entry down if necessary |
| Fxu_HeapDoubleUpdate( p, p->pTree[pDiv->HNum] ); |
| pDiv->HNum = 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Fxu_Double * Fxu_HeapDoubleReadMax( Fxu_HeapDouble * p ) |
| { |
| if ( p->nItems == 0 ) |
| return NULL; |
| return p->pTree[1]; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Fxu_Double * Fxu_HeapDoubleGetMax( Fxu_HeapDouble * p ) |
| { |
| Fxu_Double * pDiv; |
| if ( p->nItems == 0 ) |
| return NULL; |
| // prepare the return value |
| pDiv = p->pTree[1]; |
| pDiv->HNum = 0; |
| // put the last entry on top |
| // decrement the number of entries |
| p->pTree[1] = p->pTree[p->nItems--]; |
| p->pTree[1]->HNum = 1; |
| // move the top entry down if necessary |
| Fxu_HeapDoubleMoveDn( p, p->pTree[1] ); |
| return pDiv; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Fxu_HeapDoubleReadMaxWeight( Fxu_HeapDouble * p ) |
| { |
| if ( p->nItems == 0 ) |
| return -1; |
| else |
| return FXU_HEAP_DOUBLE_WEIGHT(p->pTree[1]); |
| } |
| |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_HeapDoubleSwap( Fxu_Double ** pDiv1, Fxu_Double ** pDiv2 ) |
| { |
| Fxu_Double * pDiv; |
| int Temp; |
| pDiv = *pDiv1; |
| *pDiv1 = *pDiv2; |
| *pDiv2 = pDiv; |
| Temp = (*pDiv1)->HNum; |
| (*pDiv1)->HNum = (*pDiv2)->HNum; |
| (*pDiv2)->HNum = Temp; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_HeapDoubleMoveUp( Fxu_HeapDouble * p, Fxu_Double * pDiv ) |
| { |
| Fxu_Double ** ppDiv, ** ppPar; |
| ppDiv = &FXU_HEAP_DOUBLE_CURRENT(p, pDiv); |
| while ( FXU_HEAP_DOUBLE_PARENT_EXISTS(p,*ppDiv) ) |
| { |
| ppPar = &FXU_HEAP_DOUBLE_PARENT(p,*ppDiv); |
| if ( FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) > FXU_HEAP_DOUBLE_WEIGHT(*ppPar) ) |
| { |
| Fxu_HeapDoubleSwap( ppDiv, ppPar ); |
| ppDiv = ppPar; |
| } |
| else |
| break; |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fxu_HeapDoubleMoveDn( Fxu_HeapDouble * p, Fxu_Double * pDiv ) |
| { |
| Fxu_Double ** ppChild1, ** ppChild2, ** ppDiv; |
| ppDiv = &FXU_HEAP_DOUBLE_CURRENT(p, pDiv); |
| while ( FXU_HEAP_DOUBLE_CHILD1_EXISTS(p,*ppDiv) ) |
| { // if Child1 does not exist, Child2 also does not exists |
| |
| // get the children |
| ppChild1 = &FXU_HEAP_DOUBLE_CHILD1(p,*ppDiv); |
| if ( FXU_HEAP_DOUBLE_CHILD2_EXISTS(p,*ppDiv) ) |
| { |
| ppChild2 = &FXU_HEAP_DOUBLE_CHILD2(p,*ppDiv); |
| |
| // consider two cases |
| if ( FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild1) && |
| FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild2) ) |
| { // Div is larger than both, skip |
| break; |
| } |
| else |
| { // Div is smaller than one of them, then swap it with larger |
| if ( FXU_HEAP_DOUBLE_WEIGHT(*ppChild1) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild2) ) |
| { |
| Fxu_HeapDoubleSwap( ppDiv, ppChild1 ); |
| // update the pointer |
| ppDiv = ppChild1; |
| } |
| else |
| { |
| Fxu_HeapDoubleSwap( ppDiv, ppChild2 ); |
| // update the pointer |
| ppDiv = ppChild2; |
| } |
| } |
| } |
| else // Child2 does not exist |
| { |
| // consider two cases |
| if ( FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild1) ) |
| { // Div is larger than Child1, skip |
| break; |
| } |
| else |
| { // Div is smaller than Child1, then swap them |
| Fxu_HeapDoubleSwap( ppDiv, ppChild1 ); |
| // update the pointer |
| ppDiv = ppChild1; |
| } |
| } |
| } |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |