#include "util.h"
#include "cuddInt.h"
Go to the source code of this file.
#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.
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.
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.