ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
utilNam.c
Go to the documentation of this file.
1
20
21
22#include <stdio.h>
23#include <string.h>
24#include <stdlib.h>
25#include <assert.h>
26
27#include "abc_global.h"
28#include "misc/vec/vec.h"
29#include "utilNam.h"
30
32
33
37
38// this package maps non-empty character strings into natural numbers and back
39
40// name manager
42{
43 // info storage for names
44 int nStore; // the size of allocated storage
45 int iHandle; // the current free handle
46 char * pStore; // storage for name objects
47 // internal number mappings
48 Vec_Int_t vInt2Handle; // mapping integers into handles
49 Vec_Int_t vInt2Next; // mapping integers into nexts
50 // hash table for names
51 int * pBins; // the hash table bins
52 int nBins; // the number of bins
53 // manager recycling
54 int nRefs; // reference counter for the manager
55 // internal buffer
57};
58
59static inline char * Abc_NamHandleToStr( Abc_Nam_t * p, int h ) { return (char *)(p->pStore + h); }
60static inline int Abc_NamIntToHandle( Abc_Nam_t * p, int i ) { return Vec_IntEntry(&p->vInt2Handle, i); }
61static inline char * Abc_NamIntToStr( Abc_Nam_t * p, int i ) { return Abc_NamHandleToStr(p, Abc_NamIntToHandle(p,i)); }
62static inline int Abc_NamIntToNext( Abc_Nam_t * p, int i ) { return Vec_IntEntry(&p->vInt2Next, i); }
63static inline int * Abc_NamIntToNextP( Abc_Nam_t * p, int i ) { return Vec_IntEntryP(&p->vInt2Next, i); }
64
68
80Abc_Nam_t * Abc_NamStart( int nObjs, int nAveSize )
81{
82 Abc_Nam_t * p;
83 if ( nObjs == 0 )
84 nObjs = 16;
85 p = ABC_CALLOC( Abc_Nam_t, 1 );
86 p->nStore = ((nObjs * (nAveSize + 1) + 16) / 4) * 4;
87 p->pStore = ABC_ALLOC( char, p->nStore );
88 p->nBins = Abc_PrimeCudd( nObjs );
89 p->pBins = ABC_CALLOC( int, p->nBins );
90 // 0th object is unused
91 Vec_IntGrow( &p->vInt2Handle, nObjs ); Vec_IntPush( &p->vInt2Handle, -1 );
92 Vec_IntGrow( &p->vInt2Next, nObjs ); Vec_IntPush( &p->vInt2Next, -1 );
93 p->iHandle = 4;
94 memset( p->pStore, 0, 4 );
95//Abc_Print( 1, "Starting nam with %d bins.\n", p->nBins );
96 // start reference counting
97 p->nRefs = 1;
98 return p;
99}
100
113{
114//Abc_Print( 1, "Starting nam with %d bins.\n", p->nBins );
115 Vec_StrErase( &p->vBuffer );
116 Vec_IntErase( &p->vInt2Handle );
117 Vec_IntErase( &p->vInt2Next );
118 ABC_FREE( p->pStore );
119 ABC_FREE( p->pBins );
120 ABC_FREE( p );
121}
122
134void Abc_NamPrint( Abc_Nam_t * p, char * pFileName )
135{
136 FILE * pFile = pFileName ? fopen( pFileName, "wb" ) : stdout;
137 int h, i;
138 if ( pFile == NULL ) { printf( "Count node open file %s\n", pFileName ); return; }
139 Vec_IntForEachEntryStart( &p->vInt2Handle, h, i, 1 )
140 fprintf( pFile, "%8d = %s\n", i, Abc_NamHandleToStr(p, h) );
141 if ( pFile != stdout )
142 fclose(pFile);
143}
144
156void Abc_NamSave( Abc_Nam_t * p, char * pFileName )
157{
158 FILE * pFile = fopen( pFileName, "wb" ); int h, i;
159 if ( pFile == NULL ) { printf( "Count node open input file %s\n", pFileName ); return; }
160 Vec_IntForEachEntryStart( &p->vInt2Handle, h, i, 1 )
161 fprintf( pFile, "%s\n", Abc_NamHandleToStr(p, h) );
162 fclose(pFile);
163}
164Abc_Nam_t * Abc_NamLoad( char * pFileName )
165{
166 Abc_Nam_t * p;
167 int fFound, NameId = -1, nLineSize = 1 << 20;
168 char * pBuffer = ABC_ALLOC( char, nLineSize+1 );
169 FILE * pFile = fopen( pFileName, "rb" );
170 if ( pFile == NULL ) { printf( "Count node open output file %s\n", pFileName ); return NULL; }
171 p = Abc_NamStart( 1000, 20 );
172 while ( fgets( pBuffer, nLineSize, pFile ) != NULL )
173 {
174 pBuffer[strlen(pBuffer)-1] = 0;
175 NameId = Abc_NamStrFindOrAdd( p, pBuffer, &fFound );
176 assert( !fFound );
177 }
178 assert( NameId+1 == Abc_NamObjNumMax(p) );
179 fclose( pFile );
180 ABC_FREE( pBuffer );
181 return p;
182}
183
196{
197 p->nRefs++;
198 return p;
199}
200
213{
214 if ( p == NULL )
215 return;
216 if ( --p->nRefs == 0 )
217 Abc_NamStop( p );
218}
219
232{
233 return Vec_IntSize(&p->vInt2Handle);
234}
235
248{
249 if ( p == NULL )
250 return 0;
251 return sizeof(Abc_Nam_t) + p->iHandle + sizeof(int) * p->nBins +
252 sizeof(int) * (p->vInt2Handle.nSize + p->vInt2Next.nSize);
253}
254
267{
268 if ( p == NULL )
269 return 0;
270 return sizeof(Abc_Nam_t) + p->nStore + sizeof(int) * p->nBins +
271 sizeof(int) * (p->vInt2Handle.nCap + p->vInt2Next.nCap);
272}
273
285int Abc_NamStrHash( const char * pStr, const char * pLim, int nTableSize )
286{
287 static int s_FPrimes[128] = {
288 1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459,
289 1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997,
290 2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543,
291 2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089,
292 3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671,
293 3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243,
294 4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871,
295 4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471,
296 5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073,
297 6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689,
298 6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309,
299 7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933,
300 8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147
301 };
302 unsigned i, uHash;
303 if ( pLim )
304 {
305 for ( uHash = 0, i = 0; pStr+i < pLim; i++ )
306 if ( i & 1 )
307 uHash *= pStr[i] * s_FPrimes[i & 0x7F];
308 else
309 uHash ^= pStr[i] * s_FPrimes[i & 0x7F];
310 }
311 else
312 {
313 for ( uHash = 0, i = 0; pStr[i]; i++ )
314 if ( i & 1 )
315 uHash *= pStr[i] * s_FPrimes[i & 0x7F];
316 else
317 uHash ^= pStr[i] * s_FPrimes[i & 0x7F];
318 }
319 return uHash % nTableSize;
320}
321// https://en.wikipedia.org/wiki/Jenkins_hash_function
322int Abc_NamStrHash2( const char * pStr, const char * pLim, int nTableSize )
323{
324 int nSize = pLim ? pLim - pStr : -1;
325 int i = 0; unsigned hash = 0;
326 while ( i != nSize && pStr[i] )
327 {
328 hash += pStr[i++];
329 hash += hash << 10;
330 hash ^= hash >> 6;
331 }
332 hash += hash << 3;
333 hash ^= hash >> 11;
334 hash += hash << 15;
335 return (int)(hash % nTableSize);
336}
337
349static inline int Abc_NamStrcmp( char * pStr, char * pLim, char * pThis )
350{
351 if ( pLim )
352 {
353 while ( pStr < pLim )
354 if ( *pStr++ != *pThis++ )
355 return 1;
356 return *pThis != '\0';
357 }
358 else
359 {
360 while ( *pStr )
361 if ( *pStr++ != *pThis++ )
362 return 1;
363 return *pThis != '\0';
364 }
365}
366static inline int * Abc_NamStrHashFind( Abc_Nam_t * p, const char * pStr, const char * pLim )
367{
368 char * pThis;
369 int * pPlace = (int *)(p->pBins + Abc_NamStrHash( pStr, pLim, p->nBins ));
370 assert( *pStr );
371 for ( pThis = (*pPlace)? Abc_NamIntToStr(p, *pPlace) : NULL;
372 pThis; pPlace = Abc_NamIntToNextP(p, *pPlace),
373 pThis = (*pPlace)? Abc_NamIntToStr(p, *pPlace) : NULL )
374 if ( !Abc_NamStrcmp( (char *)pStr, (char *)pLim, pThis ) )
375 break;
376 return pPlace;
377}
378
391{
392 Vec_Int_t vInt2HandleOld; char * pThis;
393 int * piPlace, * pBinsOld, iHandleOld, i;//, clk = Abc_Clock();
394 assert( p->pBins != NULL );
395// Abc_Print( 1, "Resizing names manager hash table from %6d to %6d. ", p->nBins, Abc_PrimeCudd( 3 * p->nBins ) );
396 // replace the table
397 pBinsOld = p->pBins;
398 p->nBins = Abc_PrimeCudd( 3 * p->nBins );
399 p->pBins = ABC_CALLOC( int, p->nBins );
400 // replace the handles array
401 vInt2HandleOld = p->vInt2Handle;
402 Vec_IntZero( &p->vInt2Handle );
403 Vec_IntGrow( &p->vInt2Handle, 2 * Vec_IntSize(&vInt2HandleOld) );
404 Vec_IntPush( &p->vInt2Handle, -1 );
405 Vec_IntClear( &p->vInt2Next ); Vec_IntPush( &p->vInt2Next, -1 );
406 // rehash the entries from the old table
407 Vec_IntForEachEntryStart( &vInt2HandleOld, iHandleOld, i, 1 )
408 {
409 pThis = Abc_NamHandleToStr( p, iHandleOld );
410 piPlace = Abc_NamStrHashFind( p, pThis, NULL );
411 assert( *piPlace == 0 );
412 *piPlace = Vec_IntSize( &p->vInt2Handle );
413 assert( Vec_IntSize( &p->vInt2Handle ) == i );
414 Vec_IntPush( &p->vInt2Handle, iHandleOld );
415 Vec_IntPush( &p->vInt2Next, 0 );
416 }
417 Vec_IntErase( &vInt2HandleOld );
418 ABC_FREE( pBinsOld );
419// Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
420}
421
433int Abc_NamStrFind( Abc_Nam_t * p, char * pStr )
434{
435 return *Abc_NamStrHashFind( p, pStr, NULL );
436}
437int Abc_NamStrFindLim( Abc_Nam_t * p, char * pStr, char * pLim )
438{
439 return *Abc_NamStrHashFind( p, pStr, pLim );
440}
441
453int Abc_NamStrFindOrAdd( Abc_Nam_t * p, char * pStr, int * pfFound )
454{
455 int i, iHandleNew;
456 int *piPlace;
457 if ( !(pStr[0] != '\\' || pStr[strlen(pStr)-1] == ' ') )
458 {
459 for ( i = strlen(pStr) - 1; i >= 0; i-- )
460 if ( *pStr == ' ' )
461 break;
462 assert( i < (int)strlen(pStr) );
463 }
464 piPlace = Abc_NamStrHashFind( p, pStr, NULL );
465 if ( *piPlace )
466 {
467 if ( pfFound )
468 *pfFound = 1;
469 return *piPlace;
470 }
471 if ( pfFound )
472 *pfFound = 0;
473 iHandleNew = p->iHandle + strlen(pStr) + 1;
474 while ( p->nStore < iHandleNew )
475 {
476 p->nStore *= 3;
477 p->nStore /= 2;
478 p->pStore = ABC_REALLOC( char, p->pStore, p->nStore );
479 }
480 assert( p->nStore >= iHandleNew );
481 // create new handle
482 *piPlace = Vec_IntSize( &p->vInt2Handle );
483 strcpy( Abc_NamHandleToStr( p, p->iHandle ), pStr );
484 Vec_IntPush( &p->vInt2Handle, p->iHandle );
485 Vec_IntPush( &p->vInt2Next, 0 );
486 p->iHandle = iHandleNew;
487 // extend the hash table
488 if ( Vec_IntSize(&p->vInt2Handle) > 2 * p->nBins )
490 return Vec_IntSize(&p->vInt2Handle) - 1;
491}
492int Abc_NamStrFindOrAddLim( Abc_Nam_t * p, char * pStr, char * pLim, int * pfFound )
493{
494 int iHandleNew;
495 int *piPlace;
496 char * pStore;
497 assert( pStr < pLim );
498 piPlace = Abc_NamStrHashFind( p, pStr, pLim );
499 if ( *piPlace )
500 {
501 if ( pfFound )
502 *pfFound = 1;
503 return *piPlace;
504 }
505 if ( pfFound )
506 *pfFound = 0;
507 iHandleNew = p->iHandle + (pLim - pStr) + 1;
508 while ( p->nStore < iHandleNew )
509 {
510 p->nStore *= 3;
511 p->nStore /= 2;
512 p->pStore = ABC_REALLOC( char, p->pStore, p->nStore );
513 }
514 assert( p->nStore >= iHandleNew );
515 // create new handle
516 *piPlace = Vec_IntSize( &p->vInt2Handle );
517 pStore = Abc_NamHandleToStr( p, p->iHandle );
518 strncpy( pStore, pStr, pLim - pStr );
519 pStore[pLim - pStr] = 0;
520 Vec_IntPush( &p->vInt2Handle, p->iHandle );
521 Vec_IntPush( &p->vInt2Next, 0 );
522 p->iHandle = iHandleNew;
523 // extend the hash table
524 if ( Vec_IntSize(&p->vInt2Handle) > 2 * p->nBins )
526 return Vec_IntSize(&p->vInt2Handle) - 1;
527}
528int Abc_NamStrFindOrAddF( Abc_Nam_t * p, const char * format, ... )
529{
530 int nAdded, nSize = 1000;
531 va_list args; va_start( args, format );
532 Vec_StrGrow( &p->vBuffer, Vec_StrSize(&p->vBuffer) + nSize );
533 nAdded = vsnprintf( Vec_StrLimit(&p->vBuffer), nSize, format, args );
534 if ( nAdded > nSize )
535 {
536 Vec_StrGrow( &p->vBuffer, Vec_StrSize(&p->vBuffer) + nAdded + nSize );
537 nSize = vsnprintf( Vec_StrLimit(&p->vBuffer), nAdded, format, args );
538 assert( nSize == nAdded );
539 }
540 va_end( args );
541 return Abc_NamStrFindOrAddLim( p, Vec_StrLimit(&p->vBuffer), Vec_StrLimit(&p->vBuffer) + nAdded, NULL );
542}
543
555char * Abc_NamStr( Abc_Nam_t * p, int NameId )
556{
557 return NameId > 0 ? Abc_NamIntToStr(p, NameId) : NULL;
558}
559
572{
573 Vec_StrClear(&p->vBuffer);
574 return &p->vBuffer;
575}
576
589{
590 Vec_Int_t * vMap;
591 char * pThis;
592 int * piPlace, iHandle1, i;
593 if ( p1 == p2 )
594 return Vec_IntStartNatural( Abc_NamObjNumMax(p1) );
595 vMap = Vec_IntStart( Abc_NamObjNumMax(p1) );
596 Vec_IntForEachEntryStart( &p1->vInt2Handle, iHandle1, i, 1 )
597 {
598 pThis = Abc_NamHandleToStr( p1, iHandle1 );
599 piPlace = Abc_NamStrHashFind( p2, pThis, NULL );
600 Vec_IntWriteEntry( vMap, i, *piPlace );
601// Abc_Print( 1, "%d->%d ", i, *piPlace );
602 }
603 return vMap;
604}
605
619int Abc_NamReportCommon( Vec_Int_t * vNameIds1, Abc_Nam_t * p1, Abc_Nam_t * p2 )
620{
621 int i, Entry, Counter = 0;
622 Vec_IntForEachEntry( vNameIds1, Entry, i )
623 {
624 assert( Entry > 0 && Entry < Abc_NamObjNumMax(p1) );
625 Counter += (Abc_NamStrFind(p2, Abc_NamStr(p1, Entry)) > 0);
626// if ( Abc_NamStrFind(p2, Abc_NamStr(p1, Entry)) == 0 )
627// Abc_Print( 1, "unique name <%s>\n", Abc_NamStr(p1, Entry) );
628 }
629 return Counter;
630}
631
643char * Abc_NamReportUnique( Vec_Int_t * vNameIds1, Abc_Nam_t * p1, Abc_Nam_t * p2 )
644{
645 int i, Entry;
646 Vec_IntForEachEntry( vNameIds1, Entry, i )
647 {
648 assert( Entry > 0 && Entry < Abc_NamObjNumMax(p1) );
649 if ( Abc_NamStrFind(p2, Abc_NamStr(p1, Entry)) == 0 )
650 return Abc_NamStr(p1, Entry);
651 }
652 return NULL;
653}
654
658
659
661
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#define ABC_REALLOC(type, obj, num)
Definition abc_global.h:268
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
struct Vec_Str_t_ Vec_Str_t
Definition bblif.c:46
Cube * p
Definition exorList.c:222
if(last==0)
Definition sparse_int.h:34
DECLARATIONS ///.
Definition utilNam.c:42
Vec_Str_t vBuffer
Definition utilNam.c:56
int nRefs
Definition utilNam.c:54
int iHandle
Definition utilNam.c:45
int nStore
Definition utilNam.c:44
Vec_Int_t vInt2Next
Definition utilNam.c:49
char * pStore
Definition utilNam.c:46
int nBins
Definition utilNam.c:52
Vec_Int_t vInt2Handle
Definition utilNam.c:48
int * pBins
Definition utilNam.c:51
void Abc_NamSave(Abc_Nam_t *p, char *pFileName)
Definition utilNam.c:156
int Abc_NamStrFindLim(Abc_Nam_t *p, char *pStr, char *pLim)
Definition utilNam.c:437
int Abc_NamStrFind(Abc_Nam_t *p, char *pStr)
Definition utilNam.c:433
int Abc_NamReportCommon(Vec_Int_t *vNameIds1, Abc_Nam_t *p1, Abc_Nam_t *p2)
Definition utilNam.c:619
int Abc_NamStrFindOrAddLim(Abc_Nam_t *p, char *pStr, char *pLim, int *pfFound)
Definition utilNam.c:492
int Abc_NamStrHash2(const char *pStr, const char *pLim, int nTableSize)
Definition utilNam.c:322
int Abc_NamMemUsed(Abc_Nam_t *p)
Definition utilNam.c:247
void Abc_NamStrHashResize(Abc_Nam_t *p)
Definition utilNam.c:390
Vec_Int_t * Abc_NamComputeIdMap(Abc_Nam_t *p1, Abc_Nam_t *p2)
Definition utilNam.c:588
void Abc_NamStop(Abc_Nam_t *p)
Definition utilNam.c:112
int Abc_NamStrFindOrAdd(Abc_Nam_t *p, char *pStr, int *pfFound)
Definition utilNam.c:453
char * Abc_NamReportUnique(Vec_Int_t *vNameIds1, Abc_Nam_t *p1, Abc_Nam_t *p2)
Definition utilNam.c:643
Abc_Nam_t * Abc_NamLoad(char *pFileName)
Definition utilNam.c:164
int Abc_NamObjNumMax(Abc_Nam_t *p)
Definition utilNam.c:231
int Abc_NamStrHash(const char *pStr, const char *pLim, int nTableSize)
Definition utilNam.c:285
Abc_Nam_t * Abc_NamStart(int nObjs, int nAveSize)
FUNCTION DEFINITIONS ///.
Definition utilNam.c:80
Vec_Str_t * Abc_NamBuffer(Abc_Nam_t *p)
Definition utilNam.c:571
int Abc_NamStrFindOrAddF(Abc_Nam_t *p, const char *format,...)
Definition utilNam.c:528
void Abc_NamDeref(Abc_Nam_t *p)
Definition utilNam.c:212
int Abc_NamMemAlloc(Abc_Nam_t *p)
Definition utilNam.c:266
Abc_Nam_t * Abc_NamRef(Abc_Nam_t *p)
Definition utilNam.c:195
char * Abc_NamStr(Abc_Nam_t *p, int NameId)
Definition utilNam.c:555
void Abc_NamPrint(Abc_Nam_t *p, char *pFileName)
Definition utilNam.c:134
typedefABC_NAMESPACE_HEADER_START struct Abc_Nam_t_ Abc_Nam_t
INCLUDES ///.
Definition utilNam.h:39
#define assert(ex)
Definition util_old.h:213
char * memset()
int strlen()
char * strncpy()
char * strcpy()
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecInt.h:54
#define Vec_IntForEachEntryStart(vVec, Entry, i, Start)
Definition vecInt.h:56