blob: ead8e91427f6254ab17d9d87fb37b3c866a2784a [file] [log] [blame]
/**CFile****************************************************************
FileName [fxuHeapS.c]
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
Synopsis [The priority queue for variables.]
Author [MVSIS Group]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - February 1, 2003.]
Revision [$Id: fxuHeapS.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "fxuInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define FXU_HEAP_SINGLE_WEIGHT(pSingle) ((pSingle)->Weight)
#define FXU_HEAP_SINGLE_CURRENT(p, pSingle) ((p)->pTree[(pSingle)->HNum])
#define FXU_HEAP_SINGLE_PARENT_EXISTS(p, pSingle) ((pSingle)->HNum > 1)
#define FXU_HEAP_SINGLE_CHILD1_EXISTS(p, pSingle) (((pSingle)->HNum << 1) <= p->nItems)
#define FXU_HEAP_SINGLE_CHILD2_EXISTS(p, pSingle) ((((pSingle)->HNum << 1)+1) <= p->nItems)
#define FXU_HEAP_SINGLE_PARENT(p, pSingle) ((p)->pTree[(pSingle)->HNum >> 1])
#define FXU_HEAP_SINGLE_CHILD1(p, pSingle) ((p)->pTree[(pSingle)->HNum << 1])
#define FXU_HEAP_SINGLE_CHILD2(p, pSingle) ((p)->pTree[((pSingle)->HNum << 1)+1])
#define FXU_HEAP_SINGLE_ASSERT(p, pSingle) assert( (pSingle)->HNum >= 1 && (pSingle)->HNum <= p->nItemsAlloc )
static void Fxu_HeapSingleResize( Fxu_HeapSingle * p );
static void Fxu_HeapSingleSwap( Fxu_Single ** pSingle1, Fxu_Single ** pSingle2 );
static void Fxu_HeapSingleMoveUp( Fxu_HeapSingle * p, Fxu_Single * pSingle );
static void Fxu_HeapSingleMoveDn( Fxu_HeapSingle * p, Fxu_Single * pSingle );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Fxu_HeapSingle * Fxu_HeapSingleStart()
{
Fxu_HeapSingle * p;
p = ABC_ALLOC( Fxu_HeapSingle, 1 );
memset( p, 0, sizeof(Fxu_HeapSingle) );
p->nItems = 0;
p->nItemsAlloc = 2000;
p->pTree = ABC_ALLOC( Fxu_Single *, p->nItemsAlloc + 10 );
p->pTree[0] = NULL;
return p;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_HeapSingleResize( Fxu_HeapSingle * p )
{
p->nItemsAlloc *= 2;
p->pTree = ABC_REALLOC( Fxu_Single *, p->pTree, p->nItemsAlloc + 10 );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_HeapSingleStop( Fxu_HeapSingle * p )
{
int i;
i = 0;
ABC_FREE( p->pTree );
i = 1;
ABC_FREE( p );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_HeapSinglePrint( FILE * pFile, Fxu_HeapSingle * p )
{
Fxu_Single * pSingle;
int Counter = 1;
int Degree = 1;
Fxu_HeapSingleCheck( p );
fprintf( pFile, "The contents of the heap:\n" );
fprintf( pFile, "Level %d: ", Degree );
Fxu_HeapSingleForEachItem( p, pSingle )
{
assert( Counter == p->pTree[Counter]->HNum );
fprintf( pFile, "%2d=%3d ", Counter, FXU_HEAP_SINGLE_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_HeapSingleCheck( Fxu_HeapSingle * p )
{
Fxu_Single * pSingle;
Fxu_HeapSingleForEachItem( p, pSingle )
{
assert( pSingle->HNum == p->i );
Fxu_HeapSingleCheckOne( p, pSingle );
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_HeapSingleCheckOne( Fxu_HeapSingle * p, Fxu_Single * pSingle )
{
int Weight1, Weight2;
if ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,pSingle) )
{
Weight1 = FXU_HEAP_SINGLE_WEIGHT(pSingle);
Weight2 = FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD1(p,pSingle) );
assert( Weight1 >= Weight2 );
}
if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,pSingle) )
{
Weight1 = FXU_HEAP_SINGLE_WEIGHT(pSingle);
Weight2 = FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD2(p,pSingle) );
assert( Weight1 >= Weight2 );
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_HeapSingleInsert( Fxu_HeapSingle * p, Fxu_Single * pSingle )
{
if ( p->nItems == p->nItemsAlloc )
Fxu_HeapSingleResize( p );
// put the last entry to the last place and move up
p->pTree[++p->nItems] = pSingle;
pSingle->HNum = p->nItems;
// move the last entry up if necessary
Fxu_HeapSingleMoveUp( p, pSingle );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_HeapSingleUpdate( Fxu_HeapSingle * p, Fxu_Single * pSingle )
{
FXU_HEAP_SINGLE_ASSERT(p,pSingle);
if ( FXU_HEAP_SINGLE_PARENT_EXISTS(p,pSingle) &&
FXU_HEAP_SINGLE_WEIGHT(pSingle) > FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_PARENT(p,pSingle) ) )
Fxu_HeapSingleMoveUp( p, pSingle );
else if ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,pSingle) &&
FXU_HEAP_SINGLE_WEIGHT(pSingle) < FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD1(p,pSingle) ) )
Fxu_HeapSingleMoveDn( p, pSingle );
else if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,pSingle) &&
FXU_HEAP_SINGLE_WEIGHT(pSingle) < FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD2(p,pSingle) ) )
Fxu_HeapSingleMoveDn( p, pSingle );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_HeapSingleDelete( Fxu_HeapSingle * p, Fxu_Single * pSingle )
{
int Place = pSingle->HNum;
FXU_HEAP_SINGLE_ASSERT(p,pSingle);
// put the last entry to the deleted place
// decrement the number of entries
p->pTree[Place] = p->pTree[p->nItems--];
p->pTree[Place]->HNum = Place;
// move the top entry down if necessary
Fxu_HeapSingleUpdate( p, p->pTree[Place] );
pSingle->HNum = 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Fxu_Single * Fxu_HeapSingleReadMax( Fxu_HeapSingle * p )
{
if ( p->nItems == 0 )
return NULL;
return p->pTree[1];
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Fxu_Single * Fxu_HeapSingleGetMax( Fxu_HeapSingle * p )
{
Fxu_Single * pSingle;
if ( p->nItems == 0 )
return NULL;
// prepare the return value
pSingle = p->pTree[1];
pSingle->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_HeapSingleMoveDn( p, p->pTree[1] );
return pSingle;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Fxu_HeapSingleReadMaxWeight( Fxu_HeapSingle * p )
{
if ( p->nItems == 0 )
return -1;
return FXU_HEAP_SINGLE_WEIGHT(p->pTree[1]);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_HeapSingleSwap( Fxu_Single ** pSingle1, Fxu_Single ** pSingle2 )
{
Fxu_Single * pSingle;
int Temp;
pSingle = *pSingle1;
*pSingle1 = *pSingle2;
*pSingle2 = pSingle;
Temp = (*pSingle1)->HNum;
(*pSingle1)->HNum = (*pSingle2)->HNum;
(*pSingle2)->HNum = Temp;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_HeapSingleMoveUp( Fxu_HeapSingle * p, Fxu_Single * pSingle )
{
Fxu_Single ** ppSingle, ** ppPar;
ppSingle = &FXU_HEAP_SINGLE_CURRENT(p, pSingle);
while ( FXU_HEAP_SINGLE_PARENT_EXISTS(p,*ppSingle) )
{
ppPar = &FXU_HEAP_SINGLE_PARENT(p,*ppSingle);
if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) > FXU_HEAP_SINGLE_WEIGHT(*ppPar) )
{
Fxu_HeapSingleSwap( ppSingle, ppPar );
ppSingle = ppPar;
}
else
break;
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_HeapSingleMoveDn( Fxu_HeapSingle * p, Fxu_Single * pSingle )
{
Fxu_Single ** ppChild1, ** ppChild2, ** ppSingle;
ppSingle = &FXU_HEAP_SINGLE_CURRENT(p, pSingle);
while ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,*ppSingle) )
{ // if Child1 does not exist, Child2 also does not exists
// get the children
ppChild1 = &FXU_HEAP_SINGLE_CHILD1(p,*ppSingle);
if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,*ppSingle) )
{
ppChild2 = &FXU_HEAP_SINGLE_CHILD2(p,*ppSingle);
// consider two cases
if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild1) &&
FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild2) )
{ // Var is larger than both, skip
break;
}
else
{ // Var is smaller than one of them, then swap it with larger
if ( FXU_HEAP_SINGLE_WEIGHT(*ppChild1) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild2) )
{
Fxu_HeapSingleSwap( ppSingle, ppChild1 );
// update the pointer
ppSingle = ppChild1;
}
else
{
Fxu_HeapSingleSwap( ppSingle, ppChild2 );
// update the pointer
ppSingle = ppChild2;
}
}
}
else // Child2 does not exist
{
// consider two cases
if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild1) )
{ // Var is larger than Child1, skip
break;
}
else
{ // Var is smaller than Child1, then swap them
Fxu_HeapSingleSwap( ppSingle, ppChild1 );
// update the pointer
ppSingle = ppChild1;
}
}
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END