src/cuBdd/cuddLevelQ.c File Reference

#include "util.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 DdQueueItemhashLookup (DdLevelQueue *queue, void *key)
static int hashInsert (DdLevelQueue *queue, DdQueueItem *item)
static void hashDelete (DdLevelQueue *queue, DdQueueItem *item)
static int hashResize (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)

Variables

static char rcsid[] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.13 2009/03/08 02:49:02 fabio 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 124 of file cuddLevelQ.c.


Function Documentation

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 350 of file cuddLevelQ.c.

00353 {
00354     DdQueueItem *item = (DdQueueItem *) queue->first;
00355 
00356     /* Delete from the hash table. */
00357     hashDelete(queue,item);
00358 
00359     /* Since we delete from the front, if this is the last item for
00360     ** its level, there are no other items for the same level. */
00361     if (queue->last[level] == item)
00362         queue->last[level] = NULL;
00363 
00364     queue->first = item->next;
00365     /* Put item on the free list. */
00366     item->next = queue->freelist;
00367     queue->freelist = item;
00368     /* Update stats. */
00369     queue->size--;
00370     return;
00371 
00372 } /* 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 278 of file cuddLevelQ.c.

00282 {
00283     int plevel;
00284     DdQueueItem *item;
00285 
00286 #ifdef DD_DEBUG
00287     assert(level < queue->levels);
00288 #endif
00289     /* Check whether entry for this node exists. */
00290     item = hashLookup(queue,key);
00291     if (item != NULL) return(item);
00292 
00293     /* Get a free item from either the free list or the memory manager. */
00294     if (queue->freelist == NULL) {
00295         item = (DdQueueItem *) ALLOC(char, queue->itemsize);
00296         if (item == NULL)
00297             return(NULL);
00298     } else {
00299         item = queue->freelist;
00300         queue->freelist = item->next;
00301     }
00302     /* Initialize. */
00303     memset(item, 0, queue->itemsize);
00304     item->key = key;
00305     /* Update stats. */
00306     queue->size++;
00307 
00308     if (queue->last[level]) {
00309         /* There are already items for this level in the queue. */
00310         item->next = queue->last[level]->next;
00311         queue->last[level]->next = item;
00312     } else {
00313         /* There are no items at the current level.  Look for the first
00314         ** non-empty level preceeding this one. */
00315         plevel = level;
00316         while (plevel != 0 && queue->last[plevel] == NULL)
00317             plevel--;
00318         if (queue->last[plevel] == NULL) {
00319             /* No element precedes this one in the queue. */
00320             item->next = (DdQueueItem *) queue->first;
00321             queue->first = item;
00322         } else {
00323             item->next = queue->last[plevel]->next;
00324             queue->last[plevel]->next = item;
00325         }
00326     }
00327     queue->last[level] = item;
00328 
00329     /* Insert entry for the key in the hash table. */
00330     if (hashInsert(queue,item) == 0) {
00331         return(NULL);
00332     }
00333     return(item);
00334 
00335 } /* 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 165 of file cuddLevelQ.c.

00169 {
00170     DdLevelQueue *queue;
00171     int logSize;
00172 
00173     queue = ALLOC(DdLevelQueue,1);
00174     if (queue == NULL)
00175         return(NULL);
00176 #ifdef __osf__
00177 #pragma pointer_size save
00178 #pragma pointer_size short
00179 #endif
00180     /* Keep pointers to the insertion points for all levels. */
00181     queue->last = ALLOC(DdQueueItem *, levels);
00182 #ifdef __osf__
00183 #pragma pointer_size restore
00184 #endif
00185     if (queue->last == NULL) {
00186         FREE(queue);
00187         return(NULL);
00188     }
00189     /* Use a hash table to test for uniqueness. */
00190     if (numBuckets < 2) numBuckets = 2;
00191     logSize = cuddComputeFloorLog2(numBuckets);
00192     queue->numBuckets = 1 << logSize;
00193     queue->shift = sizeof(int) * 8 - logSize;
00194 #ifdef __osf__
00195 #pragma pointer_size save
00196 #pragma pointer_size short
00197 #endif
00198     queue->buckets = ALLOC(DdQueueItem *, queue->numBuckets);
00199 #ifdef __osf__
00200 #pragma pointer_size restore
00201 #endif
00202     if (queue->buckets == NULL) {
00203         FREE(queue->last);
00204         FREE(queue);
00205         return(NULL);
00206     }
00207 #ifdef __osf__
00208 #pragma pointer_size save
00209 #pragma pointer_size short
00210 #endif
00211     memset(queue->last, 0, levels * sizeof(DdQueueItem *));
00212     memset(queue->buckets, 0, queue->numBuckets * sizeof(DdQueueItem *));
00213 #ifdef __osf__
00214 #pragma pointer_size restore
00215 #endif
00216     queue->first = NULL;
00217     queue->freelist = NULL;
00218     queue->levels = levels;
00219     queue->itemsize = itemSize;
00220     queue->size = 0;
00221     queue->maxsize = queue->numBuckets * DD_MAX_SUBTABLE_DENSITY;
00222     return(queue);
00223 
00224 } /* 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 240 of file cuddLevelQ.c.

00242 {
00243     DdQueueItem *item;
00244 
00245     while (queue->freelist != NULL) {
00246         item = queue->freelist;
00247         queue->freelist = item->next;
00248         FREE(item);
00249     }
00250     while (queue->first != NULL) {
00251         item = (DdQueueItem *) queue->first;
00252         queue->first = item->next;
00253         FREE(item);
00254     }
00255     FREE(queue->buckets);
00256     FREE(queue->last);
00257     FREE(queue);
00258     return;
00259 
00260 } /* 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 463 of file cuddLevelQ.c.

00466 {
00467     int posn;
00468     DdQueueItem *prevItem;
00469 
00470     posn = lqHash(item->key,queue->shift);
00471     prevItem = queue->buckets[posn];
00472 
00473     if (prevItem == NULL) return;
00474     if (prevItem == item) {
00475         queue->buckets[posn] = prevItem->cnext;
00476         return;
00477     }
00478 
00479     while (prevItem->cnext != NULL) {
00480         if (prevItem->cnext == item) {
00481             prevItem->cnext = item->cnext;
00482             return;
00483         }
00484         prevItem = prevItem->cnext;
00485     }
00486     return;
00487 
00488 } /* 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 429 of file cuddLevelQ.c.

00432 {
00433     int result;
00434     int posn;
00435 
00436     if (queue->size > queue->maxsize) {
00437         result = hashResize(queue);
00438         if (result == 0) return(0);
00439     }
00440 
00441     posn = lqHash(item->key,queue->shift);
00442     item->cnext = queue->buckets[posn];
00443     queue->buckets[posn] = item;
00444 
00445     return(1);
00446     
00447 } /* end of hashInsert */

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

AutomaticStart

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 394 of file cuddLevelQ.c.

00397 {
00398     int posn;
00399     DdQueueItem *item;
00400 
00401     posn = lqHash(key,queue->shift);
00402     item = queue->buckets[posn];
00403 
00404     while (item != NULL) {
00405         if (item->key == key) {
00406             return(item);
00407         }
00408         item = item->cnext;
00409     }
00410     return(NULL);
00411 
00412 } /* 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 504 of file cuddLevelQ.c.

00506 {
00507     int j;
00508     int posn;
00509     DdQueueItem *item;
00510     DdQueueItem *next;
00511     int numBuckets;
00512 #ifdef __osf__
00513 #pragma pointer_size save
00514 #pragma pointer_size short
00515 #endif
00516     DdQueueItem **buckets;
00517     DdQueueItem **oldBuckets = queue->buckets;
00518 #ifdef __osf__
00519 #pragma pointer_size restore
00520 #endif
00521     int shift;
00522     int oldNumBuckets = queue->numBuckets;
00523     extern DD_OOMFP MMoutOfMemory;
00524     DD_OOMFP saveHandler;
00525 
00526     /* Compute the new size of the subtable. */
00527     numBuckets = oldNumBuckets << 1;
00528     saveHandler = MMoutOfMemory;
00529     MMoutOfMemory = Cudd_OutOfMem;
00530 #ifdef __osf__
00531 #pragma pointer_size save
00532 #pragma pointer_size short
00533 #endif
00534     buckets = queue->buckets = ALLOC(DdQueueItem *, numBuckets);
00535     MMoutOfMemory = saveHandler;
00536     if (buckets == NULL) {
00537         queue->maxsize <<= 1;
00538         return(1);
00539     }
00540 
00541     queue->numBuckets = numBuckets;
00542     shift = --(queue->shift);
00543     queue->maxsize <<= 1;
00544     memset(buckets, 0, numBuckets * sizeof(DdQueueItem *));
00545 #ifdef __osf__
00546 #pragma pointer_size restore
00547 #endif
00548     for (j = 0; j < oldNumBuckets; j++) {
00549         item = oldBuckets[j];
00550         while (item != NULL) {
00551             next = item->cnext;
00552             posn = lqHash(item->key, shift);
00553             item->cnext = buckets[posn];
00554             buckets[posn] = item;
00555             item = next;
00556         }
00557     }
00558     FREE(oldBuckets);
00559     return(1);
00560 
00561 } /* end of hashResize */


Variable Documentation

char rcsid [] DD_UNUSED = "$Id: cuddLevelQ.c,v 1.13 2009/03/08 02:49:02 fabio 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 [Copyright (c) 1995-2004, 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.]

Definition at line 101 of file cuddLevelQ.c.


Generated on Tue Jan 12 13:57:20 2010 for glu-2.2 by  doxygen 1.6.1