abc/src/bdd/cudd/cuddTable.c
/**Function********************************************************************

  Synopsis    [Checks the unique table for the existence of an internal node.]

  Description [Checks the unique table for the existence of an internal
  node. If it does not exist, it creates a new one.  Does not
  modify the reference count of whatever is returned.  A newly created
  internal node comes back with a reference count 0.  For a newly
  created node, increments the reference counts of what T and E point
  to.  Returns a pointer to the new node if successful; NULL if memory
  is exhausted or if reordering took place.]

  SideEffects [None]

  SeeAlso     [cuddUniqueInterZdd]

******************************************************************************/
Function
Synopsis    [Checks the unique table for the existence of an internal node.]

Description [Checks the unique table for the existence of an internal
node. If it does not exist, it creates a new one.  Does not
modify the reference count of whatever is returned.  A newly created
internal node comes back with a reference count 0.  For a newly
created node, increments the reference counts of what T and E point
to.  Returns a pointer to the new node if successful; NULL if memory
is exhausted or if reordering took place.]




Function Synopsis [ Checks the unique table for the existence of an internal node . ] Description [ Checks the unique table for the existence of an internal node . If it does not exist it creates a new one . Does not modify the reference count of whatever is returned . A newly created internal node comes back with a reference count 0 . For a newly created node increments the reference counts of what T and E point to . Returns a pointer to the new node if successful ; NULL if memory is exhausted or if reordering took place . ]
DdNode *
cuddUniqueInter(
  DdManager * unique,
  int  index,
  DdNode * T,
  DdNode * E)
{
    int pos;
    unsigned int level;
    int retval;
    DdNodePtr *nodelist;
    DdNode *looking;
    DdNodePtr *previousP;
    DdSubtable *subtable;
    int gcNumber;
#ifdef DD_UNIQUE_PROFILE
    unique->uniqueLookUps++;
#endif
    if (index >= unique->size) {
        if (!ddResizeTable(unique,index)) return(NULL);
    }
    level = unique->perm[index];
    subtable = &(unique->subtables[level]);
#ifdef DD_DEBUG
    assert(level < (unsigned) cuddI(unique,T->index));
    assert(level < (unsigned) cuddI(unique,Cudd_Regular(E)->index));
#endif
    pos = ddHash(cuddF2L(T), cuddF2L(E), subtable->shift);
    nodelist = subtable->nodelist;
    previousP = &(nodelist[pos]);
    looking = *previousP;
    while (T < cuddT(looking)) {
        previousP = &(looking->next);
        looking = *previousP;
#ifdef DD_UNIQUE_PROFILE
        unique->uniqueLinks++;
#endif
    }
    while (T == cuddT(looking) && E < cuddE(looking)) {
        previousP = &(looking->next);
        looking = *previousP;
#ifdef DD_UNIQUE_PROFILE
        unique->uniqueLinks++;
#endif
    }
    if (T == cuddT(looking) && E == cuddE(looking)) {
        if (looking->ref == 0) {
            cuddReclaim(unique,looking);
        }
        return(looking);
    }
    if (unique->autoDyn &&
    unique->keys - (unique->dead & unique->countDead) >= unique->nextDyn) {
#ifdef DD_DEBUG
        retval = Cudd_DebugCheck(unique);
        if (retval != 0) return(NULL);
        retval = Cudd_CheckKeys(unique);
        if (retval != 0) return(NULL);
#endif
        retval = Cudd_ReduceHeap(unique,unique->autoMethod,10); 
        if (retval == 0) unique->reordered = 2;
#ifdef DD_DEBUG
        retval = Cudd_DebugCheck(unique);
        if (retval != 0) unique->reordered = 2;
        retval = Cudd_CheckKeys(unique);
        if (retval != 0) unique->reordered = 2;
#endif
        return(NULL);
    }
    if (subtable->keys > subtable->maxKeys) {
        if (unique->gcEnabled &&
            ((unique->dead > unique->minDead) ||
            ((unique->dead > unique->minDead / 2) &&
            (subtable->dead > subtable->keys * 0.95)))) { 
            (void) cuddGarbageCollect(unique,1);
        } else {
            cuddRehash(unique,(int)level);
        }
        pos = ddHash(cuddF2L(T), cuddF2L(E), subtable->shift);
        nodelist = subtable->nodelist;
        previousP = &(nodelist[pos]);
        looking = *previousP;
        while (T < cuddT(looking)) {
            previousP = &(looking->next);
            looking = *previousP;
#ifdef DD_UNIQUE_PROFILE
            unique->uniqueLinks++;
#endif
        }
        while (T == cuddT(looking) && E < cuddE(looking)) {
            previousP = &(looking->next);
            looking = *previousP;
#ifdef DD_UNIQUE_PROFILE
            unique->uniqueLinks++;
#endif
        }
    }
    gcNumber = unique->garbageCollections;
    looking = cuddAllocNode(unique);
    if (looking == NULL) {
        return(NULL);
    }
    unique->keys++;
    subtable->keys++;
    if (gcNumber != unique->garbageCollections) {
        DdNode *looking2;
        pos = ddHash(cuddF2L(T), cuddF2L(E), subtable->shift);
        nodelist = subtable->nodelist;
        previousP = &(nodelist[pos]);
        looking2 = *previousP;
        while (T < cuddT(looking2)) {
            previousP = &(looking2->next);
            looking2 = *previousP;
#ifdef DD_UNIQUE_PROFILE
            unique->uniqueLinks++;
#endif
        }
        while (T == cuddT(looking2) && E < cuddE(looking2)) {
            previousP = &(looking2->next);
            looking2 = *previousP;
#ifdef DD_UNIQUE_PROFILE
            unique->uniqueLinks++;
#endif
        }
    }
    looking->index = index;
    cuddT(looking) = T;
    cuddE(looking) = E;
    looking->next = *previousP;
    *previousP = looking;
    cuddSatInc(T->ref);         
    cuddRef(E);
#ifdef DD_DEBUG
    cuddCheckCollisionOrdering(unique,level,pos);
#endif
    return(looking);
}
DdNode * cuddUniqueInter ( DdManager * unique , int index , DdNode * T , DdNode * E ) { int pos ; unsigned int level ; int retval ; DdNodePtr * nodelist ; DdNode * looking ; DdNodePtr * previousP ; DdSubtable * subtable ; int gcNumber ; #ifdef DD_UNIQUE_PROFILE unique -> uniqueLookUps ++ ; #endif if ( index >= unique -> size ) { if ( ! ddResizeTable ( unique , index ) ) return ( NULL ) ; } level = unique -> perm [ index ] ; subtable = & ( unique -> subtables [ level ] ) ; #ifdef DD_DEBUG assert ( level < ( unsigned ) cuddI ( unique , T -> index ) ) ; assert ( level < ( unsigned ) cuddI ( unique , Cudd_Regular ( E ) -> index ) ) ; #endif pos = ddHash ( cuddF2L ( T ) , cuddF2L ( E ) , subtable -> shift ) ; nodelist = subtable -> nodelist ; previousP = & ( nodelist [ pos ] ) ; looking = * previousP ; while ( T < cuddT ( looking ) ) { previousP = & ( looking -> next ) ; looking = * previousP ; #ifdef DD_UNIQUE_PROFILE unique -> uniqueLinks ++ ; #endif } while ( T == cuddT ( looking ) && E < cuddE ( looking ) ) { previousP = & ( looking -> next ) ; looking = * previousP ; #ifdef DD_UNIQUE_PROFILE unique -> uniqueLinks ++ ; #endif } if ( T == cuddT ( looking ) && E == cuddE ( looking ) ) { if ( looking -> ref == 0 ) { cuddReclaim ( unique , looking ) ; } return ( looking ) ; } if ( unique -> autoDyn && unique -> keys - ( unique -> dead & unique -> countDead ) >= unique -> nextDyn ) { #ifdef DD_DEBUG retval = Cudd_DebugCheck ( unique ) ; if ( retval != 0 ) return ( NULL ) ; retval = Cudd_CheckKeys ( unique ) ; if ( retval != 0 ) return ( NULL ) ; #endif retval = Cudd_ReduceHeap ( unique , unique -> autoMethod , 10 ) ; if ( retval == 0 ) unique -> reordered = 2 ; #ifdef DD_DEBUG retval = Cudd_DebugCheck ( unique ) ; if ( retval != 0 ) unique -> reordered = 2 ; retval = Cudd_CheckKeys ( unique ) ; if ( retval != 0 ) unique -> reordered = 2 ; #endif return ( NULL ) ; } if ( subtable -> keys > subtable -> maxKeys ) { if ( unique -> gcEnabled && ( ( unique -> dead > unique -> minDead ) || ( ( unique -> dead > unique -> minDead / 2 ) && ( subtable -> dead > subtable -> keys * 0.95 ) ) ) ) { ( void ) cuddGarbageCollect ( unique , 1 ) ; } else { cuddRehash ( unique , ( int ) level ) ; } pos = ddHash ( cuddF2L ( T ) , cuddF2L ( E ) , subtable -> shift ) ; nodelist = subtable -> nodelist ; previousP = & ( nodelist [ pos ] ) ; looking = * previousP ; while ( T < cuddT ( looking ) ) { previousP = & ( looking -> next ) ; looking = * previousP ; #ifdef DD_UNIQUE_PROFILE unique -> uniqueLinks ++ ; #endif } while ( T == cuddT ( looking ) && E < cuddE ( looking ) ) { previousP = & ( looking -> next ) ; looking = * previousP ; #ifdef DD_UNIQUE_PROFILE unique -> uniqueLinks ++ ; #endif } } gcNumber = unique -> garbageCollections ; looking = cuddAllocNode ( unique ) ; if ( looking == NULL ) { return ( NULL ) ; } unique -> keys ++ ; subtable -> keys ++ ; if ( gcNumber != unique -> garbageCollections ) { DdNode * looking2 ; pos = ddHash ( cuddF2L ( T ) , cuddF2L ( E ) , subtable -> shift ) ; nodelist = subtable -> nodelist ; previousP = & ( nodelist [ pos ] ) ; looking2 = * previousP ; while ( T < cuddT ( looking2 ) ) { previousP = & ( looking2 -> next ) ; looking2 = * previousP ; #ifdef DD_UNIQUE_PROFILE unique -> uniqueLinks ++ ; #endif } while ( T == cuddT ( looking2 ) && E < cuddE ( looking2 ) ) { previousP = & ( looking2 -> next ) ; looking2 = * previousP ; #ifdef DD_UNIQUE_PROFILE unique -> uniqueLinks ++ ; #endif } } looking -> index = index ; cuddT ( looking ) = T ; cuddE ( looking ) = E ; looking -> next = * previousP ; * previousP = looking ; cuddSatInc ( T -> ref ) ; cuddRef ( E ) ; #ifdef DD_DEBUG cuddCheckCollisionOrdering ( unique , level , pos ) ; #endif return ( looking ) ; }
Function
Synopsis    [Checks the unique table for the existence of an internal node.]
Function Synopsis [ Checks the unique table for the existence of an internal node . ]
/* countDead is 0 if deads should be counted and ~0 if they should not. */ /* 10 = whatever */ /* too many dead */ /* Update pointer to insertion point. In the case of rehashing,
        ** the slot may have changed. In the case of garbage collection,
        ** the predecessor may have been dead. */ /* we know T is a regular pointer */ //    assert( Cudd_Regular(T)->Id < 100000000 ); //    assert( Cudd_Regular(E)->Id < 100000000 );