You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
6.8 KiB
C++
210 lines
6.8 KiB
C++
#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:
|
|
//
|
|
// 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.
|
|
|
|
#include "vtkIOExodusModule.h" // For export macro
|
|
#include "vtkObject.h"
|
|
|
|
#include <list> // use for LRU ordering
|
|
#include <map> // used for cache storage
|
|
|
|
class VTKIOEXODUS_EXPORT vtkExodusIICacheKey
|
|
{
|
|
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;
|
|
}
|
|
vtkExodusIICacheKey(const vtkExodusIICacheKey& src)
|
|
{
|
|
Time = src.Time;
|
|
ObjectType = src.ObjectType;
|
|
ObjectId = src.ObjectId;
|
|
ArrayId = src.ArrayId;
|
|
}
|
|
vtkExodusIICacheKey& operator=(const vtkExodusIICacheKey& src)
|
|
{
|
|
Time = src.Time;
|
|
ObjectType = src.ObjectType;
|
|
ObjectId = src.ObjectId;
|
|
ArrayId = src.ArrayId;
|
|
return *this;
|
|
}
|
|
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;
|
|
|
|
typedef std::map<vtkExodusIICacheKey, vtkExodusIICacheEntry*> vtkExodusIICacheSet;
|
|
typedef std::map<vtkExodusIICacheKey, vtkExodusIICacheEntry*>::iterator vtkExodusIICacheRef;
|
|
typedef std::list<vtkExodusIICacheRef> vtkExodusIICacheLRU;
|
|
typedef std::list<vtkExodusIICacheRef>::iterator vtkExodusIICacheLRURef;
|
|
|
|
class VTKIOEXODUS_EXPORT vtkExodusIICacheEntry
|
|
{
|
|
public:
|
|
vtkExodusIICacheEntry();
|
|
vtkExodusIICacheEntry(vtkDataArray* arr);
|
|
vtkExodusIICacheEntry(const vtkExodusIICacheEntry& other);
|
|
|
|
~vtkExodusIICacheEntry();
|
|
|
|
vtkDataArray* GetValue() { return this->Value; }
|
|
|
|
protected:
|
|
vtkDataArray* Value;
|
|
vtkExodusIICacheLRURef LRUEntry;
|
|
|
|
friend class vtkExodusIICache;
|
|
};
|
|
|
|
class VTKIOEXODUS_EXPORT vtkExodusIICache : public vtkObject
|
|
{
|
|
public:
|
|
static vtkExodusIICache* New();
|
|
vtkTypeMacro(vtkExodusIICache, vtkObject);
|
|
void PrintSelf(ostream& os, vtkIndent indent) override;
|
|
|
|
/// 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);
|
|
|
|
/// 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 nullptr.
|
|
* If a cache entry exists, it is marked as most recently used.
|
|
*/
|
|
vtkDataArray*& Find(const 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(const 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(const vtkExodusIICacheKey& key, const vtkExodusIICacheKey& pattern);
|
|
|
|
protected:
|
|
/// Default constructor
|
|
vtkExodusIICache();
|
|
|
|
/// Destructor.
|
|
~vtkExodusIICache() override;
|
|
|
|
/// 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;
|
|
|
|
/** 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.
|
|
*/
|
|
vtkExodusIICacheSet Cache;
|
|
|
|
/// The actual LRU list (indices into the cache ordered least to most recently used).
|
|
vtkExodusIICacheLRU LRU;
|
|
|
|
private:
|
|
vtkExodusIICache(const vtkExodusIICache&) = delete;
|
|
void operator=(const vtkExodusIICache&) = delete;
|
|
};
|
|
#endif // vtkExodusIICache_h
|