blob: 3028d737e61c82af347745ef753a65ecf22618c5 [file] [log] [blame]
/**CFile****************************************************************
FileName [vecQue.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Resizable arrays.]
Synopsis [Priority queue.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: vecQue.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef ABC__misc__vec__Queue_h
#define ABC__misc__vec__Queue_h
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include <stdio.h>
ABC_NAMESPACE_HEADER_START
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Vec_Que_t_ Vec_Que_t;
struct Vec_Que_t_
{
int nCap;
int nSize;
int * pHeap;
int * pOrder;
float ** pCostsFlt; // owned by the caller
};
static inline float Vec_QuePrio( Vec_Que_t * p, int v ) { return *p->pCostsFlt ? (*p->pCostsFlt)[v] : v; }
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Vec_Que_t * Vec_QueAlloc( int nCap )
{
Vec_Que_t * p;
p = ABC_CALLOC( Vec_Que_t, 1 );
if ( nCap < 16 )
nCap = 16;
p->nSize = 1;
p->nCap = nCap + 1;
p->pHeap = ABC_FALLOC( int, p->nCap );
p->pOrder = ABC_FALLOC( int, p->nCap );
return p;
}
static inline void Vec_QueFree( Vec_Que_t * p )
{
ABC_FREE( p->pOrder );
ABC_FREE( p->pHeap );
ABC_FREE( p );
}
static inline void Vec_QueFreeP( Vec_Que_t ** p )
{
if ( *p )
Vec_QueFree( *p );
*p = NULL;
}
static inline void Vec_QueSetPriority( Vec_Que_t * p, float ** pCosts )
{
assert( p->pCostsFlt == NULL );
p->pCostsFlt = pCosts;
}
static inline void Vec_QueGrow( Vec_Que_t * p, int nCapMin )
{
if ( p->nCap >= nCapMin )
return;
p->pHeap = ABC_REALLOC( int, p->pHeap, nCapMin );
p->pOrder = ABC_REALLOC( int, p->pOrder, nCapMin );
memset( p->pHeap + p->nCap, 0xff, (nCapMin - p->nCap) * sizeof(int) );
memset( p->pOrder + p->nCap, 0xff, (nCapMin - p->nCap) * sizeof(int) );
p->nCap = nCapMin;
}
static inline void Vec_QueClear( Vec_Que_t * p )
{
int i;
assert( p->pHeap[0] == -1 );
for ( i = 1; i < p->nSize; i++ )
{
assert( p->pHeap[i] >= 0 && p->pOrder[p->pHeap[i]] == i );
p->pOrder[p->pHeap[i]] = -1;
p->pHeap[i] = -1;
}
p->nSize = 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_QueSize( Vec_Que_t * p )
{
assert( p->nSize > 0 );
return p->nSize - 1;
}
static inline int Vec_QueTop( Vec_Que_t * p )
{
return Vec_QueSize(p) > 0 ? p->pHeap[1] : -1;
}
static inline float Vec_QueTopPriority( Vec_Que_t * p )
{
return Vec_QueSize(p) > 0 ? Vec_QuePrio(p, p->pHeap[1]) : -ABC_INFINITY;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_QueMoveUp( Vec_Que_t * p, int v )
{
float Cost = Vec_QuePrio(p, v);
int i = p->pOrder[v];
int parent = i >> 1;
int fMoved = 0;
assert( p->pOrder[v] != -1 );
assert( p->pHeap[i] == v );
while ( i > 1 && Cost > Vec_QuePrio(p, p->pHeap[parent]) )
{
p->pHeap[i] = p->pHeap[parent];
p->pOrder[p->pHeap[i]] = i;
i = parent;
parent = i >> 1;
fMoved = 1;
}
p->pHeap[i] = v;
p->pOrder[v] = i;
return fMoved;
}
static inline void Vec_QueMoveDown( Vec_Que_t * p, int v )
{
float Cost = Vec_QuePrio(p, v);
int i = p->pOrder[v];
int child = i << 1;
while ( child < p->nSize )
{
if ( child + 1 < p->nSize && Vec_QuePrio(p, p->pHeap[child]) < Vec_QuePrio(p, p->pHeap[child+1]) )
child++;
assert( child < p->nSize );
if ( Cost >= Vec_QuePrio(p, p->pHeap[child]))
break;
p->pHeap[i] = p->pHeap[child];
p->pOrder[p->pHeap[i]] = i;
i = child;
child = child << 1;
}
p->pHeap[i] = v;
p->pOrder[v] = i;
}
static inline void Vec_QueUpdate( Vec_Que_t * p, int v )
{
if ( !Vec_QueMoveUp( p, v ) )
Vec_QueMoveDown( p, v );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_QueIsMember( Vec_Que_t * p, int v )
{
assert( v >= 0 );
return (int)( v < p->nCap && p->pOrder[v] >= 0 );
}
static inline void Vec_QuePush( Vec_Que_t * p, int v )
{
if ( p->nSize >= p->nCap )
Vec_QueGrow( p, Abc_MaxInt(p->nSize+1, 2*p->nCap) );
if ( v >= p->nCap )
Vec_QueGrow( p, Abc_MaxInt(v+1, 2*p->nCap) );
assert( p->nSize < p->nCap );
assert( p->pOrder[v] == -1 );
assert( p->pHeap[p->nSize] == -1 );
p->pOrder[v] = p->nSize;
p->pHeap[p->nSize++] = v;
Vec_QueMoveUp( p, v );
}
static inline int Vec_QuePop( Vec_Que_t * p )
{
int v, Res;
assert( p->nSize > 1 );
Res = p->pHeap[1]; p->pOrder[Res] = -1;
if ( --p->nSize == 1 )
{
p->pHeap[1] = -1;
return Res;
}
v = p->pHeap[p->nSize]; p->pHeap[p->nSize] = -1;
p->pHeap[1] = v; p->pOrder[v] = 1;
Vec_QueMoveDown( p, v );
return Res;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_QuePrint( Vec_Que_t * p )
{
int i, k, m;
for ( i = k = 1; i < p->nSize; i += k, k *= 2 )
{
for ( m = 0; m < k; m++ )
if ( i+m < p->nSize )
printf( "%-5d", p->pHeap[i+m] );
printf( "\n" );
for ( m = 0; m < k; m++ )
if ( i+m < p->nSize )
printf( "%-5.0f", Vec_QuePrio(p, p->pHeap[i+m]) );
printf( "\n" );
printf( "\n" );
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_QueCheck( Vec_Que_t * p )
{
int i, child;
assert( p->nSize > 0 );
assert( p->nSize <= p->nCap );
// check mapping
for ( i = 0; i < p->nSize-1; i++ )
assert( p->pOrder[i] > 0 );
for ( ; i < p->nCap; i++ )
assert( p->pOrder[i] == -1 );
// check heap
assert( p->pHeap[0] == -1 );
for ( i = 0; i < p->nSize-1; i++ )
assert( p->pHeap[p->pOrder[i]] == i );
for ( i++; i < p->nCap; i++ )
assert( p->pHeap[i] == -1 );
// check heap property
for ( i = 1; i < p->nSize; i++ )
{
child = i << 1;
if ( child < p->nSize )
assert( Vec_QuePrio(p, p->pHeap[i]) >= Vec_QuePrio(p, p->pHeap[child]) );
child++;
if ( child < p->nSize )
assert( Vec_QuePrio(p, p->pHeap[i]) >= Vec_QuePrio(p, p->pHeap[child]) );
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_QueTest( Vec_Flt_t * vCosts )
{
Vec_Int_t * vTop;
Vec_Que_t * p;
int i, Entry;
// start the queue
p = Vec_QueAlloc( Vec_FltSize(vCosts) );
Vec_QueSetPriority( p, Vec_FltArrayP(vCosts) );
for ( i = 0; i < Vec_FltSize(vCosts); i++ )
Vec_QuePush( p, i );
// Vec_QuePrint( p );
Vec_QueCheck( p );
// find the topmost 10%
vTop = Vec_IntAlloc( Vec_FltSize(vCosts) / 10 );
while ( Vec_IntSize(vTop) < Vec_FltSize(vCosts) / 10 )
Vec_IntPush( vTop, Vec_QuePop(p) );
// Vec_IntPrint( vTop );
// Vec_QueCheck( p ); // queque is not ready at this point!!!
// put them back
Vec_IntForEachEntry( vTop, Entry, i )
Vec_QuePush( p, Entry );
Vec_IntFree( vTop );
Vec_QueCheck( p );
Vec_QueFree( p );
}
/*
{
extern void Vec_QueTest( Vec_Flt_t * p );
Vec_QueTest( p->vTimesOut );
}
*/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_HEADER_END
#endif