src/bdd/cudd/cuddLevelQ.c File Reference

#include "util_hack.h"
#include "cuddInt.h"
Include dependency graph for cuddLevelQ.c:

Go to the source code of this file.

Defines

#define lqHash(key, shift)   (((unsigned)(key) * DD_P1) >> (shift))

Functions

static DdQueueItem *hashLookup ARGS ((DdLevelQueue *queue, void *key))
static int hashInsert ARGS ((DdLevelQueue *queue, DdQueueItem *item))
static int hashResize ARGS ((DdLevelQueue *queue))
DdLevelQueuecuddLevelQueueInit (int levels, int itemSize, int numBuckets)
void cuddLevelQueueQuit (DdLevelQueue *queue)
void * cuddLevelQueueEnqueue (DdLevelQueue *queue, void *key, int level)
void cuddLevelQueueDequeue (DdLevelQueue *queue, int level)
static DdQueueItemhashLookup (DdLevelQueue *queue, void *key)
static int hashInsert (DdLevelQueue *queue, DdQueueItem *item)
static void hashDelete (DdLevelQueue *queue, DdQueueItem *item)
static int hashResize (DdLevelQueue *queue)

Variables

static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $"

Define Documentation

#define lqHash ( key,
shift   )     (((unsigned)(key) * DD_P1) >> (shift))

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]

Definition at line 97 of file cuddLevelQ.c.


Function Documentation

static int hashResize ARGS ( (DdLevelQueue *queue)   )  [static]
static void hashDelete ARGS ( (DdLevelQueue *queue, DdQueueItem *item)   )  [static]
static DdQueueItem* hashLookup ARGS ( (DdLevelQueue *queue, void *key  )  [static]

AutomaticStart

void cuddLevelQueueDequeue ( DdLevelQueue queue,
int  level 
)

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]

Definition at line 323 of file cuddLevelQ.c.

00326 {
00327     DdQueueItem *item = (DdQueueItem *) queue->first;
00328 
00329     /* Delete from the hash table. */
00330     hashDelete(queue,item);
00331 
00332     /* Since we delete from the front, if this is the last item for
00333     ** its level, there are no other items for the same level. */
00334     if (queue->last[level] == item)
00335         queue->last[level] = NULL;
00336 
00337     queue->first = item->next;
00338     /* Put item on the free list. */
00339     item->next = queue->freelist;
00340     queue->freelist = item;
00341     /* Update stats. */
00342     queue->size--;
00343     return;
00344 
00345 } /* end of cuddLevelQueueDequeue */

void* cuddLevelQueueEnqueue ( DdLevelQueue queue,
void *  key,
int  level 
)

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]

Definition at line 251 of file cuddLevelQ.c.

00255 {
00256     int plevel;
00257     DdQueueItem *item;
00258 
00259 #ifdef DD_DEBUG
00260     assert(level < queue->levels);
00261 #endif
00262     /* Check whether entry for this node exists. */
00263     item = hashLookup(queue,key);
00264     if (item != NULL) return(item);
00265 
00266     /* Get a free item from either the free list or the memory manager. */
00267     if (queue->freelist == NULL) {
00268         item = (DdQueueItem *) ALLOC(char, queue->itemsize);
00269         if (item == NULL)
00270             return(NULL);
00271     } else {
00272         item = queue->freelist;
00273         queue->freelist = item->next;
00274     }
00275     /* Initialize. */
00276     memset(item, 0, queue->itemsize);
00277     item->key = key;
00278     /* Update stats. */
00279     queue->size++;
00280 
00281     if (queue->last[level]) {
00282         /* There are already items for this level in the queue. */
00283         item->next = queue->last[level]->next;
00284         queue->last[level]->next = item;
00285     } else {
00286         /* There are no items at the current level.  Look for the first
00287         ** non-empty level preceeding this one. */
00288         plevel = level;
00289         while (plevel != 0 && queue->last[plevel] == NULL)
00290             plevel--;
00291         if (queue->last[plevel] == NULL) {
00292             /* No element precedes this one in the queue. */
00293             item->next = (DdQueueItem *) queue->first;
00294             queue->first = item;
00295         } else {
00296             item->next = queue->last[plevel]->next;
00297             queue->last[plevel]->next = item;
00298         }
00299     }
00300     queue->last[level] = item;
00301 
00302     /* Insert entry for the key in the hash table. */
00303     if (hashInsert(queue,item) == 0) {
00304         return(NULL);
00305     }
00306     return(item);
00307 
00308 } /* end of cuddLevelQueueEnqueue */

DdLevelQueue* cuddLevelQueueInit ( int  levels,
int  itemSize,
int  numBuckets 
)

AutomaticEnd 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]

Definition at line 138 of file cuddLevelQ.c.

00142 {
00143     DdLevelQueue *queue;
00144     int logSize;
00145 
00146     queue = ALLOC(DdLevelQueue,1);
00147     if (queue == NULL)
00148         return(NULL);
00149 #ifdef __osf__
00150 #pragma pointer_size save
00151 #pragma pointer_size short
00152 #endif
00153     /* Keep pointers to the insertion points for all levels. */
00154     queue->last = ALLOC(DdQueueItem *, levels);
00155 #ifdef __osf__
00156 #pragma pointer_size restore
00157 #endif
00158     if (queue->last == NULL) {
00159         FREE(queue);
00160         return(NULL);
00161     }
00162     /* Use a hash table to test for uniqueness. */
00163     if (numBuckets < 2) numBuckets = 2;
00164     logSize = cuddComputeFloorLog2(numBuckets);
00165     queue->numBuckets = 1 << logSize;
00166     queue->shift = sizeof(int) * 8 - logSize;
00167 #ifdef __osf__
00168 #pragma pointer_size save
00169 #pragma pointer_size short
00170 #endif
00171     queue->buckets = ALLOC(DdQueueItem *, queue->numBuckets);
00172 #ifdef __osf__
00173 #pragma pointer_size restore
00174 #endif
00175     if (queue->buckets == NULL) {
00176         FREE(queue->last);
00177         FREE(queue);
00178         return(NULL);
00179     }
00180 #ifdef __osf__
00181 #pragma pointer_size save
00182 #pragma pointer_size short
00183 #endif
00184     memset(queue->last, 0, levels * sizeof(DdQueueItem *));
00185     memset(queue->buckets, 0, queue->numBuckets * sizeof(DdQueueItem *));
00186 #ifdef __osf__
00187 #pragma pointer_size restore
00188 #endif
00189     queue->first = NULL;
00190     queue->freelist = NULL;
00191     queue->levels = levels;
00192     queue->itemsize = itemSize;
00193     queue->size = 0;
00194     queue->maxsize = queue->numBuckets * DD_MAX_SUBTABLE_DENSITY;
00195     return(queue);
00196 
00197 } /* end of cuddLevelQueueInit */

void cuddLevelQueueQuit ( DdLevelQueue queue  ) 

Function********************************************************************

Synopsis [Shuts down a level queue.]

Description [Shuts down a level queue and releases all the associated memory.]

SideEffects [None]

SeeAlso [cuddLevelQueueInit]

Definition at line 213 of file cuddLevelQ.c.

00215 {
00216     DdQueueItem *item;
00217 
00218     while (queue->freelist != NULL) {
00219         item = queue->freelist;
00220         queue->freelist = item->next;
00221         FREE(item);
00222     }
00223     while (queue->first != NULL) {
00224         item = (DdQueueItem *) queue->first;
00225         queue->first = item->next;
00226         FREE(item);
00227     }
00228     FREE(queue->buckets);
00229     FREE(queue->last);
00230     FREE(queue);
00231     return;
00232 
00233 } /* end of cuddLevelQueueQuit */

static void hashDelete ( DdLevelQueue queue,
DdQueueItem item 
) [static]

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]

Definition at line 436 of file cuddLevelQ.c.

00439 {
00440     int posn;
00441     DdQueueItem *prevItem;
00442 
00443     posn = lqHash(item->key,queue->shift);
00444     prevItem = queue->buckets[posn];
00445 
00446     if (prevItem == NULL) return;
00447     if (prevItem == item) {
00448         queue->buckets[posn] = prevItem->cnext;
00449         return;
00450     }
00451 
00452     while (prevItem->cnext != NULL) {
00453         if (prevItem->cnext == item) {
00454             prevItem->cnext = item->cnext;
00455             return;
00456         }
00457         prevItem = prevItem->cnext;
00458     }
00459     return;
00460 
00461 } /* end of hashDelete */

static int hashInsert ( DdLevelQueue queue,
DdQueueItem item 
) [static]

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]

Definition at line 402 of file cuddLevelQ.c.

00405 {
00406     int result;
00407     int posn;
00408 
00409     if (queue->size > queue->maxsize) {
00410         result = hashResize(queue);
00411         if (result == 0) return(0);
00412     }
00413 
00414     posn = lqHash(item->key,queue->shift);
00415     item->cnext = queue->buckets[posn];
00416     queue->buckets[posn] = item;
00417 
00418     return(1);
00419     
00420 } /* end of hashInsert */

static DdQueueItem* hashLookup ( DdLevelQueue queue,
void *  key 
) [static]

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]

Definition at line 367 of file cuddLevelQ.c.

00370 {
00371     int posn;
00372     DdQueueItem *item;
00373 
00374     posn = lqHash(key,queue->shift);
00375     item = queue->buckets[posn];
00376 
00377     while (item != NULL) {
00378         if (item->key == key) {
00379             return(item);
00380         }
00381         item = item->cnext;
00382     }
00383     return(NULL);
00384 
00385 } /* end of hashLookup */

static int hashResize ( DdLevelQueue queue  )  [static]

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]

Definition at line 477 of file cuddLevelQ.c.

00479 {
00480     int j;
00481     int posn;
00482     DdQueueItem *item;
00483     DdQueueItem *next;
00484     int numBuckets;
00485 #ifdef __osf__
00486 #pragma pointer_size save
00487 #pragma pointer_size short
00488 #endif
00489     DdQueueItem **buckets;
00490     DdQueueItem **oldBuckets = queue->buckets;
00491 #ifdef __osf__
00492 #pragma pointer_size restore
00493 #endif
00494     int shift;
00495     int oldNumBuckets = queue->numBuckets;
00496     extern void (*MMoutOfMemory)(long);
00497     void (*saveHandler)(long);
00498 
00499     /* Compute the new size of the subtable. */
00500     numBuckets = oldNumBuckets << 1;
00501     saveHandler = MMoutOfMemory;
00502     MMoutOfMemory = Cudd_OutOfMem;
00503 #ifdef __osf__
00504 #pragma pointer_size save
00505 #pragma pointer_size short
00506 #endif
00507     buckets = queue->buckets = ALLOC(DdQueueItem *, numBuckets);
00508     if (buckets == NULL) {
00509         queue->maxsize <<= 1;
00510         return(1);
00511     }
00512 
00513     queue->numBuckets = numBuckets;
00514     shift = --(queue->shift);
00515     queue->maxsize <<= 1;
00516     memset(buckets, 0, numBuckets * sizeof(DdQueueItem *));
00517 #ifdef __osf__
00518 #pragma pointer_size restore
00519 #endif
00520     for (j = 0; j < oldNumBuckets; j++) {
00521         item = oldBuckets[j];
00522         while (item != NULL) {
00523             next = item->cnext;
00524             posn = lqHash(item->key, shift);
00525             item->cnext = buckets[posn];
00526             buckets[posn] = item;
00527             item = next;
00528         }
00529     }
00530     FREE(oldBuckets);
00531     return(1);
00532 
00533 } /* end of hashResize */


Variable Documentation

char rcsid [] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $" [static]

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:

Static procedures included in this module:

]

SeeAlso []

Author [Fabio Somenzi]

Copyright [This file was created at the University of Colorado at Boulder. The University of Colorado at Boulder makes no warranty about the suitability of this software for any purpose. It is presented on an AS IS basis.]

Definition at line 74 of file cuddLevelQ.c.


Generated on Tue Jan 5 12:18:55 2010 for abc70930 by  doxygen 1.6.1