src/cuBdd/cuddLCache.c File Reference

#include "util.h"
#include "cuddInt.h"
Include dependency graph for cuddLCache.c:

Go to the source code of this file.

Defines

#define DD_MAX_HASHTABLE_DENSITY   2
#define ddLCHash2(f, g, shift)   ((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (shift))
#define ddLCHash3(f, g, h, shift)   ddCHash2(f,g,h,shift)

Functions

static void cuddLocalCacheResize (DdLocalCache *cache)
static DD_INLINE unsigned int ddLCHash (DdNodePtr *key, unsigned int keysize, int shift)
static void cuddLocalCacheAddToList (DdLocalCache *cache)
static void cuddLocalCacheRemoveFromList (DdLocalCache *cache)
static int cuddHashTableResize (DdHashTable *hash)
static DD_INLINE DdHashItemcuddHashTableAlloc (DdHashTable *hash)
DdLocalCachecuddLocalCacheInit (DdManager *manager, unsigned int keySize, unsigned int cacheSize, unsigned int maxCacheSize)
void cuddLocalCacheQuit (DdLocalCache *cache)
void cuddLocalCacheInsert (DdLocalCache *cache, DdNodePtr *key, DdNode *value)
DdNodecuddLocalCacheLookup (DdLocalCache *cache, DdNodePtr *key)
void cuddLocalCacheClearDead (DdManager *manager)
void cuddLocalCacheClearAll (DdManager *manager)
DdHashTablecuddHashTableInit (DdManager *manager, unsigned int keySize, unsigned int initSize)
void cuddHashTableQuit (DdHashTable *hash)
int cuddHashTableInsert (DdHashTable *hash, DdNodePtr *key, DdNode *value, ptrint count)
DdNodecuddHashTableLookup (DdHashTable *hash, DdNodePtr *key)
int cuddHashTableInsert1 (DdHashTable *hash, DdNode *f, DdNode *value, ptrint count)
DdNodecuddHashTableLookup1 (DdHashTable *hash, DdNode *f)
int cuddHashTableInsert2 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *value, ptrint count)
DdNodecuddHashTableLookup2 (DdHashTable *hash, DdNode *f, DdNode *g)
int cuddHashTableInsert3 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h, DdNode *value, ptrint count)
DdNodecuddHashTableLookup3 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h)

Variables

static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.24 2009/03/08 02:49:02 fabio Exp $"

Define Documentation

#define DD_MAX_HASHTABLE_DENSITY   2

CFile***********************************************************************

FileName [cuddLCache.c]

PackageName [cudd]

Synopsis [Functions for local caches.]

Description [Internal procedures included in 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 82 of file cuddLCache.c.

#define ddLCHash2 ( f,
g,
shift   )     ((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (shift))

Macro***********************************************************************

Synopsis [Computes hash function for keys of two operands.]

Description []

SideEffects [None]

SeeAlso [ddLCHash3 ddLCHash]

Definition at line 122 of file cuddLCache.c.

#define ddLCHash3 ( f,
g,
h,
shift   )     ddCHash2(f,g,h,shift)

Macro***********************************************************************

Synopsis [Computes hash function for keys of three operands.]

Description []

SideEffects [None]

SeeAlso [ddLCHash2 ddLCHash]

Definition at line 138 of file cuddLCache.c.


Function Documentation

static DD_INLINE DdHashItem * cuddHashTableAlloc ( DdHashTable hash  )  [static]

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

Synopsis [Fast storage allocation for items in a hash table.]

Description [Fast storage allocation for items in a hash table. The first 4 bytes of a chunk contain a pointer to the next block; the rest contains DD_MEM_CHUNK spaces for hash items. Returns a pointer to a new item if successful; NULL is memory is full.]

SideEffects [None]

SeeAlso [cuddAllocNode cuddDynamicAllocNode]

Definition at line 1389 of file cuddLCache.c.

01391 {
01392     int i;
01393     unsigned int itemsize = hash->itemsize;
01394     extern DD_OOMFP MMoutOfMemory;
01395     DD_OOMFP saveHandler;
01396 #ifdef __osf__
01397 #pragma pointer_size save
01398 #pragma pointer_size short
01399 #endif
01400     DdHashItem **mem, *thisOne, *next, *item;
01401 
01402     if (hash->nextFree == NULL) {
01403         saveHandler = MMoutOfMemory;
01404         MMoutOfMemory = Cudd_OutOfMem;
01405         mem = (DdHashItem **) ALLOC(char,(DD_MEM_CHUNK+1) * itemsize);
01406         MMoutOfMemory = saveHandler;
01407 #ifdef __osf__
01408 #pragma pointer_size restore
01409 #endif
01410         if (mem == NULL) {
01411             if (hash->manager->stash != NULL) {
01412                 FREE(hash->manager->stash);
01413                 hash->manager->stash = NULL;
01414                 /* Inhibit resizing of tables. */
01415                 hash->manager->maxCacheHard = hash->manager->cacheSlots - 1;
01416                 hash->manager->cacheSlack = - (int) (hash->manager->cacheSlots + 1);
01417                 for (i = 0; i < hash->manager->size; i++) {
01418                     hash->manager->subtables[i].maxKeys <<= 2;
01419                 }
01420                 hash->manager->gcFrac = 0.2;
01421                 hash->manager->minDead =
01422                     (unsigned) (0.2 * (double) hash->manager->slots);
01423 #ifdef __osf__
01424 #pragma pointer_size save
01425 #pragma pointer_size short
01426 #endif
01427                 mem = (DdHashItem **) ALLOC(char,(DD_MEM_CHUNK+1) * itemsize);
01428 #ifdef __osf__
01429 #pragma pointer_size restore
01430 #endif
01431             }
01432             if (mem == NULL) {
01433                 (*MMoutOfMemory)((long)((DD_MEM_CHUNK + 1) * itemsize));
01434                 hash->manager->errorCode = CUDD_MEMORY_OUT;
01435                 return(NULL);
01436             }
01437         }
01438 
01439         mem[0] = (DdHashItem *) hash->memoryList;
01440         hash->memoryList = mem;
01441 
01442         thisOne = (DdHashItem *) ((char *) mem + itemsize);
01443         hash->nextFree = thisOne;
01444         for (i = 1; i < DD_MEM_CHUNK; i++) {
01445             next = (DdHashItem *) ((char *) thisOne + itemsize);
01446             thisOne->next = next;
01447             thisOne = next;
01448         }
01449 
01450         thisOne->next = NULL;
01451 
01452     }
01453     item = hash->nextFree;
01454     hash->nextFree = item->next;
01455     return(item);
01456 
01457 } /* end of cuddHashTableAlloc */

DdHashTable* cuddHashTableInit ( DdManager manager,
unsigned int  keySize,
unsigned int  initSize 
)

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

Synopsis [Initializes a hash table.]

Description [Initializes a hash table. Returns a pointer to the new table if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableQuit]

Definition at line 534 of file cuddLCache.c.

00538 {
00539     DdHashTable *hash;
00540     int logSize;
00541 
00542 #ifdef __osf__
00543 #pragma pointer_size save
00544 #pragma pointer_size short
00545 #endif
00546     hash = ALLOC(DdHashTable, 1);
00547     if (hash == NULL) {
00548         manager->errorCode = CUDD_MEMORY_OUT;
00549         return(NULL);
00550     }
00551     hash->keysize = keySize;
00552     hash->manager = manager;
00553     hash->memoryList = NULL;
00554     hash->nextFree = NULL;
00555     hash->itemsize = (keySize + 1) * sizeof(DdNode *) +
00556         sizeof(ptrint) + sizeof(DdHashItem *);
00557     /* We have to guarantee that the shift be < 32. */
00558     if (initSize < 2) initSize = 2;
00559     logSize = cuddComputeFloorLog2(initSize);
00560     hash->numBuckets = 1 << logSize;
00561     hash->shift = sizeof(int) * 8 - logSize;
00562     hash->bucket = ALLOC(DdHashItem *, hash->numBuckets);
00563     if (hash->bucket == NULL) {
00564         manager->errorCode = CUDD_MEMORY_OUT;
00565         FREE(hash);
00566         return(NULL);
00567     }
00568     memset(hash->bucket, 0, hash->numBuckets * sizeof(DdHashItem *));
00569     hash->size = 0;
00570     hash->maxsize = hash->numBuckets * DD_MAX_HASHTABLE_DENSITY;
00571 #ifdef __osf__
00572 #pragma pointer_size restore
00573 #endif
00574     return(hash);
00575 
00576 } /* end of cuddHashTableInit */

int cuddHashTableInsert ( DdHashTable hash,
DdNodePtr key,
DdNode value,
ptrint  count 
)

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

Synopsis [Inserts an item in a hash table.]

Description [Inserts an item in a hash table when the key has more than three pointers. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [[cuddHashTableInsert1 cuddHashTableInsert2 cuddHashTableInsert3 cuddHashTableLookup]

Definition at line 644 of file cuddLCache.c.

00649 {
00650     int result;
00651     unsigned int posn;
00652     DdHashItem *item;
00653     unsigned int i;
00654 
00655 #ifdef DD_DEBUG
00656     assert(hash->keysize > 3);
00657 #endif
00658 
00659     if (hash->size > hash->maxsize) {
00660         result = cuddHashTableResize(hash);
00661         if (result == 0) return(0);
00662     }
00663     item = cuddHashTableAlloc(hash);
00664     if (item == NULL) return(0);
00665     hash->size++;
00666     item->value = value;
00667     cuddRef(value);
00668     item->count = count;
00669     for (i = 0; i < hash->keysize; i++) {
00670         item->key[i] = key[i];
00671     }
00672     posn = ddLCHash(key,hash->keysize,hash->shift);
00673     item->next = hash->bucket[posn];
00674     hash->bucket[posn] = item;
00675 
00676     return(1);
00677 
00678 } /* end of cuddHashTableInsert */

int cuddHashTableInsert1 ( DdHashTable hash,
DdNode f,
DdNode value,
ptrint  count 
)

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

Synopsis [Inserts an item in a hash table.]

Description [Inserts an item in a hash table when the key is one pointer. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableInsert cuddHashTableInsert2 cuddHashTableInsert3 cuddHashTableLookup1]

Definition at line 763 of file cuddLCache.c.

00768 {
00769     int result;
00770     unsigned int posn;
00771     DdHashItem *item;
00772 
00773 #ifdef DD_DEBUG
00774     assert(hash->keysize == 1);
00775 #endif
00776 
00777     if (hash->size > hash->maxsize) {
00778         result = cuddHashTableResize(hash);
00779         if (result == 0) return(0);
00780     }
00781     item = cuddHashTableAlloc(hash);
00782     if (item == NULL) return(0);
00783     hash->size++;
00784     item->value = value;
00785     cuddRef(value);
00786     item->count = count;
00787     item->key[0] = f;
00788     posn = ddLCHash2(f,f,hash->shift);
00789     item->next = hash->bucket[posn];
00790     hash->bucket[posn] = item;
00791 
00792     return(1);
00793 
00794 } /* end of cuddHashTableInsert1 */

int cuddHashTableInsert2 ( DdHashTable hash,
DdNode f,
DdNode g,
DdNode value,
ptrint  count 
)

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

Synopsis [Inserts an item in a hash table.]

Description [Inserts an item in a hash table when the key is composed of two pointers. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableInsert cuddHashTableInsert1 cuddHashTableInsert3 cuddHashTableLookup2]

Definition at line 870 of file cuddLCache.c.

00876 {
00877     int result;
00878     unsigned int posn;
00879     DdHashItem *item;
00880 
00881 #ifdef DD_DEBUG
00882     assert(hash->keysize == 2);
00883 #endif
00884 
00885     if (hash->size > hash->maxsize) {
00886         result = cuddHashTableResize(hash);
00887         if (result == 0) return(0);
00888     }
00889     item = cuddHashTableAlloc(hash);
00890     if (item == NULL) return(0);
00891     hash->size++;
00892     item->value = value;
00893     cuddRef(value);
00894     item->count = count;
00895     item->key[0] = f;
00896     item->key[1] = g;
00897     posn = ddLCHash2(f,g,hash->shift);
00898     item->next = hash->bucket[posn];
00899     hash->bucket[posn] = item;
00900 
00901     return(1);
00902 
00903 } /* end of cuddHashTableInsert2 */

int cuddHashTableInsert3 ( DdHashTable hash,
DdNode f,
DdNode g,
DdNode h,
DdNode value,
ptrint  count 
)

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

Synopsis [Inserts an item in a hash table.]

Description [Inserts an item in a hash table when the key is composed of three pointers. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableInsert cuddHashTableInsert1 cuddHashTableInsert2 cuddHashTableLookup3]

Definition at line 980 of file cuddLCache.c.

00987 {
00988     int result;
00989     unsigned int posn;
00990     DdHashItem *item;
00991 
00992 #ifdef DD_DEBUG
00993     assert(hash->keysize == 3);
00994 #endif
00995 
00996     if (hash->size > hash->maxsize) {
00997         result = cuddHashTableResize(hash);
00998         if (result == 0) return(0);
00999     }
01000     item = cuddHashTableAlloc(hash);
01001     if (item == NULL) return(0);
01002     hash->size++;
01003     item->value = value;
01004     cuddRef(value);
01005     item->count = count;
01006     item->key[0] = f;
01007     item->key[1] = g;
01008     item->key[2] = h;
01009     posn = ddLCHash3(f,g,h,hash->shift);
01010     item->next = hash->bucket[posn];
01011     hash->bucket[posn] = item;
01012 
01013     return(1);
01014 
01015 } /* end of cuddHashTableInsert3 */

DdNode* cuddHashTableLookup ( DdHashTable hash,
DdNodePtr key 
)

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

Synopsis [Looks up a key in a hash table.]

Description [Looks up a key consisting of more than three pointers in a hash table. Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the value of the entry is dereferenced, and the entry is returned to the free list.]

SideEffects [None]

SeeAlso [cuddHashTableLookup1 cuddHashTableLookup2 cuddHashTableLookup3 cuddHashTableInsert]

Definition at line 699 of file cuddLCache.c.

00702 {
00703     unsigned int posn;
00704     DdHashItem *item, *prev;
00705     unsigned int i, keysize;
00706 
00707 #ifdef DD_DEBUG
00708     assert(hash->keysize > 3);
00709 #endif
00710 
00711     posn = ddLCHash(key,hash->keysize,hash->shift);
00712     item = hash->bucket[posn];
00713     prev = NULL;
00714 
00715     keysize = hash->keysize;
00716     while (item != NULL) {
00717         DdNodePtr *key2 = item->key;
00718         int equal = 1;
00719         for (i = 0; i < keysize; i++) {
00720             if (key[i] != key2[i]) {
00721                 equal = 0;
00722                 break;
00723             }
00724         }
00725         if (equal) {
00726             DdNode *value = item->value;
00727             cuddSatDec(item->count);
00728             if (item->count == 0) {
00729                 cuddDeref(value);
00730                 if (prev == NULL) {
00731                     hash->bucket[posn] = item->next;
00732                 } else {
00733                     prev->next = item->next;
00734                 }
00735                 item->next = hash->nextFree;
00736                 hash->nextFree = item;
00737                 hash->size--;
00738             }
00739             return(value);
00740         }
00741         prev = item;
00742         item = item->next;
00743     }
00744     return(NULL);
00745 
00746 } /* end of cuddHashTableLookup */

DdNode* cuddHashTableLookup1 ( DdHashTable hash,
DdNode f 
)

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

Synopsis [Looks up a key consisting of one pointer in a hash table.]

Description [Looks up a key consisting of one pointer in a hash table. Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the value of the entry is dereferenced, and the entry is returned to the free list.]

SideEffects [None]

SeeAlso [cuddHashTableLookup cuddHashTableLookup2 cuddHashTableLookup3 cuddHashTableInsert1]

Definition at line 815 of file cuddLCache.c.

00818 {
00819     unsigned int posn;
00820     DdHashItem *item, *prev;
00821 
00822 #ifdef DD_DEBUG
00823     assert(hash->keysize == 1);
00824 #endif
00825 
00826     posn = ddLCHash2(f,f,hash->shift);
00827     item = hash->bucket[posn];
00828     prev = NULL;
00829 
00830     while (item != NULL) {
00831         DdNodePtr *key = item->key;
00832         if (f == key[0]) {
00833             DdNode *value = item->value;
00834             cuddSatDec(item->count);
00835             if (item->count == 0) {
00836                 cuddDeref(value);
00837                 if (prev == NULL) {
00838                     hash->bucket[posn] = item->next;
00839                 } else {
00840                     prev->next = item->next;
00841                 }
00842                 item->next = hash->nextFree;
00843                 hash->nextFree = item;
00844                 hash->size--;
00845             }
00846             return(value);
00847         }
00848         prev = item;
00849         item = item->next;
00850     }
00851     return(NULL);
00852 
00853 } /* end of cuddHashTableLookup1 */

DdNode* cuddHashTableLookup2 ( DdHashTable hash,
DdNode f,
DdNode g 
)

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

Synopsis [Looks up a key consisting of two pointers in a hash table.]

Description [Looks up a key consisting of two pointer in a hash table. Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the value of the entry is dereferenced, and the entry is returned to the free list.]

SideEffects [None]

SeeAlso [cuddHashTableLookup cuddHashTableLookup1 cuddHashTableLookup3 cuddHashTableInsert2]

Definition at line 924 of file cuddLCache.c.

00928 {
00929     unsigned int posn;
00930     DdHashItem *item, *prev;
00931 
00932 #ifdef DD_DEBUG
00933     assert(hash->keysize == 2);
00934 #endif
00935 
00936     posn = ddLCHash2(f,g,hash->shift);
00937     item = hash->bucket[posn];
00938     prev = NULL;
00939 
00940     while (item != NULL) {
00941         DdNodePtr *key = item->key;
00942         if ((f == key[0]) && (g == key[1])) {
00943             DdNode *value = item->value;
00944             cuddSatDec(item->count);
00945             if (item->count == 0) {
00946                 cuddDeref(value);
00947                 if (prev == NULL) {
00948                     hash->bucket[posn] = item->next;
00949                 } else {
00950                     prev->next = item->next;
00951                 }
00952                 item->next = hash->nextFree;
00953                 hash->nextFree = item;
00954                 hash->size--;
00955             }
00956             return(value);
00957         }
00958         prev = item;
00959         item = item->next;
00960     }
00961     return(NULL);
00962 
00963 } /* end of cuddHashTableLookup2 */

DdNode* cuddHashTableLookup3 ( DdHashTable hash,
DdNode f,
DdNode g,
DdNode h 
)

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

Synopsis [Looks up a key consisting of three pointers in a hash table.]

Description [Looks up a key consisting of three pointers in a hash table. Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the value of the entry is dereferenced, and the entry is returned to the free list.]

SideEffects [None]

SeeAlso [cuddHashTableLookup cuddHashTableLookup1 cuddHashTableLookup2 cuddHashTableInsert3]

Definition at line 1036 of file cuddLCache.c.

01041 {
01042     unsigned int posn;
01043     DdHashItem *item, *prev;
01044 
01045 #ifdef DD_DEBUG
01046     assert(hash->keysize == 3);
01047 #endif
01048 
01049     posn = ddLCHash3(f,g,h,hash->shift);
01050     item = hash->bucket[posn];
01051     prev = NULL;
01052 
01053     while (item != NULL) {
01054         DdNodePtr *key = item->key;
01055         if ((f == key[0]) && (g == key[1]) && (h == key[2])) {
01056             DdNode *value = item->value;
01057             cuddSatDec(item->count);
01058             if (item->count == 0) {
01059                 cuddDeref(value);
01060                 if (prev == NULL) {
01061                     hash->bucket[posn] = item->next;
01062                 } else {
01063                     prev->next = item->next;
01064                 }
01065                 item->next = hash->nextFree;
01066                 hash->nextFree = item;
01067                 hash->size--;
01068             }
01069             return(value);
01070         }
01071         prev = item;
01072         item = item->next;
01073     }
01074     return(NULL);
01075 
01076 } /* end of cuddHashTableLookup3 */

void cuddHashTableQuit ( DdHashTable hash  ) 

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

Synopsis [Shuts down a hash table.]

Description [Shuts down a hash table, dereferencing all the values.]

SideEffects [None]

SeeAlso [cuddHashTableInit]

Definition at line 591 of file cuddLCache.c.

00593 {
00594 #ifdef __osf__
00595 #pragma pointer_size save
00596 #pragma pointer_size short
00597 #endif
00598     unsigned int i;
00599     DdManager *dd = hash->manager;
00600     DdHashItem *bucket;
00601     DdHashItem **memlist, **nextmem;
00602     unsigned int numBuckets = hash->numBuckets;
00603 
00604     for (i = 0; i < numBuckets; i++) {
00605         bucket = hash->bucket[i];
00606         while (bucket != NULL) {
00607             Cudd_RecursiveDeref(dd, bucket->value);
00608             bucket = bucket->next;
00609         }
00610     }
00611 
00612     memlist = hash->memoryList;
00613     while (memlist != NULL) {
00614         nextmem = (DdHashItem **) memlist[0];
00615         FREE(memlist);
00616         memlist = nextmem;
00617     }
00618 
00619     FREE(hash->bucket);
00620     FREE(hash);
00621 #ifdef __osf__
00622 #pragma pointer_size restore
00623 #endif
00624 
00625     return;
00626 
00627 } /* end of cuddHashTableQuit */

static int cuddHashTableResize ( DdHashTable hash  )  [static]

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

Synopsis [Resizes a hash table.]

Description [Resizes a hash table. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableInsert]

Definition at line 1273 of file cuddLCache.c.

01275 {
01276     int j;
01277     unsigned int posn;
01278     DdHashItem *item;
01279     DdHashItem *next;
01280 #ifdef __osf__
01281 #pragma pointer_size save
01282 #pragma pointer_size short
01283 #endif
01284     DdNode **key;
01285     int numBuckets;
01286     DdHashItem **buckets;
01287     DdHashItem **oldBuckets = hash->bucket;
01288 #ifdef __osf__
01289 #pragma pointer_size restore
01290 #endif
01291     int shift;
01292     int oldNumBuckets = hash->numBuckets;
01293     extern DD_OOMFP MMoutOfMemory;
01294     DD_OOMFP saveHandler;
01295 
01296     /* Compute the new size of the table. */
01297     numBuckets = oldNumBuckets << 1;
01298     saveHandler = MMoutOfMemory;
01299     MMoutOfMemory = Cudd_OutOfMem;
01300 #ifdef __osf__
01301 #pragma pointer_size save
01302 #pragma pointer_size short
01303 #endif
01304     buckets = ALLOC(DdHashItem *, numBuckets);
01305     MMoutOfMemory = saveHandler;
01306     if (buckets == NULL) {
01307         hash->maxsize <<= 1;
01308         return(1);
01309     }
01310 
01311     hash->bucket = buckets;
01312     hash->numBuckets = numBuckets;
01313     shift = --(hash->shift);
01314     hash->maxsize <<= 1;
01315     memset(buckets, 0, numBuckets * sizeof(DdHashItem *));
01316 #ifdef __osf__
01317 #pragma pointer_size restore
01318 #endif
01319     if (hash->keysize == 1) {
01320         for (j = 0; j < oldNumBuckets; j++) {
01321             item = oldBuckets[j];
01322             while (item != NULL) {
01323                 next = item->next;
01324                 key = item->key;
01325                 posn = ddLCHash2(key[0], key[0], shift);
01326                 item->next = buckets[posn];
01327                 buckets[posn] = item;
01328                 item = next;
01329             }
01330         }
01331     } else if (hash->keysize == 2) {
01332         for (j = 0; j < oldNumBuckets; j++) {
01333             item = oldBuckets[j];
01334             while (item != NULL) {
01335                 next = item->next;
01336                 key = item->key;
01337                 posn = ddLCHash2(key[0], key[1], shift);
01338                 item->next = buckets[posn];
01339                 buckets[posn] = item;
01340                 item = next;
01341             }
01342         }
01343     } else if (hash->keysize == 3) {
01344         for (j = 0; j < oldNumBuckets; j++) {
01345             item = oldBuckets[j];
01346             while (item != NULL) {
01347                 next = item->next;
01348                 key = item->key;
01349                 posn = ddLCHash3(key[0], key[1], key[2], shift);
01350                 item->next = buckets[posn];
01351                 buckets[posn] = item;
01352                 item = next;
01353             }
01354         }
01355     } else {
01356         for (j = 0; j < oldNumBuckets; j++) {
01357             item = oldBuckets[j];
01358             while (item != NULL) {
01359                 next = item->next;
01360                 posn = ddLCHash(item->key, hash->keysize, shift);
01361                 item->next = buckets[posn];
01362                 buckets[posn] = item;
01363                 item = next;
01364             }
01365         }
01366     }
01367     FREE(oldBuckets);
01368     return(1);
01369 
01370 } /* end of cuddHashTableResize */

static void cuddLocalCacheAddToList ( DdLocalCache cache  )  [static]

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

Synopsis [Inserts a local cache in the manager list.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 1207 of file cuddLCache.c.

01209 {
01210     DdManager *manager = cache->manager;
01211 
01212     cache->next = manager->localCaches;
01213     manager->localCaches = cache;
01214     return;
01215 
01216 } /* end of cuddLocalCacheAddToList */

void cuddLocalCacheClearAll ( DdManager manager  ) 

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

Synopsis [Clears the local caches of a manager.]

Description [Clears the local caches of a manager. Used before reordering.]

SideEffects [None]

SeeAlso []

Definition at line 400 of file cuddLCache.c.

00402 {
00403     DdLocalCache *cache = manager->localCaches;
00404 
00405     while (cache != NULL) {
00406         memset(cache->item, 0, cache->slots * cache->itemsize);
00407         cache = cache->next;
00408     }
00409     return;
00410 
00411 } /* end of cuddLocalCacheClearAll */

void cuddLocalCacheClearDead ( DdManager manager  ) 

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

Synopsis [Clears the dead entries of the local caches of a manager.]

Description [Clears the dead entries of the local caches of a manager. Used during garbage collection.]

SideEffects [None]

SeeAlso []

Definition at line 348 of file cuddLCache.c.

00350 {
00351     DdLocalCache *cache = manager->localCaches;
00352     unsigned int keysize;
00353     unsigned int itemsize;
00354     unsigned int slots;
00355     DdLocalCacheItem *item;
00356     DdNodePtr *key;
00357     unsigned int i, j;
00358 
00359     while (cache != NULL) {
00360         keysize = cache->keysize;
00361         itemsize = cache->itemsize;
00362         slots = cache->slots;
00363         item = cache->item;
00364         for (i = 0; i < slots; i++) {
00365             if (item->value != NULL) {
00366                 if (Cudd_Regular(item->value)->ref == 0) {
00367                     item->value = NULL;
00368                 } else {
00369                     key = item->key;
00370                     for (j = 0; j < keysize; j++) {
00371                         if (Cudd_Regular(key[j])->ref == 0) {
00372                             item->value = NULL;
00373                             break;
00374                         }
00375                     }
00376                 }
00377             }
00378             item = (DdLocalCacheItem *) ((char *) item + itemsize);
00379         }
00380         cache = cache->next;
00381     }
00382     return;
00383 
00384 } /* end of cuddLocalCacheClearDead */

DdLocalCache* cuddLocalCacheInit ( DdManager manager,
unsigned int  keySize,
unsigned int  cacheSize,
unsigned int  maxCacheSize 
)

AutomaticEnd Function********************************************************************

Synopsis [Initializes a local computed table.]

Description [Initializes a computed table. Returns a pointer the the new local cache in case of success; NULL otherwise.]

SideEffects [None]

SeeAlso [cuddInitCache]

Definition at line 179 of file cuddLCache.c.

00184 {
00185     DdLocalCache *cache;
00186     int logSize;
00187 
00188     cache = ALLOC(DdLocalCache,1);
00189     if (cache == NULL) {
00190         manager->errorCode = CUDD_MEMORY_OUT;
00191         return(NULL);
00192     }
00193     cache->manager = manager;
00194     cache->keysize = keySize;
00195     cache->itemsize = (keySize + 1) * sizeof(DdNode *);
00196 #ifdef DD_CACHE_PROFILE
00197     cache->itemsize += sizeof(ptrint);
00198 #endif
00199     logSize = cuddComputeFloorLog2(ddMax(cacheSize,manager->slots/2));
00200     cacheSize = 1 << logSize;
00201     cache->item = (DdLocalCacheItem *)
00202         ALLOC(char, cacheSize * cache->itemsize);
00203     if (cache->item == NULL) {
00204         manager->errorCode = CUDD_MEMORY_OUT;
00205         FREE(cache);
00206         return(NULL);
00207     }
00208     cache->slots = cacheSize;
00209     cache->shift = sizeof(int) * 8 - logSize;
00210     cache->maxslots = ddMin(maxCacheSize,manager->slots);
00211     cache->minHit = manager->minHit;
00212     /* Initialize to avoid division by 0 and immediate resizing. */
00213     cache->lookUps = (double) (int) (cacheSize * cache->minHit + 1);
00214     cache->hits = 0;
00215     manager->memused += cacheSize * cache->itemsize + sizeof(DdLocalCache);
00216 
00217     /* Initialize the cache. */
00218     memset(cache->item, 0, cacheSize * cache->itemsize);
00219 
00220     /* Add to manager's list of local caches for GC. */
00221     cuddLocalCacheAddToList(cache);
00222 
00223     return(cache);
00224 
00225 } /* end of cuddLocalCacheInit */

void cuddLocalCacheInsert ( DdLocalCache cache,
DdNodePtr key,
DdNode value 
)

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

Synopsis [Inserts a result in a local cache.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 268 of file cuddLCache.c.

00272 {
00273     unsigned int posn;
00274     DdLocalCacheItem *entry;
00275 
00276     posn = ddLCHash(key,cache->keysize,cache->shift);
00277     entry = (DdLocalCacheItem *) ((char *) cache->item +
00278                                   posn * cache->itemsize);
00279     memcpy(entry->key,key,cache->keysize * sizeof(DdNode *));
00280     entry->value = value;
00281 #ifdef DD_CACHE_PROFILE
00282     entry->count++;
00283 #endif
00284 
00285 } /* end of cuddLocalCacheInsert */

DdNode* cuddLocalCacheLookup ( DdLocalCache cache,
DdNodePtr key 
)

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

Synopsis [Looks up in a local cache.]

Description [Looks up in a local cache. Returns the result if found; it returns NULL if no result is found.]

SideEffects [None]

SeeAlso []

Definition at line 301 of file cuddLCache.c.

00304 {
00305     unsigned int posn;
00306     DdLocalCacheItem *entry;
00307     DdNode *value;
00308 
00309     cache->lookUps++;
00310     posn = ddLCHash(key,cache->keysize,cache->shift);
00311     entry = (DdLocalCacheItem *) ((char *) cache->item +
00312                                   posn * cache->itemsize);
00313     if (entry->value != NULL &&
00314         memcmp(key,entry->key,cache->keysize*sizeof(DdNode *)) == 0) {
00315         cache->hits++;
00316         value = Cudd_Regular(entry->value);
00317         if (value->ref == 0) {
00318             cuddReclaim(cache->manager,value);
00319         }
00320         return(entry->value);
00321     }
00322 
00323     /* Cache miss: decide whether to resize */
00324 
00325     if (cache->slots < cache->maxslots &&
00326         cache->hits > cache->lookUps * cache->minHit) {
00327         cuddLocalCacheResize(cache);
00328     }
00329 
00330     return(NULL);
00331 
00332 } /* end of cuddLocalCacheLookup */

void cuddLocalCacheQuit ( DdLocalCache cache  ) 

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

Synopsis [Shuts down a local computed table.]

Description [Initializes the computed table. It is called by Cudd_Init. Returns a pointer the the new local cache in case of success; NULL otherwise.]

SideEffects [None]

SeeAlso [cuddLocalCacheInit]

Definition at line 242 of file cuddLCache.c.

00244 {
00245     cache->manager->memused -=
00246         cache->slots * cache->itemsize + sizeof(DdLocalCache);
00247     cuddLocalCacheRemoveFromList(cache);
00248     FREE(cache->item);
00249     FREE(cache);
00250 
00251     return;
00252 
00253 } /* end of cuddLocalCacheQuit */

static void cuddLocalCacheRemoveFromList ( DdLocalCache cache  )  [static]

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

Synopsis [Removes a local cache from the manager list.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 1231 of file cuddLCache.c.

01233 {
01234     DdManager *manager = cache->manager;
01235 #ifdef __osf__
01236 #pragma pointer_size save
01237 #pragma pointer_size short
01238 #endif
01239     DdLocalCache **prevCache, *nextCache;
01240 #ifdef __osf__
01241 #pragma pointer_size restore
01242 #endif
01243 
01244     prevCache = &(manager->localCaches);
01245     nextCache = manager->localCaches;
01246 
01247     while (nextCache != NULL) {
01248         if (nextCache == cache) {
01249             *prevCache = nextCache->next;
01250             return;
01251         }
01252         prevCache = &(nextCache->next);
01253         nextCache = nextCache->next;
01254     }
01255     return;                     /* should never get here */
01256 
01257 } /* end of cuddLocalCacheRemoveFromList */

static void cuddLocalCacheResize ( DdLocalCache cache  )  [static]

AutomaticStart

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

Synopsis [Resizes a local cache.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 1096 of file cuddLCache.c.

01098 {
01099     DdLocalCacheItem *item, *olditem, *entry, *old;
01100     int i, shift;
01101     unsigned int posn;
01102     unsigned int slots, oldslots;
01103     extern DD_OOMFP MMoutOfMemory;
01104     DD_OOMFP saveHandler;
01105 
01106     olditem = cache->item;
01107     oldslots = cache->slots;
01108     slots = cache->slots = oldslots << 1;
01109 
01110 #ifdef DD_VERBOSE
01111     (void) fprintf(cache->manager->err,
01112                    "Resizing local cache from %d to %d entries\n",
01113                    oldslots, slots);
01114     (void) fprintf(cache->manager->err,
01115                    "\thits = %.0f\tlookups = %.0f\thit ratio = %5.3f\n",
01116                    cache->hits, cache->lookUps, cache->hits / cache->lookUps);
01117 #endif
01118 
01119     saveHandler = MMoutOfMemory;
01120     MMoutOfMemory = Cudd_OutOfMem;
01121     cache->item = item =
01122         (DdLocalCacheItem *) ALLOC(char, slots * cache->itemsize);
01123     MMoutOfMemory = saveHandler;
01124     /* If we fail to allocate the new table we just give up. */
01125     if (item == NULL) {
01126 #ifdef DD_VERBOSE
01127         (void) fprintf(cache->manager->err,"Resizing failed. Giving up.\n");
01128 #endif
01129         cache->slots = oldslots;
01130         cache->item = olditem;
01131         /* Do not try to resize again. */
01132         cache->maxslots = oldslots - 1;
01133         return;
01134     }
01135     shift = --(cache->shift);
01136     cache->manager->memused += (slots - oldslots) * cache->itemsize;
01137 
01138     /* Clear new cache. */
01139     memset(item, 0, slots * cache->itemsize);
01140 
01141     /* Copy from old cache to new one. */
01142     for (i = 0; (unsigned) i < oldslots; i++) {
01143         old = (DdLocalCacheItem *) ((char *) olditem + i * cache->itemsize);
01144         if (old->value != NULL) {
01145             posn = ddLCHash(old->key,cache->keysize,shift);
01146             entry = (DdLocalCacheItem *) ((char *) item +
01147                                           posn * cache->itemsize);
01148             memcpy(entry->key,old->key,cache->keysize*sizeof(DdNode *));
01149             entry->value = old->value;
01150         }
01151     }
01152 
01153     FREE(olditem);
01154 
01155     /* Reinitialize measurements so as to avoid division by 0 and
01156     ** immediate resizing.
01157     */
01158     cache->lookUps = (double) (int) (slots * cache->minHit + 1);
01159     cache->hits = 0;
01160 
01161 } /* end of cuddLocalCacheResize */

static DD_INLINE unsigned int ddLCHash ( DdNodePtr key,
unsigned int  keysize,
int  shift 
) [static]

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

Synopsis [Computes the hash value for a local cache.]

Description [Computes the hash value for a local cache. Returns the bucket index.]

SideEffects [None]

SeeAlso []

Definition at line 1178 of file cuddLCache.c.

01182 {
01183     unsigned int val = (unsigned int) (ptrint) key[0] * DD_P2;
01184     unsigned int i;
01185 
01186     for (i = 1; i < keysize; i++) {
01187         val = val * DD_P1 + (int) (ptrint) key[i];
01188     }
01189 
01190     return(val >> shift);
01191 
01192 } /* end of ddLCHash */


Variable Documentation

char rcsid [] DD_UNUSED = "$Id: cuddLCache.c,v 1.24 2009/03/08 02:49:02 fabio Exp $" [static]

Definition at line 99 of file cuddLCache.c.


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