86 #define DD_MAX_HASHTABLE_DENSITY 2
103 static char rcsid[]
DD_UNUSED =
"$Id: cuddLCache.c,v 1.24 2009/03/08 02:49:02 fabio Exp $";
121 #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
122 #define ddLCHash2(f,g,shift) \
123 ((((unsigned)(ptruint)(f) * DD_P1 + \
124 (unsigned)(ptruint)(g)) * DD_P2) >> (shift))
126 #define ddLCHash2(f,g,shift) \
127 ((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (shift))
142 #define ddLCHash3(f,g,h,shift) ddCHash2(f,g,h,shift)
185 unsigned int keySize ,
186 unsigned int cacheSize ,
187 unsigned int maxCacheSize )
200 #ifdef DD_CACHE_PROFILE
204 cacheSize = 1 << logSize;
207 if (cache->
item == NULL) {
212 cache->
slots = cacheSize;
213 cache->
shift =
sizeof(int) * 8 - logSize;
217 cache->
lookUps = (double) (
int) (cacheSize * cache->
minHit + 1);
285 #ifdef DD_CACHE_PROFILE
317 if (entry->
value != NULL &&
321 if (value->
ref == 0) {
324 return(entry->
value);
356 unsigned int keysize;
357 unsigned int itemsize;
363 while (cache != NULL) {
366 slots = cache->
slots;
368 for (i = 0; i < slots; i++) {
369 if (item->
value != NULL) {
374 for (j = 0; j < keysize; j++) {
409 while (cache != NULL) {
418 #ifdef DD_CACHE_PROFILE
420 #define DD_HYSTO_BINS 8
435 cuddLocalCacheProfile(
438 double count, mean, meansq, stddev, expected;
441 int i, retval, slots;
443 int nbins = DD_HYSTO_BINS;
451 slots = cache->
slots;
453 meansq = mean = expected = 0.0;
454 max = min = (long) cache->
item[0].count;
455 imax = imin = nzeroes = 0;
459 if (hystogram == NULL) {
462 for (i = 0; i < nbins; i++) {
466 for (i = 0; i < slots; i++) {
469 thiscount = (long) entry->count;
470 if (thiscount > max) {
474 if (thiscount < min) {
478 if (thiscount == 0) {
481 count = (double) thiscount;
483 meansq += count * count;
485 expected += count * (double) i;
486 bin = (i * nbins) / slots;
487 hystogram[bin] += thiscount;
489 mean /= (double) slots;
490 meansq /= (double) slots;
491 stddev = sqrt(meansq - mean*mean);
493 retval = fprintf(fp,
"Cache stats: slots = %d average = %g ", slots, mean);
494 if (retval == EOF)
return(0);
495 retval = fprintf(fp,
"standard deviation = %g\n", stddev);
496 if (retval == EOF)
return(0);
497 retval = fprintf(fp,
"Cache max accesses = %ld for slot %d\n", max, imax);
498 if (retval == EOF)
return(0);
499 retval = fprintf(fp,
"Cache min accesses = %ld for slot %d\n", min, imin);
500 if (retval == EOF)
return(0);
501 retval = fprintf(fp,
"Cache unused slots = %d\n", nzeroes);
502 if (retval == EOF)
return(0);
505 expected /= totalcount;
506 retval = fprintf(fp,
"Cache access hystogram for %d bins", nbins);
507 if (retval == EOF)
return(0);
508 retval = fprintf(fp,
" (expected bin value = %g)\n# ", expected);
509 if (retval == EOF)
return(0);
510 for (i = nbins - 1; i>=0; i--) {
511 retval = fprintf(fp,
"%ld ", hystogram[i]);
512 if (retval == EOF)
return(0);
514 retval = fprintf(fp,
"\n");
515 if (retval == EOF)
return(0);
540 unsigned int keySize,
541 unsigned int initSize)
547 #pragma pointer_size save
548 #pragma pointer_size short
562 if (initSize < 2) initSize = 2;
565 hash->
shift =
sizeof(int) * 8 - logSize;
567 if (hash->
bucket == NULL) {
576 #pragma pointer_size restore
599 #pragma pointer_size save
600 #pragma pointer_size short
608 for (i = 0; i < numBuckets; i++) {
610 while (bucket != NULL) {
612 bucket = bucket->
next;
617 while (memlist != NULL) {
626 #pragma pointer_size restore
665 if (result == 0)
return(0);
668 if (item == NULL)
return(0);
673 for (i = 0; i < hash->
keysize; i++) {
674 item->
key[i] = key[i];
678 hash->
bucket[posn] = item;
709 unsigned int i, keysize;
716 item = hash->
bucket[posn];
720 while (item != NULL) {
723 for (i = 0; i < keysize; i++) {
724 if (key[i] != key2[i]) {
732 if (item->
count == 0) {
783 if (result == 0)
return(0);
786 if (item == NULL)
return(0);
794 hash->
bucket[posn] = item;
831 item = hash->
bucket[posn];
834 while (item != NULL) {
839 if (item->
count == 0) {
891 if (result == 0)
return(0);
894 if (item == NULL)
return(0);
903 hash->
bucket[posn] = item;
941 item = hash->
bucket[posn];
944 while (item != NULL) {
946 if ((f == key[0]) && (g == key[1])) {
949 if (item->
count == 0) {
1002 if (result == 0)
return(0);
1005 if (item == NULL)
return(0);
1009 item->
count = count;
1015 hash->
bucket[posn] = item;
1054 item = hash->
bucket[posn];
1057 while (item != NULL) {
1059 if ((f == key[0]) && (g == key[1]) && (h == key[2])) {
1062 if (item->
count == 0) {
1106 unsigned int slots, oldslots;
1110 olditem = cache->
item;
1111 oldslots = cache->
slots;
1112 slots = cache->
slots = oldslots << 1;
1116 "Resizing local cache from %d to %d entries\n",
1119 "\thits = %.0f\tlookups = %.0f\thit ratio = %5.3f\n",
1125 cache->
item = item =
1127 MMoutOfMemory = saveHandler;
1131 (void) fprintf(cache->
manager->
err,
"Resizing failed. Giving up.\n");
1133 cache->
slots = oldslots;
1134 cache->
item = olditem;
1139 shift = --(cache->
shift);
1146 for (i = 0; (unsigned) i < oldslots; i++) {
1148 if (old->
value != NULL) {
1162 cache->
lookUps = (double) (
int) (slots * cache->
minHit + 1);
1184 unsigned int keysize,
1187 unsigned int val = (
unsigned int) (
ptrint) key[0] *
DD_P2;
1190 for (i = 1; i < keysize; i++) {
1194 return(val >> shift);
1240 #pragma pointer_size save
1241 #pragma pointer_size short
1245 #pragma pointer_size restore
1251 while (nextCache != NULL) {
1252 if (nextCache == cache) {
1253 *prevCache = nextCache->
next;
1256 prevCache = &(nextCache->
next);
1257 nextCache = nextCache->
next;
1285 #pragma pointer_size save
1286 #pragma pointer_size short
1293 #pragma pointer_size restore
1301 numBuckets = oldNumBuckets << 1;
1305 #pragma pointer_size save
1306 #pragma pointer_size short
1309 MMoutOfMemory = saveHandler;
1310 if (buckets == NULL) {
1317 shift = --(hash->
shift);
1321 #pragma pointer_size restore
1324 for (j = 0; j < oldNumBuckets; j++) {
1325 item = oldBuckets[j];
1326 while (item != NULL) {
1330 item->
next = buckets[posn];
1331 buckets[posn] = item;
1335 }
else if (hash->
keysize == 2) {
1336 for (j = 0; j < oldNumBuckets; j++) {
1337 item = oldBuckets[j];
1338 while (item != NULL) {
1342 item->
next = buckets[posn];
1343 buckets[posn] = item;
1347 }
else if (hash->
keysize == 3) {
1348 for (j = 0; j < oldNumBuckets; j++) {
1349 item = oldBuckets[j];
1350 while (item != NULL) {
1354 item->
next = buckets[posn];
1355 buckets[posn] = item;
1360 for (j = 0; j < oldNumBuckets; j++) {
1361 item = oldBuckets[j];
1362 while (item != NULL) {
1365 item->
next = buckets[posn];
1366 buckets[posn] = item;
1397 unsigned int itemsize = hash->
itemsize;
1401 #pragma pointer_size save
1402 #pragma pointer_size short
1410 MMoutOfMemory = saveHandler;
1412 #pragma pointer_size restore
1428 #pragma pointer_size save
1429 #pragma pointer_size short
1433 #pragma pointer_size restore
1437 (*MMoutOfMemory)((long)((
DD_MEM_CHUNK + 1) * itemsize));
1446 thisOne = (
DdHashItem *) ((
char *) mem + itemsize);
1449 next = (
DdHashItem *) ((
char *) thisOne + itemsize);
1450 thisOne->
next = next;
1454 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)
DdHashTable * cuddHashTableInit(DdManager *manager, unsigned int keySize, unsigned int initSize)
#define ABC_ALLOC(type, num)
void cuddLocalCacheQuit(DdLocalCache *cache)
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)
int cuddComputeFloorLog2(unsigned int value)
DdLocalCache * cuddLocalCacheInit(DdManager *manager, unsigned int keySize, unsigned int cacheSize, unsigned int maxCacheSize)
#define ABC_NAMESPACE_IMPL_END
static uint32_t hash(uint32_t x)
static void cuddLocalCacheResize(DdLocalCache *cache)
void cuddLocalCacheClearDead(DdManager *manager)
DdLocalCache * localCaches
DdNode * cuddHashTableLookup1(DdHashTable *hash, DdNode *f)
DdNode * cuddLocalCacheLookup(DdLocalCache *cache, DdNodePtr *key)
void cuddHashTableQuit(DdHashTable *hash)
#define ABC_NAMESPACE_IMPL_START
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)
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)