source: vis_dev/sharpSAT/src/src_sharpSAT/MainSolver/FormulaCache.h @ 9

Last change on this file since 9 was 9, checked in by cecile, 13 years ago

add sharpSat

File size: 8.7 KB
Line 
1#ifndef FORMULACACHE_H
2#define FORMULACACHE_H
3
4
5#ifdef DEBUG
6#include<assert.h>
7#endif
8   
9#include <sys/sysinfo.h>
10#include <vector>
11#include <iostream>
12
13
14#include <SomeTime.h>
15#include <RealNumberTypes.h>
16#include <Interface/AnalyzerData.h>
17
18
19#include "../Basics.h"
20#include "InstanceGraph/ComponentTypes.h"
21#include "DecisionStack.h"
22using namespace std;
23
24typedef unsigned int CacheEntryId;
25
26class CCacheEntry : public CPackedCompId<unsigned int>
27{
28  long unsigned int hashKey;
29  friend class CFormulaCache; 
30 
31  // theFather and theDescendants:
32  // each CCacheEntry is a Node in a tree which represents the relationship
33  // of the components stored
34  CacheEntryId theFather;
35  vector<CacheEntryId> theDescendants;
36 
37 public: 
38 
39  CRealNum   theVal;
40 
41  unsigned int score;
42 
43  CCacheEntry()
44  {
45    score = 0;
46    theFather = 0;
47  }
48   
49   
50  void clear()
51  {
52   theVars.clear();
53   theClauses.clear();
54   theDescendants.clear();
55  }
56 
57 
58  ~CCacheEntry()
59  {
60    theDescendants.clear();
61    theFather = 0;
62    clear();
63  }
64 
65 
66  long unsigned int getHashKey() const
67  {
68    return hashKey;
69  }
70 
71  void setHashKey(long unsigned int &val)
72  {
73    hashKey = val;
74  }
75 
76  unsigned int memSize()
77  {
78    return  CPackedCompId<unsigned int>::memSize() + theDescendants.capacity()*sizeof(CacheEntryId);
79  }
80 
81  void substituteDescendant(CacheEntryId iold, CacheEntryId inew)
82  {
83    vector<CacheEntryId>::iterator it;
84    for(it = theDescendants.begin();it != theDescendants.end();it++)
85    {
86      if(*it == iold) *it = inew;
87    }
88  }
89 
90  void removeDescendant(CacheEntryId d)
91  {
92    vector<CacheEntryId>::iterator it;
93    for(it = theDescendants.end()-1;it != theDescendants.begin()-1;it--)
94    {
95      if(*it == d)
96      {
97        it = theDescendants.erase(it);
98      }
99    }
100  }
101 
102 
103  void addDescendants(vector<CacheEntryId> &dVec)
104  {
105    theDescendants.insert(theDescendants.end(),dVec.begin(),dVec.end());   
106  }
107 
108  CacheEntryId getFather() {return theFather;}
109  void substituteFather(CacheEntryId newFather){theFather = newFather;} 
110 
111 
112};
113
114
115class CCacheBucket : protected vector<CacheEntryId>
116{ 
117  friend class CFormulaCache;   
118 
119 
120 public: 
121   
122  CCacheBucket()
123  {     
124  } 
125 
126  ~CCacheBucket()
127  {
128    clear();
129  }
130 
131  bool substituteIds(CacheEntryId oldId, CacheEntryId newId)
132  {
133    for(CCacheBucket::iterator it = begin(); it != end(); it++)
134    {
135     if(*it == oldId) { *it = newId; return true;}     
136    }
137    return false;
138  }
139 
140  using vector<CacheEntryId>::size; 
141};
142
143class CFormulaCache
144{ 
145  vector<CCacheBucket> theBucketBase; 
146 
147  vector<CCacheEntry> theEntryBase;
148 
149  #define NIL_ENTRY 0
150 
151  vector<CCacheBucket *> theData; 
152 
153  vector<CCacheEntry>::iterator beginEntries(){return theEntryBase.begin()+1;}
154  vector<CCacheEntry>::iterator endEntries(){return theEntryBase.end();}
155 
156  CacheEntryId toCacheEntryId(vector<CCacheEntry>::iterator &it)
157  {
158    return (CacheEntryId)(it - theEntryBase.begin());
159  }
160 
161 
162  unsigned int iBuckets;
163  static unsigned int oldestEntryAllowed; 
164  /* statistics */
165  unsigned int iCacheRetrievals;
166  unsigned int iSumRetrieveSize;
167  unsigned int iCacheTries;
168 
169  unsigned int iCachedComponents;
170  unsigned int iSumCachedCompSize;
171  unsigned int iSumCachedMemSize;
172  unsigned int iUsedBuckets; 
173  unsigned int scoresDivTime;
174  unsigned int minScoreBound;
175 
176  unsigned int lastDivTime;
177 
178  /*end statistics */
179  unsigned int memUsage; 
180  //unsigned int maxMemUsage; 
181 
182  double avgCachedSize() 
183  {
184     if(iCacheRetrievals == 0) return 0.0;
185     return (double) iSumCachedCompSize / (double) iCachedComponents;
186  }
187 
188  double avgCachedMemSize() 
189  {
190     if(iCacheRetrievals == 0) return 0.0;
191     return (double) memUsage / (double) iCachedComponents;
192  }
193 
194  double avgHitSize() 
195  {
196     if(iCacheRetrievals == 0) return 0.0;
197     return (double) iSumRetrieveSize / (double) iCacheRetrievals;
198  }
199 
200  unsigned int clip(unsigned int ofs)
201  {
202    return ofs % iBuckets;
203  }
204 
205  unsigned int clip(long unsigned int ofs)
206  {
207    return ofs % iBuckets;
208  }
209 
210  bool isEntry(CacheEntryId theId)
211  {
212    return (theId != 0) & (theId < theEntryBase.size());
213  }
214 
215  CCacheEntry &entry(CacheEntryId theId)
216  {
217    #ifdef DEBUG
218    assert(theId < theEntryBase.size());
219    #endif
220    return theEntryBase[theId]; 
221  }
222 
223  CacheEntryId newEntry()
224  {   
225    theEntryBase.push_back(CCacheEntry());
226    return theEntryBase.size()-1;
227  }
228 
229  unsigned int memSizeOf(CCacheBucket &rBuck)
230  {
231   unsigned int n = 0; 
232   for(CCacheBucket::iterator it = rBuck.begin();it!= rBuck.end();it++)
233   {
234     n += entry(*it).memSize();
235   }
236   return n;
237  }
238 
239  CCacheBucket *createNewCacheBucket()
240  {
241    theBucketBase.push_back(CCacheBucket());
242    iUsedBuckets++;
243    return &theBucketBase.back();
244  }
245 
246  CCacheBucket &at(unsigned int ofs)
247  {
248    if(theData[ofs] == NULL) theData[ofs] = createNewCacheBucket();
249    return *theData[ofs];
250  }
251 
252  bool isBucketAt(unsigned int ofs)
253  {
254    #ifdef DEBUG
255    assert(theData.size() > ofs);   
256    #endif
257    return theData[ofs] != NULL;
258  }
259 
260 public:
261 
262  unsigned int getScoresDivTime() {return scoresDivTime;}
263  unsigned int getLastDivTime() {return lastDivTime;}
264  void setLastDivTime(unsigned int d) {lastDivTime = d;}
265 
266  CFormulaCache();
267 
268  ~CFormulaCache()
269  {   
270    reset();
271  }
272 
273  void init()
274  {
275    theBucketBase.clear();
276    theData.clear();
277    theEntryBase.clear();
278    theEntryBase.push_back(CCacheEntry()); // dummy Element
279    theData.resize(iBuckets,NULL);
280    theBucketBase.reserve(iBuckets);
281    iUsedBuckets = 0;
282    memUsage = 0;
283    iCachedComponents = 0;
284    iCacheRetrievals = 0;
285    iSumRetrieveSize = 0;
286    iSumCachedCompSize = 0;
287    iSumCachedMemSize = 0;
288    iCacheTries = 0;
289    minScoreBound = 0;
290  }
291 
292  void reset()
293  {
294    theBucketBase.clear();
295    theEntryBase.clear();
296    theData.clear();
297  } 
298 
299  void printStatistics(CRunAnalyzer & rAn)
300  {
301    rAn.setValue(FCACHE_MAXMEM,CSolverConf::maxCacheSize);  // Formula Cache Memory Bound
302    rAn.setValue(FCACHE_MEMUSE,memUsage);  // Formula Cache memory usage
303    rAn.setValue(FCACHE_USEDBUCKETS,iUsedBuckets); // number of hashbuckets used
304    rAn.setValue(FCACHE_CACHEDCOMPS,iCachedComponents);
305    rAn.setValue(FCACHE_RETRIEVALS,iCacheRetrievals); // number of retrieved components
306    rAn.setValue(FCACHE_INCLUDETRIES,iCacheTries); // number of times it was tried to put a component into the cache   
307   
308  }
309 
310  void divCacheScores()
311  {     
312     for(vector<CCacheEntry>::iterator it =  theEntryBase.begin(); it != theEntryBase.end(); it++)
313     { 
314       (it->score) >>= 1;     
315     }
316  }
317 
318  long unsigned int computeHashVal(const CComponentId &rComp);
319   
320  bool include(CComponentId &rComp, const CRealNum &val);
321
322  bool extract(CComponentId &rComp, CRealNum &val);
323 
324  bool deleteEntries(CDecisionStack & rDecStack);
325 
326  void revalidateCacheLinksIn(const vector<CComponentId*> &rComps);
327  void substituteCacheLinksIn(const vector<CComponentId*> &rComps, CacheEntryId idOld, CacheEntryId idNew);
328 
329 
330  int removePollutedEntries(CacheEntryId root); // remove the whole tree below root
331 
332 
333  bool cacheCompaction(CDecisionStack & rDecStack);
334 
335  void adjustDescendantsFather(CacheEntryId father)
336  {
337    vector<CacheEntryId>::iterator it;
338    for(it = entry(father).theDescendants.begin();
339        it != entry(father).theDescendants.end();it++)
340    {
341      entry(*it).theFather = father;
342    }
343  }
344 
345  // delete entries, keeping the descendants tree consistent
346  void deleteFromDescendantsTree(CacheEntryId rEnt)
347  { 
348     // let ME be the entry to be deleted
349     CacheEntryId father = entry(rEnt).getFather();
350     // first remove link from father to ME
351     if(father != NIL_ENTRY)
352     {
353       entry(father).removeDescendant(rEnt);
354       // then add all my descendants to descendants of father
355       entry(father).addDescendants(entry(rEnt).theDescendants);
356     }
357     // next all MY descendants have now father father
358     vector<CacheEntryId>::iterator it;
359     for(it = entry(rEnt).theDescendants.begin();
360         it != entry(rEnt).theDescendants.end();
361         it++)
362         {
363           entry(*it).substituteFather(father);
364         } 
365  }
366 
367  void substituteInDescTree(CacheEntryId rOld, CacheEntryId rNew)
368  { 
369     // let ME be the entry to be deleted
370     CacheEntryId father = entry(rOld).getFather();
371     // first subst link from father to ME     
372     
373     if(father != NIL_ENTRY)
374     {
375       #ifdef DEBUG
376       assert(isEntry(father));
377       #endif
378       entry(father).substituteDescendant(rOld, rNew);
379     }         
380     // next all MY descendants get father rNew
381     vector<CacheEntryId>::iterator it;
382     for(it = entry(rOld).theDescendants.begin();
383         it != entry(rOld).theDescendants.end();
384         it++)
385         {
386           #ifdef DEBUG
387           assert(isEntry(*it));
388           #endif
389           entry(*it).substituteFather(rNew);
390         }
391  }
392 
393};
394
395
396
397#endif
Note: See TracBrowser for help on using the repository browser.