You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							583 lines
						
					
					
						
							17 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							583 lines
						
					
					
						
							17 KiB
						
					
					
				
								/**CFile***********************************************************************
							 | 
						|
								
							 | 
						|
								  FileName    [cuddLevelQ.c]
							 | 
						|
								
							 | 
						|
								  PackageName [cudd]
							 | 
						|
								
							 | 
						|
								  Synopsis    [Procedure to manage level queues.]
							 | 
						|
								
							 | 
						|
								  Description [The functions in this file allow an application to
							 | 
						|
								  easily manipulate a queue where nodes are prioritized by level. The
							 | 
						|
								  emphasis is on efficiency. Therefore, the queue items can have
							 | 
						|
								  variable size.  If the application does not need to attach
							 | 
						|
								  information to the nodes, it can declare the queue items to be of
							 | 
						|
								  type DdQueueItem. Otherwise, it can declare them to be of a
							 | 
						|
								  structure type such that the first three fields are data
							 | 
						|
								  pointers. The third pointer points to the node.  The first two
							 | 
						|
								  pointers are used by the level queue functions. The remaining fields
							 | 
						|
								  are initialized to 0 when a new item is created, and are then left
							 | 
						|
								  to the exclusive use of the application. On the DEC Alphas the three
							 | 
						|
								  pointers must be 32-bit pointers when CUDD is compiled with 32-bit
							 | 
						|
								  pointers.  The level queue functions make sure that each node
							 | 
						|
								  appears at most once in the queue. They do so by keeping a hash
							 | 
						|
								  table where the node is used as key.  Queue items are recycled via a
							 | 
						|
								  free list for efficiency.
							 | 
						|
								  
							 | 
						|
								  Internal procedures provided by this module:
							 | 
						|
								                <ul>
							 | 
						|
										<li> cuddLevelQueueInit()
							 | 
						|
										<li> cuddLevelQueueQuit()
							 | 
						|
										<li> cuddLevelQueueEnqueue()
							 | 
						|
										<li> cuddLevelQueueDequeue()
							 | 
						|
										</ul>
							 | 
						|
								  Static procedures included in this module:
							 | 
						|
										<ul>
							 | 
						|
										<li> hashLookup()
							 | 
						|
										<li> hashInsert()
							 | 
						|
										<li> hashDelete()
							 | 
						|
										<li> hashResize()
							 | 
						|
										</ul>
							 | 
						|
										]
							 | 
						|
								
							 | 
						|
								  SeeAlso     []
							 | 
						|
								
							 | 
						|
								  Author      [Fabio Somenzi]
							 | 
						|
								
							 | 
						|
								  Copyright   [Copyright (c) 1995-2012, Regents of the University of Colorado
							 | 
						|
								
							 | 
						|
								  All rights reserved.
							 | 
						|
								
							 | 
						|
								  Redistribution and use in source and binary forms, with or without
							 | 
						|
								  modification, are permitted provided that the following conditions
							 | 
						|
								  are met:
							 | 
						|
								
							 | 
						|
								  Redistributions of source code must retain the above copyright
							 | 
						|
								  notice, this list of conditions and the following disclaimer.
							 | 
						|
								
							 | 
						|
								  Redistributions in binary form must reproduce the above copyright
							 | 
						|
								  notice, this list of conditions and the following disclaimer in the
							 | 
						|
								  documentation and/or other materials provided with the distribution.
							 | 
						|
								
							 | 
						|
								  Neither the name of the University of Colorado nor the names of its
							 | 
						|
								  contributors may be used to endorse or promote products derived from
							 | 
						|
								  this software without specific prior written permission.
							 | 
						|
								
							 | 
						|
								  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
							 | 
						|
								  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
							 | 
						|
								  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
							 | 
						|
								  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
							 | 
						|
								  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
							 | 
						|
								  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
							 | 
						|
								  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
							 | 
						|
								  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
							 | 
						|
								  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
							 | 
						|
								  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
							 | 
						|
								  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
							 | 
						|
								  POSSIBILITY OF SUCH DAMAGE.]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								#include "util.h"
							 | 
						|
								#include "cuddInt.h"
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Constant declarations                                                     */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Stucture declarations                                                     */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Type declarations                                                         */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Variable declarations                                                     */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								#ifndef lint
							 | 
						|
								static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.16 2012/02/05 01:07:19 fabio Exp $";
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Macro declarations                                                        */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**Macro***********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis    [Hash function for the table of a level queue.]
							 | 
						|
								
							 | 
						|
								  Description [Hash function for the table of a level queue.]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     [hashInsert hashLookup hashDelete]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
							 | 
						|
								#define lqHash(key,shift) \
							 | 
						|
								(((unsigned)(ptruint)(key) * DD_P1) >> (shift))
							 | 
						|
								#else
							 | 
						|
								#define lqHash(key,shift) \
							 | 
						|
								(((unsigned)(key) * DD_P1) >> (shift))
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**AutomaticStart*************************************************************/
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Static function prototypes                                                */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								static DdQueueItem * hashLookup(DdLevelQueue *queue, void *key);
							 | 
						|
								static int hashInsert(DdLevelQueue *queue, DdQueueItem *item);
							 | 
						|
								static void hashDelete(DdLevelQueue *queue, DdQueueItem *item);
							 | 
						|
								static int hashResize(DdLevelQueue *queue);
							 | 
						|
								
							 | 
						|
								/**AutomaticEnd***************************************************************/
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Definition of internal functions                                          */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis    [Initializes a level queue.]
							 | 
						|
								
							 | 
						|
								  Description [Initializes a level queue. A level queue is a queue
							 | 
						|
								  where inserts are based on the levels of the nodes. Within each
							 | 
						|
								  level the policy is FIFO. Level queues are useful in traversing a
							 | 
						|
								  BDD top-down. Queue items are kept in a free list when dequeued for
							 | 
						|
								  efficiency. Returns a pointer to the new queue if successful; NULL
							 | 
						|
								  otherwise.]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     [cuddLevelQueueQuit cuddLevelQueueEnqueue cuddLevelQueueDequeue]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								DdLevelQueue *
							 | 
						|
								cuddLevelQueueInit(
							 | 
						|
								  int  levels /* number of levels */,
							 | 
						|
								  int  itemSize /* size of the item */,
							 | 
						|
								  int  numBuckets /* initial number of hash buckets */)
							 | 
						|
								{
							 | 
						|
								    DdLevelQueue *queue;
							 | 
						|
								    int logSize;
							 | 
						|
								
							 | 
						|
								    queue = ALLOC(DdLevelQueue,1);
							 | 
						|
								    if (queue == NULL)
							 | 
						|
									return(NULL);
							 | 
						|
								    /* Keep pointers to the insertion points for all levels. */
							 | 
						|
								    queue->last = ALLOC(DdQueueItem *, levels);
							 | 
						|
								    if (queue->last == NULL) {
							 | 
						|
									FREE(queue);
							 | 
						|
									return(NULL);
							 | 
						|
								    }
							 | 
						|
								    /* Use a hash table to test for uniqueness. */
							 | 
						|
								    if (numBuckets < 2) numBuckets = 2;
							 | 
						|
								    logSize = cuddComputeFloorLog2(numBuckets);
							 | 
						|
								    queue->numBuckets = 1 << logSize;
							 | 
						|
								    queue->shift = sizeof(int) * 8 - logSize;
							 | 
						|
								    queue->buckets = ALLOC(DdQueueItem *, queue->numBuckets);
							 | 
						|
								    if (queue->buckets == NULL) {
							 | 
						|
									FREE(queue->last);
							 | 
						|
									FREE(queue);
							 | 
						|
									return(NULL);
							 | 
						|
								    }
							 | 
						|
								    memset(queue->last, 0, levels * sizeof(DdQueueItem *));
							 | 
						|
								    memset(queue->buckets, 0, queue->numBuckets * sizeof(DdQueueItem *));
							 | 
						|
								    queue->first = NULL;
							 | 
						|
								    queue->freelist = NULL;
							 | 
						|
								    queue->levels = levels;
							 | 
						|
								    queue->itemsize = itemSize;
							 | 
						|
								    queue->size = 0;
							 | 
						|
								    queue->maxsize = queue->numBuckets * DD_MAX_SUBTABLE_DENSITY;
							 | 
						|
								    return(queue);
							 | 
						|
								
							 | 
						|
								} /* end of cuddLevelQueueInit */
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis    [Shuts down a level queue.]
							 | 
						|
								
							 | 
						|
								  Description [Shuts down a level queue and releases all the
							 | 
						|
								  associated memory.]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     [cuddLevelQueueInit]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								void
							 | 
						|
								cuddLevelQueueQuit(
							 | 
						|
								  DdLevelQueue * queue)
							 | 
						|
								{
							 | 
						|
								    DdQueueItem *item;
							 | 
						|
								
							 | 
						|
								    while (queue->freelist != NULL) {
							 | 
						|
									item = queue->freelist;
							 | 
						|
									queue->freelist = item->next;
							 | 
						|
									FREE(item);
							 | 
						|
								    }
							 | 
						|
								    while (queue->first != NULL) {
							 | 
						|
									item = (DdQueueItem *) queue->first;
							 | 
						|
									queue->first = item->next;
							 | 
						|
									FREE(item);
							 | 
						|
								    }
							 | 
						|
								    FREE(queue->buckets);
							 | 
						|
								    FREE(queue->last);
							 | 
						|
								    FREE(queue);
							 | 
						|
								    return;
							 | 
						|
								
							 | 
						|
								} /* end of cuddLevelQueueQuit */
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis    [Inserts a new key in a level queue.]
							 | 
						|
								
							 | 
						|
								  Description [Inserts a new key in a level queue. A new entry is
							 | 
						|
								  created in the queue only if the node is not already
							 | 
						|
								  enqueued. Returns a pointer to the queue item if successful; NULL
							 | 
						|
								  otherwise.]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     [cuddLevelQueueInit cuddLevelQueueDequeue]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								void *
							 | 
						|
								cuddLevelQueueEnqueue(
							 | 
						|
								  DdLevelQueue * queue /* level queue */,
							 | 
						|
								  void * key /* key to be enqueued */,
							 | 
						|
								  int  level /* level at which to insert */)
							 | 
						|
								{
							 | 
						|
								    DdQueueItem *item;
							 | 
						|
								
							 | 
						|
								#ifdef DD_DEBUG
							 | 
						|
								    assert(level < queue->levels);
							 | 
						|
								#endif
							 | 
						|
								    /* Check whether entry for this node exists. */
							 | 
						|
								    item = hashLookup(queue,key);
							 | 
						|
								    if (item != NULL) return(item);
							 | 
						|
								
							 | 
						|
								    /* Get a free item from either the free list or the memory manager. */
							 | 
						|
								    if (queue->freelist == NULL) {
							 | 
						|
									item = (DdQueueItem *) ALLOC(char, queue->itemsize);
							 | 
						|
									if (item == NULL)
							 | 
						|
									    return(NULL);
							 | 
						|
								    } else {
							 | 
						|
									item = queue->freelist;
							 | 
						|
									queue->freelist = item->next;
							 | 
						|
								    }
							 | 
						|
								    /* Initialize. */
							 | 
						|
								    memset(item, 0, queue->itemsize);
							 | 
						|
								    item->key = key;
							 | 
						|
								    /* Update stats. */
							 | 
						|
								    queue->size++;
							 | 
						|
								
							 | 
						|
								    if (queue->last[level]) {
							 | 
						|
									/* There are already items for this level in the queue. */
							 | 
						|
									item->next = queue->last[level]->next;
							 | 
						|
									queue->last[level]->next = item;
							 | 
						|
								    } else {
							 | 
						|
									/* There are no items at the current level.  Look for the first
							 | 
						|
									** non-empty level preceeding this one. */
							 | 
						|
								        int plevel = level;
							 | 
						|
									while (plevel != 0 && queue->last[plevel] == NULL)
							 | 
						|
									    plevel--;
							 | 
						|
									if (queue->last[plevel] == NULL) {
							 | 
						|
									    /* No element precedes this one in the queue. */
							 | 
						|
									    item->next = (DdQueueItem *) queue->first;
							 | 
						|
									    queue->first = item;
							 | 
						|
									} else {
							 | 
						|
									    item->next = queue->last[plevel]->next;
							 | 
						|
									    queue->last[plevel]->next = item;
							 | 
						|
									}
							 | 
						|
								    }
							 | 
						|
								    queue->last[level] = item;
							 | 
						|
								
							 | 
						|
								    /* Insert entry for the key in the hash table. */
							 | 
						|
								    if (hashInsert(queue,item) == 0) {
							 | 
						|
									return(NULL);
							 | 
						|
								    }
							 | 
						|
								    return(item);
							 | 
						|
								
							 | 
						|
								} /* end of cuddLevelQueueEnqueue */
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis    [Inserts the first key in a level queue.]
							 | 
						|
								
							 | 
						|
								  Description [Inserts the first key in a level queue. Returns a
							 | 
						|
								  pointer to the queue item if successful; NULL otherwise.]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     [cuddLevelQueueEnqueue]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								void *
							 | 
						|
								cuddLevelQueueFirst(
							 | 
						|
								  DdLevelQueue * queue /* level queue */,
							 | 
						|
								  void * key /* key to be enqueued */,
							 | 
						|
								  int  level /* level at which to insert */)
							 | 
						|
								{
							 | 
						|
								    DdQueueItem *item;
							 | 
						|
								
							 | 
						|
								#ifdef DD_DEBUG
							 | 
						|
								    assert(level < queue->levels);
							 | 
						|
								    /* Check whether entry for this node exists. */
							 | 
						|
								    item = hashLookup(queue,key);
							 | 
						|
								    assert(item == NULL);
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								    /* Get a free item from either the free list or the memory manager. */
							 | 
						|
								    if (queue->freelist == NULL) {
							 | 
						|
									item = (DdQueueItem *) ALLOC(char, queue->itemsize);
							 | 
						|
									if (item == NULL)
							 | 
						|
									    return(NULL);
							 | 
						|
								    } else {
							 | 
						|
									item = queue->freelist;
							 | 
						|
									queue->freelist = item->next;
							 | 
						|
								    }
							 | 
						|
								    /* Initialize. */
							 | 
						|
								    memset(item, 0, queue->itemsize);
							 | 
						|
								    item->key = key;
							 | 
						|
								    /* Update stats. */
							 | 
						|
								    queue->size = 1;
							 | 
						|
								
							 | 
						|
								    /* No element precedes this one in the queue. */
							 | 
						|
								    queue->first = item;
							 | 
						|
								    queue->last[level] = item;
							 | 
						|
								
							 | 
						|
								    /* Insert entry for the key in the hash table. */
							 | 
						|
								    if (hashInsert(queue,item) == 0) {
							 | 
						|
									return(NULL);
							 | 
						|
								    }
							 | 
						|
								    return(item);
							 | 
						|
								
							 | 
						|
								} /* end of cuddLevelQueueFirst */
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis    [Remove an item from the front of a level queue.]
							 | 
						|
								
							 | 
						|
								  Description [Remove an item from the front of a level queue.]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     [cuddLevelQueueEnqueue]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								void
							 | 
						|
								cuddLevelQueueDequeue(
							 | 
						|
								  DdLevelQueue * queue,
							 | 
						|
								  int  level)
							 | 
						|
								{
							 | 
						|
								    DdQueueItem *item = (DdQueueItem *) queue->first;
							 | 
						|
								
							 | 
						|
								    /* Delete from the hash table. */
							 | 
						|
								    hashDelete(queue,item);
							 | 
						|
								
							 | 
						|
								    /* Since we delete from the front, if this is the last item for
							 | 
						|
								    ** its level, there are no other items for the same level. */
							 | 
						|
								    if (queue->last[level] == item) {
							 | 
						|
									queue->last[level] = NULL;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    queue->first = item->next;
							 | 
						|
								    /* Put item on the free list. */
							 | 
						|
								    item->next = queue->freelist;
							 | 
						|
								    queue->freelist = item;
							 | 
						|
								    /* Update stats. */
							 | 
						|
								    queue->size--;
							 | 
						|
								    return;
							 | 
						|
								
							 | 
						|
								} /* end of cuddLevelQueueDequeue */
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Definition of static functions                                            */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis    [Looks up a key in the hash table of a level queue.]
							 | 
						|
								
							 | 
						|
								  Description [Looks up a key in the hash table of a level queue. Returns
							 | 
						|
								  a pointer to the item with the given key if the key is found; NULL
							 | 
						|
								  otherwise.]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     [cuddLevelQueueEnqueue hashInsert]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								static DdQueueItem *
							 | 
						|
								hashLookup(
							 | 
						|
								  DdLevelQueue * queue,
							 | 
						|
								  void * key)
							 | 
						|
								{
							 | 
						|
								    int posn;
							 | 
						|
								    DdQueueItem *item;
							 | 
						|
								
							 | 
						|
								    posn = lqHash(key,queue->shift);
							 | 
						|
								    item = queue->buckets[posn];
							 | 
						|
								
							 | 
						|
								    while (item != NULL) {
							 | 
						|
									if (item->key == key) {
							 | 
						|
									    return(item);
							 | 
						|
									}
							 | 
						|
									item = item->cnext;
							 | 
						|
								    }
							 | 
						|
								    return(NULL);
							 | 
						|
								
							 | 
						|
								} /* end of hashLookup */
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis    [Inserts an item in the hash table of a level queue.]
							 | 
						|
								
							 | 
						|
								  Description [Inserts an item in the hash table of a level queue. Returns
							 | 
						|
								  1 if successful; 0 otherwise. No check is performed to see if an item with
							 | 
						|
								  the same key is already in the hash table.]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     [cuddLevelQueueEnqueue]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								static int
							 | 
						|
								hashInsert(
							 | 
						|
								  DdLevelQueue * queue,
							 | 
						|
								  DdQueueItem * item)
							 | 
						|
								{
							 | 
						|
								    int result;
							 | 
						|
								    int posn;
							 | 
						|
								
							 | 
						|
								    if (queue->size > queue->maxsize) {
							 | 
						|
									result = hashResize(queue);
							 | 
						|
									if (result == 0) return(0);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    posn = lqHash(item->key,queue->shift);
							 | 
						|
								    item->cnext = queue->buckets[posn];
							 | 
						|
								    queue->buckets[posn] = item;
							 | 
						|
								
							 | 
						|
								    return(1);
							 | 
						|
								    
							 | 
						|
								} /* end of hashInsert */
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis    [Removes an item from the hash table of a level queue.]
							 | 
						|
								
							 | 
						|
								  Description [Removes an item from the hash table of a level queue.
							 | 
						|
								  Nothing is done if the item is not in the table.]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     [cuddLevelQueueDequeue hashInsert]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								static void
							 | 
						|
								hashDelete(
							 | 
						|
								  DdLevelQueue * queue,
							 | 
						|
								  DdQueueItem * item)
							 | 
						|
								{
							 | 
						|
								    int posn;
							 | 
						|
								    DdQueueItem *prevItem;
							 | 
						|
								
							 | 
						|
								    posn = lqHash(item->key,queue->shift);
							 | 
						|
								    prevItem = queue->buckets[posn];
							 | 
						|
								
							 | 
						|
								    if (prevItem == NULL) return;
							 | 
						|
								    if (prevItem == item) {
							 | 
						|
									queue->buckets[posn] = prevItem->cnext;
							 | 
						|
									return;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    while (prevItem->cnext != NULL) {
							 | 
						|
									if (prevItem->cnext == item) {
							 | 
						|
									    prevItem->cnext = item->cnext;
							 | 
						|
									    return;
							 | 
						|
									}
							 | 
						|
									prevItem = prevItem->cnext;
							 | 
						|
								    }
							 | 
						|
								    return;
							 | 
						|
								
							 | 
						|
								} /* end of hashDelete */
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis    [Resizes the hash table of a level queue.]
							 | 
						|
								
							 | 
						|
								  Description [Resizes the hash table of a level queue. Returns 1 if
							 | 
						|
								  successful; 0 otherwise.]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     [hashInsert]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								static int
							 | 
						|
								hashResize(
							 | 
						|
								  DdLevelQueue * queue)
							 | 
						|
								{
							 | 
						|
								    int j;
							 | 
						|
								    int posn;
							 | 
						|
								    DdQueueItem *item;
							 | 
						|
								    DdQueueItem *next;
							 | 
						|
								    int numBuckets;
							 | 
						|
								    DdQueueItem **buckets;
							 | 
						|
								    DdQueueItem **oldBuckets = queue->buckets;
							 | 
						|
								    int shift;
							 | 
						|
								    int oldNumBuckets = queue->numBuckets;
							 | 
						|
								    extern DD_OOMFP MMoutOfMemory;
							 | 
						|
								    DD_OOMFP saveHandler;
							 | 
						|
								
							 | 
						|
								    /* Compute the new size of the subtable. */
							 | 
						|
								    numBuckets = oldNumBuckets << 1;
							 | 
						|
								    saveHandler = MMoutOfMemory;
							 | 
						|
								    MMoutOfMemory = Cudd_OutOfMem;
							 | 
						|
								    buckets = queue->buckets = ALLOC(DdQueueItem *, numBuckets);
							 | 
						|
								    MMoutOfMemory = saveHandler;
							 | 
						|
								    if (buckets == NULL) {
							 | 
						|
									queue->maxsize <<= 1;
							 | 
						|
									return(1);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    queue->numBuckets = numBuckets;
							 | 
						|
								    shift = --(queue->shift);
							 | 
						|
								    queue->maxsize <<= 1;
							 | 
						|
								    memset(buckets, 0, numBuckets * sizeof(DdQueueItem *));
							 | 
						|
								    for (j = 0; j < oldNumBuckets; j++) {
							 | 
						|
									item = oldBuckets[j];
							 | 
						|
									while (item != NULL) {
							 | 
						|
									    next = item->cnext;
							 | 
						|
									    posn = lqHash(item->key, shift);
							 | 
						|
									    item->cnext = buckets[posn];
							 | 
						|
									    buckets[posn] = item;
							 | 
						|
									    item = next;
							 | 
						|
									}
							 | 
						|
								    }
							 | 
						|
								    FREE(oldBuckets);
							 | 
						|
								    return(1);
							 | 
						|
								
							 | 
						|
								} /* end of hashResize */
							 |