85 #define DD_MAX_HASHTABLE_DENSITY 2 102 static char rcsid[]
DD_UNUSED =
"$Id: cuddLCache.c,v 1.27 2012/02/05 01:07:19 fabio Exp $";
120 #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 121 #define ddLCHash1(f,shift) \ 122 (((unsigned)(ptruint)(f) * DD_P1) >> (shift)) 124 #define ddLCHash1(f,shift) \ 125 (((unsigned)(f) * DD_P1) >> (shift)) 140 #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4 141 #define ddLCHash2(f,g,shift) \ 142 ((((unsigned)(ptruint)(f) * DD_P1 + \ 143 (unsigned)(ptruint)(g)) * DD_P2) >> (shift)) 145 #define ddLCHash2(f,g,shift) \ 146 ((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (shift)) 161 #define ddLCHash3(f,g,h,shift) ddCHash2(f,g,h,shift) 204 unsigned int keySize ,
205 unsigned int cacheSize ,
206 unsigned int maxCacheSize )
219 #ifdef DD_CACHE_PROFILE 223 cacheSize = 1 << logSize;
226 if (cache->
item == NULL) {
231 cache->
slots = cacheSize;
232 cache->
shift =
sizeof(int) * 8 - logSize;
236 cache->
lookUps = (double) (
int) (cacheSize * cache->
minHit + 1);
303 entry->
value = value;
304 #ifdef DD_CACHE_PROFILE 336 if (entry->
value != NULL &&
340 if (value->
ref == 0) {
343 return(entry->
value);
375 unsigned int keysize;
376 unsigned int itemsize;
382 while (cache != NULL) {
385 slots = cache->
slots;
387 for (i = 0; i < slots; i++) {
388 if (item->
value != NULL) {
393 for (j = 0; j < keysize; j++) {
428 while (cache != NULL) {
437 #ifdef DD_CACHE_PROFILE 439 #define DD_HYSTO_BINS 8 454 cuddLocalCacheProfile(
457 double count, mean, meansq, stddev, expected;
460 int i, retval, slots;
462 int nbins = DD_HYSTO_BINS;
470 slots = cache->
slots;
472 meansq = mean = expected = 0.0;
473 max = min = (long) cache->
item[0].count;
474 imax = imin = nzeroes = 0;
477 hystogram =
ALLOC(
long, nbins);
478 if (hystogram == NULL) {
481 for (i = 0; i < nbins; i++) {
485 for (i = 0; i < slots; i++) {
488 thiscount = (long) entry->count;
489 if (thiscount > max) {
493 if (thiscount < min) {
497 if (thiscount == 0) {
500 count = (double) thiscount;
502 meansq += count * count;
504 expected += count * (double) i;
505 bin = (i * nbins) / slots;
506 hystogram[bin] += thiscount;
508 mean /= (double) slots;
509 meansq /= (double) slots;
510 stddev = sqrt(meansq - mean*mean);
512 retval = fprintf(fp,
"Cache stats: slots = %d average = %g ", slots, mean);
513 if (retval == EOF)
return(0);
514 retval = fprintf(fp,
"standard deviation = %g\n", stddev);
515 if (retval == EOF)
return(0);
516 retval = fprintf(fp,
"Cache max accesses = %ld for slot %d\n", max, imax);
517 if (retval == EOF)
return(0);
518 retval = fprintf(fp,
"Cache min accesses = %ld for slot %d\n", min, imin);
519 if (retval == EOF)
return(0);
520 retval = fprintf(fp,
"Cache unused slots = %d\n", nzeroes);
521 if (retval == EOF)
return(0);
524 expected /= totalcount;
525 retval = fprintf(fp,
"Cache access hystogram for %d bins", nbins);
526 if (retval == EOF)
return(0);
527 retval = fprintf(fp,
" (expected bin value = %g)\n# ", expected);
528 if (retval == EOF)
return(0);
529 for (i = nbins - 1; i>=0; i--) {
530 retval = fprintf(fp,
"%ld ", hystogram[i]);
531 if (retval == EOF)
return(0);
533 retval = fprintf(fp,
"\n");
534 if (retval == EOF)
return(0);
559 unsigned int keySize,
560 unsigned int initSize)
577 if (initSize < 2) initSize = 2;
580 hash->
shift =
sizeof(int) * 8 - logSize;
582 if (hash->
bucket == NULL) {
616 for (i = 0; i < numBuckets; i++) {
618 while (bucket != NULL) {
620 bucket = bucket->
next;
625 while (memlist != NULL) {
656 #pragma pointer_size save 657 #pragma pointer_size short 662 while (memlist != NULL) {
671 #pragma pointer_size restore 710 if (result == 0)
return(0);
713 if (item == NULL)
return(0);
718 for (i = 0; i < hash->
keysize; i++) {
719 item->
key[i] = key[i];
723 hash->
bucket[posn] = item;
754 unsigned int i, keysize;
761 item = hash->
bucket[posn];
765 while (item != NULL) {
768 for (i = 0; i < keysize; i++) {
769 if (key[i] != key2[i]) {
777 if (item->
count == 0) {
828 if (result == 0)
return(0);
831 if (item == NULL)
return(0);
839 hash->
bucket[posn] = item;
876 item = hash->
bucket[posn];
879 while (item != NULL) {
884 if (item->
count == 0) {
934 if (result == 0)
return(0);
937 if (item == NULL)
return(0);
944 hash->
bucket[posn] = item;
978 item = hash->
bucket[posn];
980 while (item != NULL) {
981 if (f == item->
key[0]) {
982 return ((
void *) item->
value);
1022 if (result == 0)
return(0);
1025 if (item == NULL)
return(0);
1027 item->
value = value;
1029 item->
count = count;
1034 hash->
bucket[posn] = item;
1072 item = hash->
bucket[posn];
1075 while (item != NULL) {
1077 if ((f == key[0]) && (g == key[1])) {
1080 if (item->
count == 0) {
1133 if (result == 0)
return(0);
1136 if (item == NULL)
return(0);
1138 item->
value = value;
1140 item->
count = count;
1146 hash->
bucket[posn] = item;
1185 item = hash->
bucket[posn];
1188 while (item != NULL) {
1190 if ((f == key[0]) && (g == key[1]) && (h == key[2])) {
1193 if (item->
count == 0) {
1237 unsigned int slots, oldslots;
1241 olditem = cache->
item;
1242 oldslots = cache->
slots;
1243 slots = cache->
slots = oldslots << 1;
1247 "Resizing local cache from %d to %d entries\n",
1250 "\thits = %.0f\tlookups = %.0f\thit ratio = %5.3f\n",
1256 cache->
item = item =
1258 MMoutOfMemory = saveHandler;
1262 (void) fprintf(cache->
manager->
err,
"Resizing failed. Giving up.\n");
1264 cache->
slots = oldslots;
1265 cache->
item = olditem;
1270 shift = --(cache->
shift);
1277 for (i = 0; (unsigned) i < oldslots; i++) {
1279 if (old->
value != NULL) {
1293 cache->
lookUps = (double) (
int) (slots * cache->
minHit + 1);
1315 unsigned int keysize,
1318 unsigned int val = (
unsigned int) (
ptrint) key[0] *
DD_P2;
1321 for (i = 1; i < keysize; i++) {
1325 return(val >> shift);
1375 while (nextCache != NULL) {
1376 if (nextCache == cache) {
1377 *prevCache = nextCache->
next;
1380 prevCache = &(nextCache->
next);
1381 nextCache = nextCache->
next;
1418 numBuckets = oldNumBuckets << 1;
1422 MMoutOfMemory = saveHandler;
1423 if (buckets == NULL) {
1430 shift = --(hash->
shift);
1434 for (j = 0; j < oldNumBuckets; j++) {
1435 item = oldBuckets[j];
1436 while (item != NULL) {
1439 posn =
ddLCHash2(key[0], key[0], shift);
1440 item->
next = buckets[posn];
1441 buckets[posn] = item;
1445 }
else if (hash->
keysize == 2) {
1446 for (j = 0; j < oldNumBuckets; j++) {
1447 item = oldBuckets[j];
1448 while (item != NULL) {
1451 posn =
ddLCHash2(key[0], key[1], shift);
1452 item->
next = buckets[posn];
1453 buckets[posn] = item;
1457 }
else if (hash->
keysize == 3) {
1458 for (j = 0; j < oldNumBuckets; j++) {
1459 item = oldBuckets[j];
1460 while (item != NULL) {
1463 posn =
ddLCHash3(key[0], key[1], key[2], shift);
1464 item->
next = buckets[posn];
1465 buckets[posn] = item;
1470 for (j = 0; j < oldNumBuckets; j++) {
1471 item = oldBuckets[j];
1472 while (item != NULL) {
1475 item->
next = buckets[posn];
1476 buckets[posn] = item;
1507 unsigned int itemsize = hash->
itemsize;
1516 MMoutOfMemory = saveHandler;
1533 (*MMoutOfMemory)((long)((
DD_MEM_CHUNK + 1) * itemsize));
1542 thisOne = (
DdHashItem *) ((
char *) mem + itemsize);
1545 next = (
DdHashItem *) ((
char *) thisOne + itemsize);
1546 thisOne->
next = next;
1550 thisOne->
next = NULL;
static void cuddLocalCacheRemoveFromList(DdLocalCache *cache)
void Cudd_OutOfMem(long size)
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
void cuddLocalCacheInsert(DdLocalCache *cache, DdNodePtr *key, DdNode *value)
static DD_INLINE DdHashItem * cuddHashTableAlloc(DdHashTable *hash)
unsigned int maxCacheHard
#define Cudd_Regular(node)
void cuddReclaim(DdManager *table, DdNode *n)
DdNode * cuddHashTableLookup3(DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h)
int cuddHashTableGenericInsert(DdHashTable *hash, DdNode *f, void *value)
DdHashTable * cuddHashTableInit(DdManager *manager, unsigned int keySize, unsigned int initSize)
void * cuddHashTableGenericLookup(DdHashTable *hash, DdNode *f)
void cuddLocalCacheQuit(DdLocalCache *cache)
#define ddLCHash1(f, shift)
static char rcsid [] DD_UNUSED
struct DdLocalCache * next
DdNode * cuddHashTableLookup2(DdHashTable *hash, DdNode *f, DdNode *g)
int cuddHashTableInsert1(DdHashTable *hash, DdNode *f, DdNode *value, ptrint count)
int cuddHashTableInsert3(DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h, DdNode *value, ptrint count)
static DD_INLINE unsigned int ddLCHash(DdNodePtr *key, unsigned int keysize, int shift)
DdLocalCache * cuddLocalCacheInit(DdManager *manager, unsigned int keySize, unsigned int cacheSize, unsigned int maxCacheSize)
static void cuddLocalCacheResize(DdLocalCache *cache)
void cuddLocalCacheClearDead(DdManager *manager)
DdLocalCache * localCaches
DdNode * cuddHashTableLookup1(DdHashTable *hash, DdNode *f)
DdNode * cuddLocalCacheLookup(DdLocalCache *cache, DdNodePtr *key)
void(* MMoutOfMemory)(long)
void cuddHashTableQuit(DdHashTable *hash)
int cuddHashTableInsert2(DdHashTable *hash, DdNode *f, DdNode *g, DdNode *value, ptrint count)
struct DdLocalCache DdLocalCache
#define ddLCHash2(f, g, shift)
DdNode * cuddHashTableLookup(DdHashTable *hash, DdNodePtr *key)
int cuddComputeFloorLog2(unsigned int value)
void cuddHashTableGenericQuit(DdHashTable *hash)
static void cuddLocalCacheAddToList(DdLocalCache *cache)
int cuddHashTableInsert(DdHashTable *hash, DdNodePtr *key, DdNode *value, ptrint count)
#define ddLCHash3(f, g, h, shift)
#define DD_MAX_HASHTABLE_DENSITY
static int cuddHashTableResize(DdHashTable *hash)
void cuddLocalCacheClearAll(DdManager *manager)