#include "util_hack.h"
#include "cuddInt.h"
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)) |
DdLevelQueue * | cuddLevelQueueInit (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 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) |
Variables | |
static char rcsid[] | DD_UNUSED = "$Id: cuddLevelQ.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $" |
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.
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 */
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.