abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddLevelQ.c File Reference
#include "misc/util/util_hack.h"
#include "cuddInt.h"

Go to the source code of this file.

Macros

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

Macro Definition 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 128 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 354 of file cuddLevelQ.c.

357 {
358  DdQueueItem *item = (DdQueueItem *) queue->first;
359 
360  /* Delete from the hash table. */
361  hashDelete(queue,item);
362 
363  /* Since we delete from the front, if this is the last item for
364  ** its level, there are no other items for the same level. */
365  if (queue->last[level] == item)
366  queue->last[level] = NULL;
367 
368  queue->first = item->next;
369  /* Put item on the free list. */
370  item->next = queue->freelist;
371  queue->freelist = item;
372  /* Update stats. */
373  queue->size--;
374  return;
375 
376 } /* end of cuddLevelQueueDequeue */
static void hashDelete(DdLevelQueue *queue, DdQueueItem *item)
Definition: cuddLevelQ.c:467
struct DdQueueItem * next
Definition: cuddInt.h:502
void * first
Definition: cuddInt.h:509
DdQueueItem * freelist
Definition: cuddInt.h:511
DdQueueItem ** last
Definition: cuddInt.h:510
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 282 of file cuddLevelQ.c.

286 {
287  int plevel;
288  DdQueueItem *item;
289 
290 #ifdef DD_DEBUG
291  assert(level < queue->levels);
292 #endif
293  /* Check whether entry for this node exists. */
294  item = hashLookup(queue,key);
295  if (item != NULL) return(item);
296 
297  /* Get a free item from either the free list or the memory manager. */
298  if (queue->freelist == NULL) {
299  item = (DdQueueItem *) ABC_ALLOC(char, queue->itemsize);
300  if (item == NULL)
301  return(NULL);
302  } else {
303  item = queue->freelist;
304  queue->freelist = item->next;
305  }
306  /* Initialize. */
307  memset(item, 0, queue->itemsize);
308  item->key = key;
309  /* Update stats. */
310  queue->size++;
311 
312  if (queue->last[level]) {
313  /* There are already items for this level in the queue. */
314  item->next = queue->last[level]->next;
315  queue->last[level]->next = item;
316  } else {
317  /* There are no items at the current level. Look for the first
318  ** non-empty level preceeding this one. */
319  plevel = level;
320  while (plevel != 0 && queue->last[plevel] == NULL)
321  plevel--;
322  if (queue->last[plevel] == NULL) {
323  /* No element precedes this one in the queue. */
324  item->next = (DdQueueItem *) queue->first;
325  queue->first = item;
326  } else {
327  item->next = queue->last[plevel]->next;
328  queue->last[plevel]->next = item;
329  }
330  }
331  queue->last[level] = item;
332 
333  /* Insert entry for the key in the hash table. */
334  if (hashInsert(queue,item) == 0) {
335  return(NULL);
336  }
337  return(item);
338 
339 } /* end of cuddLevelQueueEnqueue */
char * memset()
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
struct DdQueueItem * next
Definition: cuddInt.h:502
static int hashInsert(DdLevelQueue *queue, DdQueueItem *item)
Definition: cuddLevelQ.c:433
void * first
Definition: cuddInt.h:509
static DdQueueItem * hashLookup(DdLevelQueue *queue, void *key)
Definition: cuddLevelQ.c:398
enum keys key
DdQueueItem * freelist
Definition: cuddInt.h:511
#define assert(ex)
Definition: util_old.h:213
DdQueueItem ** last
Definition: cuddInt.h:510
void * key
Definition: cuddInt.h:504
int itemsize
Definition: cuddInt.h:514
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 169 of file cuddLevelQ.c.

173 {
174  DdLevelQueue *queue;
175  int logSize;
176 
177  queue = ABC_ALLOC(DdLevelQueue,1);
178  if (queue == NULL)
179  return(NULL);
180 #ifdef __osf__
181 #pragma pointer_size save
182 #pragma pointer_size short
183 #endif
184  /* Keep pointers to the insertion points for all levels. */
185  queue->last = ABC_ALLOC(DdQueueItem *, levels);
186 #ifdef __osf__
187 #pragma pointer_size restore
188 #endif
189  if (queue->last == NULL) {
190  ABC_FREE(queue);
191  return(NULL);
192  }
193  /* Use a hash table to test for uniqueness. */
194  if (numBuckets < 2) numBuckets = 2;
195  logSize = cuddComputeFloorLog2(numBuckets);
196  queue->numBuckets = 1 << logSize;
197  queue->shift = sizeof(int) * 8 - logSize;
198 #ifdef __osf__
199 #pragma pointer_size save
200 #pragma pointer_size short
201 #endif
202  queue->buckets = ABC_ALLOC(DdQueueItem *, queue->numBuckets);
203 #ifdef __osf__
204 #pragma pointer_size restore
205 #endif
206  if (queue->buckets == NULL) {
207  ABC_FREE(queue->last);
208  ABC_FREE(queue);
209  return(NULL);
210  }
211 #ifdef __osf__
212 #pragma pointer_size save
213 #pragma pointer_size short
214 #endif
215  memset(queue->last, 0, levels * sizeof(DdQueueItem *));
216  memset(queue->buckets, 0, queue->numBuckets * sizeof(DdQueueItem *));
217 #ifdef __osf__
218 #pragma pointer_size restore
219 #endif
220  queue->first = NULL;
221  queue->freelist = NULL;
222  queue->levels = levels;
223  queue->itemsize = itemSize;
224  queue->size = 0;
225  queue->maxsize = queue->numBuckets * DD_MAX_SUBTABLE_DENSITY;
226  return(queue);
227 
228 } /* end of cuddLevelQueueInit */
char * memset()
int maxsize
Definition: cuddInt.h:516
int levels
Definition: cuddInt.h:513
int numBuckets
Definition: cuddInt.h:517
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:126
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddCache.c:1079
void * first
Definition: cuddInt.h:509
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdQueueItem * freelist
Definition: cuddInt.h:511
DdQueueItem ** buckets
Definition: cuddInt.h:512
DdQueueItem ** last
Definition: cuddInt.h:510
int itemsize
Definition: cuddInt.h:514
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 244 of file cuddLevelQ.c.

246 {
247  DdQueueItem *item;
248 
249  while (queue->freelist != NULL) {
250  item = queue->freelist;
251  queue->freelist = item->next;
252  ABC_FREE(item);
253  }
254  while (queue->first != NULL) {
255  item = (DdQueueItem *) queue->first;
256  queue->first = item->next;
257  ABC_FREE(item);
258  }
259  ABC_FREE(queue->buckets);
260  ABC_FREE(queue->last);
261  ABC_FREE(queue);
262  return;
263 
264 } /* end of cuddLevelQueueQuit */
struct DdQueueItem * next
Definition: cuddInt.h:502
void * first
Definition: cuddInt.h:509
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdQueueItem * freelist
Definition: cuddInt.h:511
DdQueueItem ** buckets
Definition: cuddInt.h:512
DdQueueItem ** last
Definition: cuddInt.h:510
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 467 of file cuddLevelQ.c.

470 {
471  int posn;
472  DdQueueItem *prevItem;
473 
474  posn = lqHash(item->key,queue->shift);
475  prevItem = queue->buckets[posn];
476 
477  if (prevItem == NULL) return;
478  if (prevItem == item) {
479  queue->buckets[posn] = prevItem->cnext;
480  return;
481  }
482 
483  while (prevItem->cnext != NULL) {
484  if (prevItem->cnext == item) {
485  prevItem->cnext = item->cnext;
486  return;
487  }
488  prevItem = prevItem->cnext;
489  }
490  return;
491 
492 } /* end of hashDelete */
DdQueueItem ** buckets
Definition: cuddInt.h:512
#define lqHash(key, shift)
Definition: cuddLevelQ.c:128
struct DdQueueItem * cnext
Definition: cuddInt.h:503
void * key
Definition: cuddInt.h:504
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 433 of file cuddLevelQ.c.

436 {
437  int result;
438  int posn;
439 
440  if (queue->size > queue->maxsize) {
441  result = hashResize(queue);
442  if (result == 0) return(0);
443  }
444 
445  posn = lqHash(item->key,queue->shift);
446  item->cnext = queue->buckets[posn];
447  queue->buckets[posn] = item;
448 
449  return(1);
450 
451 } /* end of hashInsert */
int maxsize
Definition: cuddInt.h:516
static int hashResize(DdLevelQueue *queue)
Definition: cuddLevelQ.c:508
DdQueueItem ** buckets
Definition: cuddInt.h:512
static int result
Definition: cuddGenetic.c:125
#define lqHash(key, shift)
Definition: cuddLevelQ.c:128
struct DdQueueItem * cnext
Definition: cuddInt.h:503
void * key
Definition: cuddInt.h:504
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 398 of file cuddLevelQ.c.

401 {
402  int posn;
403  DdQueueItem *item;
404 
405  posn = lqHash(key,queue->shift);
406  item = queue->buckets[posn];
407 
408  while (item != NULL) {
409  if (item->key == key) {
410  return(item);
411  }
412  item = item->cnext;
413  }
414  return(NULL);
415 
416 } /* end of hashLookup */
enum keys key
DdQueueItem ** buckets
Definition: cuddInt.h:512
#define lqHash(key, shift)
Definition: cuddLevelQ.c:128
struct DdQueueItem * cnext
Definition: cuddInt.h:503
void * key
Definition: cuddInt.h:504
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 508 of file cuddLevelQ.c.

510 {
511  int j;
512  int posn;
513  DdQueueItem *item;
514  DdQueueItem *next;
515  int numBuckets;
516 #ifdef __osf__
517 #pragma pointer_size save
518 #pragma pointer_size short
519 #endif
520  DdQueueItem **buckets;
521  DdQueueItem **oldBuckets = queue->buckets;
522 #ifdef __osf__
523 #pragma pointer_size restore
524 #endif
525  int shift;
526  int oldNumBuckets = queue->numBuckets;
527  extern DD_OOMFP MMoutOfMemory;
528  DD_OOMFP saveHandler;
529 
530  /* Compute the new size of the subtable. */
531  numBuckets = oldNumBuckets << 1;
532  saveHandler = MMoutOfMemory;
533  MMoutOfMemory = Cudd_OutOfMem;
534 #ifdef __osf__
535 #pragma pointer_size save
536 #pragma pointer_size short
537 #endif
538  buckets = queue->buckets = ABC_ALLOC(DdQueueItem *, numBuckets);
539  MMoutOfMemory = saveHandler;
540  if (buckets == NULL) {
541  queue->maxsize <<= 1;
542  return(1);
543  }
544 
545  queue->numBuckets = numBuckets;
546  shift = --(queue->shift);
547  queue->maxsize <<= 1;
548  memset(buckets, 0, numBuckets * sizeof(DdQueueItem *));
549 #ifdef __osf__
550 #pragma pointer_size restore
551 #endif
552  for (j = 0; j < oldNumBuckets; j++) {
553  item = oldBuckets[j];
554  while (item != NULL) {
555  next = item->cnext;
556  posn = lqHash(item->key, shift);
557  item->cnext = buckets[posn];
558  buckets[posn] = item;
559  item = next;
560  }
561  }
562  ABC_FREE(oldBuckets);
563  return(1);
564 
565 } /* end of hashResize */
char * memset()
int maxsize
Definition: cuddInt.h:516
void(* DD_OOMFP)(long)
Definition: cudd.h:324
void Cudd_OutOfMem(long size)
Definition: cuddUtil.c:2837
int numBuckets
Definition: cuddInt.h:517
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
#define ABC_FREE(obj)
Definition: abc_global.h:232
DdQueueItem ** buckets
Definition: cuddInt.h:512
#define lqHash(key, shift)
Definition: cuddLevelQ.c:128
struct DdQueueItem * cnext
Definition: cuddInt.h:503
void * key
Definition: cuddInt.h:504
#define MMoutOfMemory
Definition: util_hack.h:38

Variable Documentation

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