1 #ifndef vtkExodusIICache_h 2 #define vtkExodusIICache_h 3 4 // ============================================================================ 5 // The following classes define an LRU cache for data arrays 6 // loaded by the Exodus reader. Here's how they work: 7 // 8 // The actual cache consists of two STL containers: a set of 9 // cache entries (vtkExodusIICacheEntry) and a list of 10 // cache references (vtkExodusIICacheRef). The entries in 11 // these containers are sorted for fast retrieval: 12 // 1. The cache entries are indexed by the timestep, the 13 // object type (edge block, face set, ...), and the 14 // object ID (if one exists). When you call Find() to 15 // retrieve a cache entry, you provide a key containing 16 // this information and the array is returned if it exists. 17 // 2. The list of cache references are stored in "least-recently-used" 18 // order. The least recently referenced array is the first in 19 // the list. Whenever you request an entry with Find(), it is 20 // moved to the back of the list if it exists. 21 // This makes retrieving arrays O(n log n) and popping LRU 22 // entries O(1). Each cache entry stores an iterator into 23 // the list of references so that it can be located quickly for 24 // removal. 25 26 #include "vtkIOExodusModule.h" // For export macro 27 #include "vtkObject.h" 28 29 #include <map> // used for cache storage 30 #include <list> // use for LRU ordering 31 32 class VTKIOEXODUS_EXPORT vtkExodusIICacheKey 33 { 34 public: 35 int Time; 36 int ObjectType; 37 int ObjectId; 38 int ArrayId; vtkExodusIICacheKey()39 vtkExodusIICacheKey() 40 { 41 Time = -1; 42 ObjectType = -1; 43 ObjectId = -1; 44 ArrayId = -1; 45 } vtkExodusIICacheKey(int time,int objType,int objId,int arrId)46 vtkExodusIICacheKey( int time, int objType, int objId, int arrId ) 47 { 48 Time = time; 49 ObjectType = objType; 50 ObjectId = objId; 51 ArrayId = arrId; 52 } vtkExodusIICacheKey(const vtkExodusIICacheKey & src)53 vtkExodusIICacheKey( const vtkExodusIICacheKey& src ) 54 { 55 Time = src.Time; 56 ObjectType = src.ObjectType; 57 ObjectId = src.ObjectId; 58 ArrayId = src.ArrayId; 59 } 60 vtkExodusIICacheKey& operator = ( const vtkExodusIICacheKey& src ) 61 { 62 Time = src.Time; 63 ObjectType = src.ObjectType; 64 ObjectId = src.ObjectId; 65 ArrayId = src.ArrayId; 66 return *this; 67 } match(const vtkExodusIICacheKey & other,const vtkExodusIICacheKey & pattern)68 bool match( const vtkExodusIICacheKey&other, const vtkExodusIICacheKey& pattern ) const 69 { 70 if ( pattern.Time && this->Time != other.Time ) 71 return false; 72 if ( pattern.ObjectType && this->ObjectType != other.ObjectType ) 73 return false; 74 if ( pattern.ObjectId && this->ObjectId != other.ObjectId ) 75 return false; 76 if ( pattern.ArrayId && this->ArrayId != other.ArrayId ) 77 return false; 78 return true; 79 } 80 bool operator < ( const vtkExodusIICacheKey& other ) const 81 { 82 if ( this->Time < other.Time ) 83 return true; 84 else if ( this->Time > other.Time ) 85 return false; 86 if ( this->ObjectType < other.ObjectType ) 87 return true; 88 else if ( this->ObjectType > other.ObjectType ) 89 return false; 90 if ( this->ObjectId < other.ObjectId ) 91 return true; 92 else if ( this->ObjectId > other.ObjectId ) 93 return false; 94 if ( this->ArrayId < other.ArrayId ) 95 return true; 96 return false; 97 } 98 }; 99 100 class vtkExodusIICacheEntry; 101 class vtkExodusIICache; 102 class vtkDataArray; 103 104 typedef std::map<vtkExodusIICacheKey,vtkExodusIICacheEntry*> vtkExodusIICacheSet; 105 typedef std::map<vtkExodusIICacheKey,vtkExodusIICacheEntry*>::iterator vtkExodusIICacheRef; 106 typedef std::list<vtkExodusIICacheRef> vtkExodusIICacheLRU; 107 typedef std::list<vtkExodusIICacheRef>::iterator vtkExodusIICacheLRURef; 108 109 class VTKIOEXODUS_EXPORT vtkExodusIICacheEntry 110 { 111 public: 112 vtkExodusIICacheEntry(); 113 vtkExodusIICacheEntry( vtkDataArray* arr ); 114 vtkExodusIICacheEntry( const vtkExodusIICacheEntry& other ); 115 116 ~vtkExodusIICacheEntry(); 117 GetValue()118 vtkDataArray* GetValue() { return this->Value; } 119 120 protected: 121 vtkDataArray* Value; 122 vtkExodusIICacheLRURef LRUEntry; 123 124 friend class vtkExodusIICache; 125 }; 126 127 class VTKIOEXODUS_EXPORT vtkExodusIICache : public vtkObject 128 { 129 public: 130 static vtkExodusIICache* New(); 131 vtkTypeMacro(vtkExodusIICache,vtkObject); 132 void PrintSelf( ostream& os, vtkIndent indent ) override; 133 134 /// Empty the cache 135 void Clear(); 136 137 /// Set the maximum allowable cache size. This will remove cache entries if the capacity is reduced below the current size. 138 void SetCacheCapacity( double sizeInMiB ); 139 140 /** See how much cache space is left. 141 * This is the difference between the capacity and the size of the cache. 142 * The result is in MiB. 143 */ GetSpaceLeft()144 double GetSpaceLeft() 145 { return this->Capacity - this->Size; } 146 147 /** Remove cache entries until the size of the cache is at or below the given size. 148 * Returns a nonzero value if deletions were required. 149 */ 150 int ReduceToSize( double newSize ); 151 152 /// Insert an entry into the cache (this can remove other cache entries to make space). 153 void Insert( vtkExodusIICacheKey& key, vtkDataArray* value ); 154 155 /** Determine whether a cache entry exists. If it does, return it -- otherwise return nullptr. 156 * If a cache entry exists, it is marked as most recently used. 157 */ 158 vtkDataArray*& Find( const vtkExodusIICacheKey& ); 159 160 /** Invalidate a cache entry (drop it from the cache) if the key exists. 161 * This does nothing if the cache entry does not exist. 162 * Returns 1 if the cache entry existed prior to this call and 0 otherwise. 163 */ 164 int Invalidate( const vtkExodusIICacheKey& key ); 165 166 /** Invalidate all cache entries matching a specified pattern, dropping all matches from the cache. 167 * Any nonzero entry in the \a pattern forces a comparison between the corresponding value of \a key. 168 * Any cache entries satisfying all the comparisons will be dropped. 169 * If pattern is entirely zero, this will empty the entire cache. 170 * This is useful for invalidating all entries of a given object type. 171 * 172 * Returns the number of cache entries dropped. 173 * It is not an error to specify an empty range -- 0 will be returned if one is given. 174 */ 175 int Invalidate( const vtkExodusIICacheKey& key, const vtkExodusIICacheKey& pattern ); 176 177 protected: 178 /// Default constructor 179 vtkExodusIICache(); 180 181 /// Destructor. 182 ~vtkExodusIICache() override; 183 184 185 /// Avoid (some) FP problems 186 void RecomputeSize(); 187 188 /// The capacity of the cache (i.e., the maximum size of all arrays it contains) in MiB. 189 double Capacity; 190 191 /// The current size of the cache (i.e., the size of the all the arrays it currently contains) in MiB. 192 double Size; 193 194 /** A least-recently-used (LRU) cache to hold arrays. 195 * During RequestData the cache may contain more than its maximum size since 196 * the user may request more data than the cache can hold. However, the cache 197 * is expunged whenever a new array is loaded. Never count on the cache holding 198 * what you request for very long. 199 */ 200 vtkExodusIICacheSet Cache; 201 202 /// The actual LRU list (indices into the cache ordered least to most recently used). 203 vtkExodusIICacheLRU LRU; 204 205 private: 206 vtkExodusIICache( const vtkExodusIICache& ) = delete; 207 void operator = ( const vtkExodusIICache& ) = delete; 208 }; 209 #endif // vtkExodusIICache_h 210