1 /**CFile****************************************************************
2 
3   FileName    [vecSet.h]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [SAT solvers.]
8 
9   Synopsis    [Multi-page dynamic array.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - June 20, 2005.]
16 
17   Revision    [$Id: vecSet.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #ifndef ABC__sat__bsat__vecSet_h
22 #define ABC__sat__bsat__vecSet_h
23 
24 
25 ////////////////////////////////////////////////////////////////////////
26 ///                          INCLUDES                                ///
27 ////////////////////////////////////////////////////////////////////////
28 
29 #include <stdio.h>
30 
31 ABC_NAMESPACE_HEADER_START
32 
33 
34 ////////////////////////////////////////////////////////////////////////
35 ///                         PARAMETERS                               ///
36 ////////////////////////////////////////////////////////////////////////
37 
38 ////////////////////////////////////////////////////////////////////////
39 ///                         BASIC TYPES                              ///
40 ////////////////////////////////////////////////////////////////////////
41 
42 // data-structure for logging entries
43 // memory is allocated in 2^nPageSize word-sized pages
44 // the first two 'words' of each page are used for bookkeeping
45 // the first 'word' of bookkeeping data stores the word limit
46 // the second 'word' of bookkeeping data stores the shadow word limit
47 // (the shadow word limit is only used during garbage collection)
48 
49 typedef struct Vec_Set_t_ Vec_Set_t;
50 struct Vec_Set_t_
51 {
52     int               nPageSize;    // page size
53     unsigned          uPageMask;    // page mask
54     int               nEntries;     // entry count
55     int               iPage;        // current page
56     int               iPageS;       // shadow page
57     int               nPagesAlloc;  // page count allocated
58     word **           pPages;       // page pointers
59 };
60 
61 ////////////////////////////////////////////////////////////////////////
62 ///                      MACRO DEFINITIONS                           ///
63 ////////////////////////////////////////////////////////////////////////
64 
Vec_SetHandPage(Vec_Set_t * p,int h)65 static inline int     Vec_SetHandPage( Vec_Set_t * p, int h )    { return h >> p->nPageSize;      }
Vec_SetHandShift(Vec_Set_t * p,int h)66 static inline int     Vec_SetHandShift( Vec_Set_t * p, int h )   { return h & p->uPageMask;       }
Vec_SetWordNum(int nSize)67 static inline int     Vec_SetWordNum( int nSize )                { return (nSize + 1) >> 1;       }
68 
69 //static inline word *  Vec_SetEntry( Vec_Set_t * p, int h )       { assert(Vec_SetHandPage(p, h) >= 0 && Vec_SetHandPage(p, h) <= p->iPage); assert(Vec_SetHandShift(p, h) >= 2 && Vec_SetHandShift(p, h) < (1 << p->nPageSize)); return p->pPages[Vec_SetHandPage(p, h)] + Vec_SetHandShift(p, h);     }
Vec_SetEntry(Vec_Set_t * p,int h)70 static inline word *  Vec_SetEntry( Vec_Set_t * p, int h )       { return p->pPages[Vec_SetHandPage(p, h)] + Vec_SetHandShift(p, h);                     }
Vec_SetEntryNum(Vec_Set_t * p)71 static inline int     Vec_SetEntryNum( Vec_Set_t * p )           { return p->nEntries;            }
Vec_SetWriteEntryNum(Vec_Set_t * p,int i)72 static inline void    Vec_SetWriteEntryNum( Vec_Set_t * p, int i){ p->nEntries = i;               }
73 
Vec_SetLimit(word * p)74 static inline int     Vec_SetLimit( word * p )                   { return p[0];                   }
Vec_SetLimitS(word * p)75 static inline int     Vec_SetLimitS( word * p )                  { return p[1];                   }
76 
Vec_SetIncLimit(word * p,int nWords)77 static inline int     Vec_SetIncLimit( word * p, int nWords )    { return p[0] += nWords;         }
Vec_SetIncLimitS(word * p,int nWords)78 static inline int     Vec_SetIncLimitS( word * p, int nWords )   { return p[1] += nWords;         }
79 
Vec_SetWriteLimit(word * p,int nWords)80 static inline void    Vec_SetWriteLimit( word * p, int nWords )  { p[0] = nWords;                 }
Vec_SetWriteLimitS(word * p,int nWords)81 static inline void    Vec_SetWriteLimitS( word * p, int nWords ) { p[1] = nWords;                 }
82 
Vec_SetHandCurrent(Vec_Set_t * p)83 static inline int     Vec_SetHandCurrent( Vec_Set_t * p )        { return (p->iPage << p->nPageSize)  + Vec_SetLimit(p->pPages[p->iPage]);               }
Vec_SetHandCurrentS(Vec_Set_t * p)84 static inline int     Vec_SetHandCurrentS( Vec_Set_t * p )       { return (p->iPageS << p->nPageSize) + Vec_SetLimitS(p->pPages[p->iPageS]);             }
85 
Vec_SetHandMemory(Vec_Set_t * p,int h)86 static inline int     Vec_SetHandMemory( Vec_Set_t * p, int h )  { return Vec_SetHandPage(p, h) * (1 << (p->nPageSize+3)) + Vec_SetHandShift(p, h) * 8;  }
Vec_SetMemory(Vec_Set_t * p)87 static inline int     Vec_SetMemory( Vec_Set_t * p )             { return Vec_SetHandMemory(p, Vec_SetHandCurrent(p));                                   }
Vec_SetMemoryS(Vec_Set_t * p)88 static inline int     Vec_SetMemoryS( Vec_Set_t * p )            { return Vec_SetHandMemory(p, Vec_SetHandCurrentS(p));                                  }
Vec_SetMemoryAll(Vec_Set_t * p)89 static inline int     Vec_SetMemoryAll( Vec_Set_t * p )          { return (p->iPage+1) * (1 << (p->nPageSize+3));                                        }
90 
91 // Type is the Set type
92 // pVec is vector of set
93 // nSize should be given by the user
94 // pSet is the pointer to the set
95 // p (page) and s (shift) are variables used here
96 #define Vec_SetForEachEntry( Type, pVec, nSize, pSet, p, s )   \
97     for ( p = 0; p <= pVec->iPage; p++ )                       \
98         for ( s = 2; s < Vec_SetLimit(pVec->pPages[p]) && ((pSet) = (Type)(pVec->pPages[p] + (s))); s += nSize )
99 
100 ////////////////////////////////////////////////////////////////////////
101 ///                     FUNCTION DEFINITIONS                         ///
102 ////////////////////////////////////////////////////////////////////////
103 
104 /**Function*************************************************************
105 
106   Synopsis    [Allocating vector.]
107 
108   Description []
109 
110   SideEffects []
111 
112   SeeAlso     []
113 
114 ***********************************************************************/
Vec_SetAlloc_(Vec_Set_t * p,int nPageSize)115 static inline void Vec_SetAlloc_( Vec_Set_t * p, int nPageSize )
116 {
117     assert( nPageSize > 8 );
118     memset( p, 0, sizeof(Vec_Set_t) );
119     p->nPageSize    = nPageSize;
120     p->uPageMask    = (unsigned)((1 << nPageSize) - 1);
121     p->nPagesAlloc  = 256;
122     p->pPages       = ABC_CALLOC( word *, p->nPagesAlloc );
123     p->pPages[0]    = ABC_ALLOC( word, (int)(((word)1) << p->nPageSize) );
124     p->pPages[0][0] = ~0;
125     p->pPages[0][1] = ~0;
126     Vec_SetWriteLimit( p->pPages[0], 2 );
127 }
Vec_SetAlloc(int nPageSize)128 static inline Vec_Set_t * Vec_SetAlloc( int nPageSize )
129 {
130     Vec_Set_t * p;
131     p = ABC_CALLOC( Vec_Set_t, 1 );
132     Vec_SetAlloc_( p, nPageSize );
133     return p;
134 }
135 
136 /**Function*************************************************************
137 
138   Synopsis    [Resetting vector.]
139 
140   Description []
141 
142   SideEffects []
143 
144   SeeAlso     []
145 
146 ***********************************************************************/
Vec_SetRestart(Vec_Set_t * p)147 static inline void Vec_SetRestart( Vec_Set_t * p )
148 {
149     p->nEntries     = 0;
150     p->iPage        = 0;
151     p->iPageS       = 0;
152     p->pPages[0][0] = ~0;
153     p->pPages[0][1] = ~0;
154     Vec_SetWriteLimit( p->pPages[0], 2 );
155 }
156 
157 /**Function*************************************************************
158 
159   Synopsis    [Freeing vector.]
160 
161   Description []
162 
163   SideEffects []
164 
165   SeeAlso     []
166 
167 ***********************************************************************/
Vec_SetFree_(Vec_Set_t * p)168 static inline void Vec_SetFree_( Vec_Set_t * p )
169 {
170     int i;
171     if ( p == NULL ) return;
172     for ( i = 0; i < p->nPagesAlloc; i++ )
173         ABC_FREE( p->pPages[i] );
174     ABC_FREE( p->pPages );
175 }
Vec_SetFree(Vec_Set_t * p)176 static inline void Vec_SetFree( Vec_Set_t * p )
177 {
178     if ( p == NULL ) return;
179     Vec_SetFree_( p );
180     ABC_FREE( p );
181 }
182 
183 /**Function*************************************************************
184 
185   Synopsis    [Returns memory in bytes occupied by the vector.]
186 
187   Description []
188 
189   SideEffects []
190 
191   SeeAlso     []
192 
193 ***********************************************************************/
Vec_ReportMemory(Vec_Set_t * p)194 static inline double Vec_ReportMemory( Vec_Set_t * p )
195 {
196     double Mem = sizeof(Vec_Set_t);
197     Mem += p->nPagesAlloc * sizeof(void *);
198     Mem += sizeof(word) * (size_t)(((word)1) << p->nPageSize) * (size_t)(1 + p->iPage);
199     return Mem;
200 }
201 
202 /**Function*************************************************************
203 
204   Synopsis    [Appending entries to vector.]
205 
206   Description []
207 
208   SideEffects []
209 
210   SeeAlso     []
211 
212 ***********************************************************************/
Vec_SetAppend(Vec_Set_t * p,int * pArray,int nSize)213 static inline int Vec_SetAppend( Vec_Set_t * p, int * pArray, int nSize )
214 {
215     int nWords = Vec_SetWordNum( nSize );
216     assert( nWords < (1 << p->nPageSize) );
217     p->nEntries++;
218     if ( Vec_SetLimit( p->pPages[p->iPage] ) + nWords >= (1 << p->nPageSize) )
219     {
220         if ( ++p->iPage == p->nPagesAlloc )
221         {
222             p->pPages = ABC_REALLOC( word *, p->pPages, p->nPagesAlloc * 2 );
223             memset( p->pPages + p->nPagesAlloc, 0, sizeof(word *) * (size_t)p->nPagesAlloc );
224             p->nPagesAlloc *= 2;
225         }
226         if ( p->pPages[p->iPage] == NULL )
227             p->pPages[p->iPage] = ABC_ALLOC( word, (int)(((word)1) << p->nPageSize) );
228         Vec_SetWriteLimit( p->pPages[p->iPage], 2 );
229         p->pPages[p->iPage][1] = ~0;
230     }
231     if ( pArray )
232         memcpy( p->pPages[p->iPage] + Vec_SetLimit(p->pPages[p->iPage]), pArray, sizeof(int) * (size_t)nSize );
233     Vec_SetIncLimit( p->pPages[p->iPage], nWords );
234     return Vec_SetHandCurrent(p) - nWords;
235 }
Vec_SetAppendS(Vec_Set_t * p,int nSize)236 static inline int Vec_SetAppendS( Vec_Set_t * p, int nSize )
237 {
238     int nWords = Vec_SetWordNum( nSize );
239     assert( nWords < (1 << p->nPageSize) );
240     if ( Vec_SetLimitS( p->pPages[p->iPageS] ) + nWords >= (1 << p->nPageSize) )
241         Vec_SetWriteLimitS( p->pPages[++p->iPageS], 2 );
242     Vec_SetIncLimitS( p->pPages[p->iPageS], nWords );
243     return Vec_SetHandCurrentS(p) - nWords;
244 }
Vec_SetFetchH(Vec_Set_t * p,int nBytes)245 static inline int Vec_SetFetchH( Vec_Set_t * p, int nBytes )
246 {
247     return Vec_SetAppend(p, NULL, (nBytes + 3) >> 2);
248 }
Vec_SetFetch(Vec_Set_t * p,int nBytes)249 static inline void * Vec_SetFetch( Vec_Set_t * p, int nBytes )
250 {
251     return (void *)Vec_SetEntry( p, Vec_SetFetchH(p, nBytes) );
252 }
Vec_SetStrsav(Vec_Set_t * p,char * pName)253 static inline char * Vec_SetStrsav( Vec_Set_t * p, char * pName )
254 {
255     char * pStr = (char *)Vec_SetFetch( p, (int)strlen(pName) + 1 );
256     strcpy( pStr, pName );
257     return pStr;
258 }
259 
260 /**Function*************************************************************
261 
262   Synopsis    [Shrinking vector size.]
263 
264   Description []
265 
266   SideEffects [This procedure does not update the number of entries.]
267 
268   SeeAlso     []
269 
270 ***********************************************************************/
Vec_SetShrink(Vec_Set_t * p,int h)271 static inline void Vec_SetShrink( Vec_Set_t * p, int h )
272 {
273     assert( h <= Vec_SetHandCurrent(p) );
274     p->iPage = Vec_SetHandPage(p, h);
275     Vec_SetWriteLimit( p->pPages[p->iPage], Vec_SetHandShift(p, h) );
276 }
Vec_SetShrinkS(Vec_Set_t * p,int h)277 static inline void Vec_SetShrinkS( Vec_Set_t * p, int h )
278 {
279     assert( h <= Vec_SetHandCurrent(p) );
280     p->iPageS = Vec_SetHandPage(p, h);
281     Vec_SetWriteLimitS( p->pPages[p->iPageS], Vec_SetHandShift(p, h) );
282 }
283 
Vec_SetShrinkLimits(Vec_Set_t * p)284 static inline void Vec_SetShrinkLimits( Vec_Set_t * p )
285 {
286     int i;
287     for ( i = 0; i <= p->iPage; i++ )
288         Vec_SetWriteLimit( p->pPages[i], Vec_SetLimitS(p->pPages[i]) );
289 }
290 
291 
292 ABC_NAMESPACE_HEADER_END
293 
294 #endif
295 
296 ////////////////////////////////////////////////////////////////////////
297 ///                       END OF FILE                                ///
298 ////////////////////////////////////////////////////////////////////////
299 
300