vtkExodusIICache.h 6.95 KB
Newer Older
1
2
3
4
5
6
#ifndef __vtkExodusIICache_h
#define __vtkExodusIICache_h

// ============================================================================
// The following classes define an LRU cache for data arrays
// loaded by the Exodus reader. Here's how they work:
7
//
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// The actual cache consists of two STL containers: a set of
// cache entries (vtkExodusIICacheEntry) and a list of
// cache references (vtkExodusIICacheRef). The entries in
// these containers are sorted for fast retrieval:
// 1. The cache entries are indexed by the timestep, the
//    object type (edge block, face set, ...), and the
//    object ID (if one exists). When you call Find() to
//    retrieve a cache entry, you provide a key containing
//    this information and the array is returned if it exists.
// 2. The list of cache references are stored in "least-recently-used"
//    order. The least recently referenced array is the first in
//    the list. Whenever you request an entry with Find(), it is
//    moved to the back of the list if it exists.
// This makes retrieving arrays O(n log n) and popping LRU
// entries O(1). Each cache entry stores an iterator into
// the list of references so that it can be located quickly for
// removal.

26
#include "vtkIOExodusModule.h" // For export macro
27
#include "vtkObject.h"
28

29
30
#include <map> // used for cache storage
#include <list> // use for LRU ordering
31
32

//BTX
33
class VTKIOEXODUS_EXPORT vtkExodusIICacheKey
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
{
public:
  int Time;
  int ObjectType;
  int ObjectId;
  int ArrayId;
  vtkExodusIICacheKey()
    {
    Time = -1;
    ObjectType = -1;
    ObjectId = -1;
    ArrayId = -1;
    }
  vtkExodusIICacheKey( int time, int objType, int objId, int arrId )
    {
    Time = time;
    ObjectType = objType;
    ObjectId = objId;
    ArrayId = arrId;
    }
54
55
56
57
58
59
60
  vtkExodusIICacheKey( const vtkExodusIICacheKey& src )
    {
    Time = src.Time;
    ObjectType = src.ObjectType;
    ObjectId = src.ObjectId;
    ArrayId = src.ArrayId;
    }
61
62
63
64
65
66
67
68
  vtkExodusIICacheKey& operator = ( const vtkExodusIICacheKey& src )
    {
    Time = src.Time;
    ObjectType = src.ObjectType;
    ObjectId = src.ObjectId;
    ArrayId = src.ArrayId;
    return *this;
    }
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  bool match( const vtkExodusIICacheKey&other, const vtkExodusIICacheKey& pattern ) const
    {
    if ( pattern.Time && this->Time != other.Time )
      return false;
    if ( pattern.ObjectType && this->ObjectType != other.ObjectType )
      return false;
    if ( pattern.ObjectId && this->ObjectId != other.ObjectId )
      return false;
    if ( pattern.ArrayId && this->ArrayId != other.ArrayId )
      return false;
    return true;
    }
  bool operator < ( const vtkExodusIICacheKey& other ) const
    {
    if ( this->Time < other.Time )
      return true;
    else if ( this->Time > other.Time )
      return false;
    if ( this->ObjectType < other.ObjectType )
      return true;
    else if ( this->ObjectType > other.ObjectType )
      return false;
    if ( this->ObjectId < other.ObjectId )
      return true;
    else if ( this->ObjectId > other.ObjectId )
      return false;
    if ( this->ArrayId < other.ArrayId )
      return true;
    return false;
    }
};

class vtkExodusIICacheEntry;
class vtkExodusIICache;
class vtkDataArray;

105
106
107
108
typedef std::map<vtkExodusIICacheKey,vtkExodusIICacheEntry*> vtkExodusIICacheSet;
typedef std::map<vtkExodusIICacheKey,vtkExodusIICacheEntry*>::iterator vtkExodusIICacheRef;
typedef std::list<vtkExodusIICacheRef> vtkExodusIICacheLRU;
typedef std::list<vtkExodusIICacheRef>::iterator vtkExodusIICacheLRURef;
109

110
class VTKIOEXODUS_EXPORT vtkExodusIICacheEntry
111
112
113
114
115
116
117
118
119
120
121
122
{
public:
  vtkExodusIICacheEntry();
  vtkExodusIICacheEntry( vtkDataArray* arr );
  vtkExodusIICacheEntry( const vtkExodusIICacheEntry& other );

  ~vtkExodusIICacheEntry();

  vtkDataArray* GetValue() { return this->Value; }

protected:
  vtkDataArray* Value;
123
  vtkExodusIICacheLRURef LRUEntry;
124
125
126
127
128

  friend class vtkExodusIICache;
};
//ETX

129
class VTKIOEXODUS_EXPORT vtkExodusIICache : public vtkObject
130
131
132
{
public:
  static vtkExodusIICache* New();
133
  vtkTypeMacro(vtkExodusIICache,vtkObject);
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
  void PrintSelf( ostream& os, vtkIndent indent );

  /// Empty the cache
  void Clear();

  /// Set the maximum allowable cache size. This will remove cache entries if the capacity is reduced below the current size.
  void SetCacheCapacity( double sizeInMiB );

  /** See how much cache space is left.
    * This is the difference between the capacity and the size of the cache.
    * The result is in MiB.
    */
  double GetSpaceLeft()
    { return this->Capacity - this->Size; }

  /** Remove cache entries until the size of the cache is at or below the given size.
    * Returns a nonzero value if deletions were required.
    */
  int ReduceToSize( double newSize );

  //BTX
  /// Insert an entry into the cache (this can remove other cache entries to make space).
  void Insert( vtkExodusIICacheKey& key, vtkDataArray* value );

  /** Determine whether a cache entry exists. If it does, return it -- otherwise return NULL.
    * If a cache entry exists, it is marked as most recently used.
    */
  vtkDataArray*& Find( vtkExodusIICacheKey );

  /** Invalidate a cache entry (drop it from the cache) if the key exists.
    * This does nothing if the cache entry does not exist.
    * Returns 1 if the cache entry existed prior to this call and 0 otherwise.
    */
  int Invalidate( vtkExodusIICacheKey key );

  /** Invalidate all cache entries matching a specified pattern, dropping all matches from the cache.
    * Any nonzero entry in the \a pattern forces a comparison between the corresponding value of \a key.
    * Any cache entries satisfying all the comparisons will be dropped.
    * If pattern is entirely zero, this will empty the entire cache.
    * This is useful for invalidating all entries of a given object type.
    *
    * Returns the number of cache entries dropped.
    * It is not an error to specify an empty range -- 0 will be returned if one is given.
    */
  int Invalidate( vtkExodusIICacheKey key, vtkExodusIICacheKey pattern );
  //ETX

protected:
  /// Default constructor
  vtkExodusIICache();

  /// Destructor.
  ~vtkExodusIICache();


  /// Avoid (some) FP problems
  void RecomputeSize();

  /// The capacity of the cache (i.e., the maximum size of all arrays it contains) in MiB.
  double Capacity;

  /// The current size of the cache (i.e., the size of the all the arrays it currently contains) in MiB.
  double Size;

198
  //BTX
199
200
201
202
203
204
  /** A least-recently-used (LRU) cache to hold arrays.
    * During RequestData the cache may contain more than its maximum size since
    * the user may request more data than the cache can hold. However, the cache
    * is expunged whenever a new array is loaded. Never count on the cache holding
    * what you request for very long.
    */
205
  vtkExodusIICacheSet Cache;
206
207

  /// The actual LRU list (indices into the cache ordered least to most recently used).
208
  vtkExodusIICacheLRU LRU;
209
  //ETX
210
211
212
213

private:
  vtkExodusIICache( const vtkExodusIICache& ); // Not implemented
  void operator = ( const vtkExodusIICache& ); // Not implemented
214
215
};
#endif // __vtkExodusIICache_h