mirror of https://github.com/YosysHQ/abc.git
415 lines
13 KiB
C
415 lines
13 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [vecHsh.h]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [Resizable arrays.]
|
|
|
|
Synopsis [Hashing vector entries.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
Revision [$Id: vecHsh.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#ifndef ABC__misc__vec__vecHsh_h
|
|
#define ABC__misc__vec__vecHsh_h
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// INCLUDES ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
#include <stdio.h>
|
|
|
|
ABC_NAMESPACE_HEADER_START
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// PARAMETERS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// BASIC TYPES ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
typedef struct Hsh_IntObj_t_ Hsh_IntObj_t;
|
|
struct Hsh_IntObj_t_
|
|
{
|
|
int iData;
|
|
int iNext;
|
|
};
|
|
|
|
typedef union Hsh_IntObjWord_t_ Hsh_IntObjWord_t;
|
|
union Hsh_IntObjWord_t_
|
|
{
|
|
Hsh_IntObj_t wObj;
|
|
word wWord;
|
|
};
|
|
|
|
typedef struct Hsh_IntMan_t_ Hsh_IntMan_t;
|
|
struct Hsh_IntMan_t_
|
|
{
|
|
int nSize; // data size
|
|
Vec_Int_t * vData; // data storage
|
|
Vec_Int_t * vTable; // hash table
|
|
Vec_Wrd_t * vObjs; // hash objects
|
|
};
|
|
|
|
|
|
|
|
typedef struct Hsh_VecObj_t_ Hsh_VecObj_t;
|
|
struct Hsh_VecObj_t_
|
|
{
|
|
int nSize;
|
|
int iNext;
|
|
int pArray[0];
|
|
};
|
|
|
|
typedef struct Hsh_VecMan_t_ Hsh_VecMan_t;
|
|
struct Hsh_VecMan_t_
|
|
{
|
|
Vec_Int_t * vTable; // hash table
|
|
Vec_Int_t * vData; // data storage
|
|
Vec_Int_t * vMap; // mapping entries into data;
|
|
Vec_Int_t vTemp; // temporary array
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// MACRO DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
static inline unsigned * Hsh_IntData( Hsh_IntMan_t * p, int iData ) { return (unsigned *)Vec_IntEntryP( p->vData, p->nSize * iData ); }
|
|
static inline Hsh_IntObj_t * Hsh_IntObj( Hsh_IntMan_t * p, int iObj ) { return iObj == -1 ? NULL : (Hsh_IntObj_t *)Vec_WrdEntryP( p->vObjs, iObj ); }
|
|
static inline word Hsh_IntWord( int iData, int iNext ) { Hsh_IntObjWord_t Obj = { {iData, iNext} }; return Obj.wWord; }
|
|
|
|
static inline Hsh_VecObj_t * Hsh_VecObj( Hsh_VecMan_t * p, int i ) { return i == -1 ? NULL : (Hsh_VecObj_t *)Vec_IntEntryP(p->vData, Vec_IntEntry(p->vMap, i)); }
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Hashing data entries composed of nSize integers.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline Hsh_IntMan_t * Hsh_IntManStart( Vec_Int_t * vData, int nSize, int nEntries )
|
|
{
|
|
Hsh_IntMan_t * p;
|
|
p = ABC_CALLOC( Hsh_IntMan_t, 1 );
|
|
p->nSize = nSize;
|
|
p->vData = vData;
|
|
p->vTable = Vec_IntStartFull( Abc_PrimeCudd(nEntries) );
|
|
p->vObjs = Vec_WrdAlloc( nEntries );
|
|
return p;
|
|
}
|
|
static inline void Hsh_IntManStop( Hsh_IntMan_t * p )
|
|
{
|
|
Vec_IntFree( p->vTable );
|
|
Vec_WrdFree( p->vObjs );
|
|
ABC_FREE( p );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline int Hsh_IntManHash( unsigned * pData, int nSize, int nTableSize )
|
|
{
|
|
static int s_Primes[7] = { 4177, 5147, 5647, 6343, 7103, 7873, 8147 };
|
|
unsigned char * pDataC = (unsigned char *)pData;
|
|
int c, nChars = nSize * 4;
|
|
unsigned Key = 0;
|
|
for ( c = 0; c < nChars; c++ )
|
|
Key += pDataC[c] * s_Primes[c % 7];
|
|
return (int)(Key % nTableSize);
|
|
}
|
|
static inline int * Hsh_IntManLookup( Hsh_IntMan_t * p, unsigned * pData )
|
|
{
|
|
Hsh_IntObj_t * pObj;
|
|
int * pPlace = Vec_IntEntryP( p->vTable, Hsh_IntManHash(pData, p->nSize, Vec_IntSize(p->vTable)) );
|
|
for ( ; (pObj = Hsh_IntObj(p, *pPlace)); pPlace = &pObj->iNext )
|
|
if ( !memcmp( pData, Hsh_IntData(p, pObj->iData), sizeof(int) * p->nSize ) )
|
|
return pPlace;
|
|
assert( *pPlace == -1 );
|
|
return pPlace;
|
|
}
|
|
static inline int Hsh_IntManAdd( Hsh_IntMan_t * p, int iData )
|
|
{
|
|
int i, * pPlace;
|
|
if ( Vec_WrdSize(p->vObjs) > Vec_IntSize(p->vTable) )
|
|
{
|
|
Vec_IntFill( p->vTable, Abc_PrimeCudd(2*Vec_IntSize(p->vTable)), -1 );
|
|
for ( i = 0; i < Vec_WrdSize(p->vObjs); i++ )
|
|
{
|
|
pPlace = Vec_IntEntryP( p->vTable, Hsh_IntManHash(Hsh_IntData(p, i), p->nSize, Vec_IntSize(p->vTable)) );
|
|
Hsh_IntObj(p, i)->iNext = *pPlace; *pPlace = i;
|
|
}
|
|
}
|
|
pPlace = Hsh_IntManLookup( p, Hsh_IntData(p, iData) );
|
|
if ( *pPlace == -1 )
|
|
{
|
|
*pPlace = Vec_WrdSize(p->vObjs);
|
|
Vec_WrdPush( p->vObjs, Hsh_IntWord(iData, -1) );
|
|
return Vec_WrdSize(p->vObjs) - 1;
|
|
}
|
|
return (word *)Hsh_IntObj(p, *pPlace) - Vec_WrdArray(p->vObjs);
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Hashes data by value.]
|
|
|
|
Description [Array vData contains data entries, each of 'nSize' integers.
|
|
The resulting array contains the indexes of unique data entries.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline Vec_Int_t * Hsh_IntManHashArray( Vec_Int_t * vData, int nSize )
|
|
{
|
|
Hsh_IntMan_t * p;
|
|
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
|
|
int i, nEntries = Vec_IntSize(vData) / nSize;
|
|
assert( Vec_IntSize(vData) % nSize == 0 );
|
|
p = Hsh_IntManStart( vData, nSize, nEntries );
|
|
for ( i = 0; i < nEntries; i++ )
|
|
Vec_IntPush( vRes, Hsh_IntManAdd(p, i) );
|
|
Hsh_IntManStop( p );
|
|
return vRes;
|
|
}
|
|
static inline Vec_Int_t * Hsh_WrdManHashArray( Vec_Wrd_t * vDataW, int nSize )
|
|
{
|
|
Hsh_IntMan_t * p;
|
|
Vec_Int_t Data = { 2*Vec_WrdCap(vDataW), 2*Vec_WrdSize(vDataW), (int *)Vec_WrdArray(vDataW) };
|
|
Vec_Int_t * vData = &Data;
|
|
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
|
|
int i, nEntries = Vec_IntSize(vData) / (2*nSize);
|
|
assert( Vec_IntSize(vData) % (2*nSize) == 0 );
|
|
p = Hsh_IntManStart( vData, (2*nSize), nEntries );
|
|
for ( i = 0; i < nEntries; i++ )
|
|
Vec_IntPush( vRes, Hsh_IntManAdd(p, i) );
|
|
Hsh_IntManStop( p );
|
|
return vRes;
|
|
}
|
|
static inline Hsh_IntMan_t * Hsh_WrdManHashArrayStart( Vec_Wrd_t * vDataW, int nSize )
|
|
{
|
|
Hsh_IntMan_t * p;
|
|
int i, nEntries = Vec_WrdSize(vDataW) / nSize;
|
|
Vec_Int_t * vData = Vec_IntAlloc( 2*Vec_WrdSize(vDataW) );
|
|
memcpy( Vec_IntArray(vData), Vec_WrdArray(vDataW), sizeof(word)*Vec_WrdSize(vDataW) );
|
|
vData->nSize = 2*Vec_WrdSize(vDataW);
|
|
/*
|
|
for ( i = 0; i < 30; i++ )
|
|
{
|
|
extern void Extra_PrintHex( FILE * pFile, unsigned * pTruth, int nVars );
|
|
Extra_PrintHex( stdout, (unsigned *) Vec_WrdEntryP(vDataW, i), 6 ); printf( " " );
|
|
Kit_DsdPrintFromTruth( (unsigned *) Vec_WrdEntryP(vDataW, i), 6 ); printf( "\n" );
|
|
}
|
|
*/
|
|
assert( Vec_IntSize(vData) % (2*nSize) == 0 );
|
|
p = Hsh_IntManStart( vData, (2*nSize), nEntries );
|
|
for ( i = 0; i < nEntries; i++ )
|
|
Hsh_IntManAdd( p, i );
|
|
assert( Vec_WrdSize(p->vObjs) == nEntries );
|
|
return p;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Test procedure.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline void Hsh_IntManHashArrayTest()
|
|
{
|
|
Vec_Int_t * vData = Vec_IntAlloc( 10 );
|
|
Vec_Int_t * vRes;
|
|
Vec_IntPush( vData, 12 );
|
|
Vec_IntPush( vData, 17 );
|
|
Vec_IntPush( vData, 13 );
|
|
Vec_IntPush( vData, 12 );
|
|
Vec_IntPush( vData, 15 );
|
|
Vec_IntPush( vData, 3 );
|
|
Vec_IntPush( vData, 16 );
|
|
Vec_IntPush( vData, 16 );
|
|
Vec_IntPush( vData, 12 );
|
|
Vec_IntPush( vData, 17 );
|
|
Vec_IntPush( vData, 12 );
|
|
Vec_IntPush( vData, 12 );
|
|
|
|
vRes = Hsh_IntManHashArray( vData, 2 );
|
|
|
|
Vec_IntPrint( vData );
|
|
Vec_IntPrint( vRes );
|
|
|
|
Vec_IntFree( vData );
|
|
Vec_IntFree( vRes );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Hashing integer arrays.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline Hsh_VecMan_t * Hsh_VecManStart( int nEntries )
|
|
{
|
|
Hsh_VecMan_t * p;
|
|
p = ABC_CALLOC( Hsh_VecMan_t, 1 );
|
|
p->vTable = Vec_IntStartFull( Abc_PrimeCudd(nEntries) );
|
|
p->vData = Vec_IntAlloc( nEntries * 4 );
|
|
p->vMap = Vec_IntAlloc( nEntries );
|
|
return p;
|
|
}
|
|
static inline void Hsh_VecManStop( Hsh_VecMan_t * p )
|
|
{
|
|
Vec_IntFree( p->vTable );
|
|
Vec_IntFree( p->vData );
|
|
Vec_IntFree( p->vMap );
|
|
ABC_FREE( p );
|
|
}
|
|
static inline Vec_Int_t * Hsh_VecReadEntry( Hsh_VecMan_t * p, int i )
|
|
{
|
|
Hsh_VecObj_t * pObj = Hsh_VecObj( p, i );
|
|
p->vTemp.nSize = p->vTemp.nCap = pObj->nSize;
|
|
p->vTemp.pArray = (int*)pObj + 2;
|
|
return &p->vTemp;
|
|
}
|
|
static inline int Hsh_VecSize( Hsh_VecMan_t * p )
|
|
{
|
|
return Vec_IntSize(p->vMap);
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline int Hsh_VecManHash( Vec_Int_t * vVec, int nTableSize )
|
|
{
|
|
static unsigned s_Primes[7] = {4177, 5147, 5647, 6343, 7103, 7873, 8147};
|
|
unsigned Key = 0;
|
|
int i, Entry;
|
|
Vec_IntForEachEntry( vVec, Entry, i )
|
|
Key += (unsigned)Entry * s_Primes[i % 7];
|
|
return (int)(Key % nTableSize);
|
|
}
|
|
static inline int Hsh_VecManAdd( Hsh_VecMan_t * p, Vec_Int_t * vVec )
|
|
{
|
|
Hsh_VecObj_t * pObj;
|
|
int i, Ent, * pPlace;
|
|
if ( Vec_IntSize(p->vMap) > Vec_IntSize(p->vTable) )
|
|
{
|
|
Vec_IntFill( p->vTable, Abc_PrimeCudd(2*Vec_IntSize(p->vTable)), -1 );
|
|
for ( i = 0; i < Vec_IntSize(p->vMap); i++ )
|
|
{
|
|
pPlace = Vec_IntEntryP( p->vTable, Hsh_VecManHash(Hsh_VecReadEntry(p, i), Vec_IntSize(p->vTable)) );
|
|
Hsh_VecObj(p, i)->iNext = *pPlace; *pPlace = i;
|
|
}
|
|
}
|
|
pPlace = Vec_IntEntryP( p->vTable, Hsh_VecManHash(vVec, Vec_IntSize(p->vTable)) );
|
|
for ( ; (pObj = Hsh_VecObj(p, *pPlace)); pPlace = &pObj->iNext )
|
|
if ( pObj->nSize == Vec_IntSize(vVec) && !memcmp( pObj->pArray, Vec_IntArray(vVec), sizeof(int) * pObj->nSize ) )
|
|
return *pPlace;
|
|
*pPlace = Vec_IntSize(p->vMap);
|
|
assert( Vec_IntSize(p->vData) % 2 == 0 );
|
|
Vec_IntPush( p->vMap, Vec_IntSize(p->vData) );
|
|
Vec_IntPush( p->vData, Vec_IntSize(vVec) );
|
|
Vec_IntPush( p->vData, -1 );
|
|
Vec_IntForEachEntry( vVec, Ent, i )
|
|
Vec_IntPush( p->vData, Ent );
|
|
if ( Vec_IntSize(vVec) & 1 )
|
|
Vec_IntPush( p->vData, -1 );
|
|
return Vec_IntSize(p->vMap) - 1;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Test procedure.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline void Hsh_VecManHashTest()
|
|
{
|
|
Hsh_VecMan_t * p;
|
|
Vec_Int_t * vTemp;
|
|
Vec_Int_t * vRes = Vec_IntAlloc( 1000 );
|
|
int i;
|
|
|
|
p = Hsh_VecManStart( 5 );
|
|
for ( i = 0; i < 20; i++ )
|
|
{
|
|
vTemp = Vec_IntStartNatural( i );
|
|
Vec_IntPush( vRes, Hsh_VecManAdd( p, vTemp ) );
|
|
Vec_IntFree( vTemp );
|
|
}
|
|
for ( ; i > 0; i-- )
|
|
{
|
|
vTemp = Vec_IntStartNatural( i );
|
|
Vec_IntPush( vRes, Hsh_VecManAdd( p, vTemp ) );
|
|
Vec_IntFree( vTemp );
|
|
}
|
|
Vec_IntPrint( vRes );
|
|
Vec_IntFree( vRes );
|
|
|
|
Hsh_VecManStop( p );
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
ABC_NAMESPACE_HEADER_END
|
|
|
|
#endif
|
|
|