Click or drag to resize
OSIsoft, LLC

AFDataCache Class

An AFDataCache manages a collection of AFAttributes via cache enabled AFData objects and will can automatically monitor for new data changes.

Inheritance Hierarchy
SystemObject
  OSIsoft.AF.DataAFDataCache

Namespace:  OSIsoft.AF.Data
Assembly:  OSIsoft.AFSDK (in OSIsoft.AFSDK.dll) Version: 2.10.6.195
Syntax
public sealed class AFDataCache : IDisposable, 
	IAFDataProvider

The AFDataCache type exposes the following members.

Constructors
  NameDescription
Public methodAFDataCache
Create new instance of AFDataCache.
Public methodAFDataCache(Int32)
Create new instance of AFDataCache with a initial capacity set.
Top
Properties
  NameDescription
Public propertyAttributes
The list of AFAttribute items being cached.c
Public propertyCacheHitCount
Returns the total number of data calls that retrieved data from the cache since the counter was reset.
Public propertyCacheTimeSpan
The minimum amount of time series data to be kept for each AFAttribute in the cache, as measured by time span.
Public propertyDataPipeStatistics
Contains statistics for the most recent signup or event scan for attributes updated by data pipe.
Public propertyEventHorizonMode
EventHorizonMode specifies what events are returned by the datapipe at the GetUpdateEvent call based on the timestamp of the events.
Public propertyEventHorizonOffset
EventHorizonOffset allows the pipe to return events in the future. The pipe would fetch events with timestamps up to current time + EventHorizonOffset when calling the GetUpdateEvents/GetObserverEvents methods
Public propertyEventsCached
The total number of events currently in the cache.
Public propertyEventsProcessed
The total number of events that have passed through the cache since the counter was reset.
Public propertyIsSuspendedSignupEnabled
If IsSuspendedSignupEnabled is set, the data pipe will suspend signups that are currently invalid but might become valid with changes outside of AF.
Public propertyMaxCacheEventsPerAttribute
The maximum number of cache events to be kept for each AFAttribute in the cache.
Public propertyMinCacheEventsPerAttribute
The minimum number of cache events to be kept for each AFAttribute in the cache.
Public propertyMissedHitCount
The total number of data calls that did not get data from the cache.
Public propertyPIServers
Get the list of PIServer that could provide data update for the attributes in the cache via DataPipe option.
Top
Methods
  NameDescription
Public methodAdd
Adds a list of AFAttribute objects to be managed by AFDataCache. The AFAttributes are reference counted. Adding AFAttribute that is already in the AFDataCache will increment the reference count and not generate error. Adding the same AFAttribute multiple times will require the same number of Remove call to actually remove the AFAttribute from the AFDataCache.
Public methodDispose
Release all the resources associated with this AFDataCache, including the AFDataPipe used to populate the cached data.
Public methodEquals
Determines whether the specified object is equal to the current object.
(Inherited from Object.)
Public methodGetDataPipeItemsByPIServer
Get the list of the AFAttribute objects managed by AFDataCache with DataPipe that get data from the passed PIServer.
Public methodGetHashCode
Serves as the default hash function.
(Inherited from Object.)
Public methodGetItemUpdateOption
Returns the AFDataCacheUpdateOption for an AFAttribute managed by this AFDataCache
Public methodGetRelatedAttributes
For each AFChangeInfo, finds the subscribed AFAttributes that might be impacted by the change.
Public methodGetType
Gets the Type of the current instance.
(Inherited from Object.)
Public methodObservePendingChanges
Observes a set of changes from the server and prepares to update the AFDataPipe to reflect them.
Public methodProcessAppliedChanges
Updates the AFDataPipe to reflect previously observed changes.
Public methodRemove
Remove a list of AFAttribute objects from the data cache.
Public methodResetCounters
Reset AFDataCache statistic counters.
Public methodSubscribe
Register an IObserver to receive AFDataPipeEvents that are a result of the internal AFDataPipe used within the data cache for auto-monitored attributes.
Public methodToString
Returns a string that represents the current object.
(Inherited from Object.)
Public methodTrimData(AFAttribute, AFTime)
Trims any cached data for the AFAttribute at or before the specified AFTime.
Public methodTrimData(AFAttribute, AFTime, Int32)
Trims cached data for the AFAttribute while maintaining coverage for events from a specified time.
Public methodTryGetItem
Returns the cache enabled AFData object for a given AFAttribute.
Public methodUpdateData
Update the time series cache for the attributes managed by this AFDataCache.
Public methodUpdateData(Boolean)
Update the time series cache for the attributes managed by this AFDataCache.
Public methodUpdateData(AFTime)
Update the time series cache for the attributes managed by this AFDataCache.
Public methodUpdateData(AFTime, Boolean)
Update the time series cache for the attributes managed by this AFDataCache.
Public methodWriteToCache(AFAttribute, IListAFValue)
Initialize the data cache of the AFAttribute with passed values. The AFAttribute must already be added to the AFDataCache with Manual or ManualRange.
Public methodWriteToCache(AFValue, AFUpdateOption)
Writes value to the data cache. The AFAttribute property of the passed AFValue is the key to lookup the data cache. This AFAttribute must already be added to the AFDataCache with Manual or ManualRange.
Top
Remarks

An AFDataCache manages a collection of AFAttributes via cache enabled AFData objects. To enable run time event caching for a list of AFAttributes, call the Add method and passed the list of AFAttributes. AFDataCache will generate and return the corresponding list of cached enabled AFData. Be default, AFDataCache uses AFDataPipe to populate the run time events in the cache. As a result, AFAttributes monitored by the AFDataCache must support AFDataPipe. The use of AFDataPipe to populate the cache can be turned off at the time of adding the AFAttribute using Manual or ManualRange. See the Add(IListAFAttribute, AFDataCacheUpdateOption) method for details.

AFDataCache will trim the cached events based on both event count and timespan. Trimming is done when the application calls the UpdateData Overload method to update the cache. Just like AFDataPipe, AFDataCache does not poll the data automatically in the background. This allows an application to have complete control over when and which thread will be used, making synchronization across threads simpler.

Single event data access queries made with the cache enabled AFData are much faster. For data access queries not supporting data cache or if the requested range exceeds the amount on data in cache, the data cache will make the normal data access query so no functionality is lost. Hence, AFDataCache is ideal for high performance applications working with streaming data while maintaining the functionality of the Rich Data Access through AFData.

Note that only data access queries made against the cached enabled AFData objects get the benefit of the cache. The cached enabled AFData objects are returned when application calls the Add(IListAFAttribute, AFDataCacheUpdateOption) or TryGetItem(AFAttribute, AFData)method of the AFDataCache. The AFData object obtained from Data is not cached enabled.

For data sources such as the PI Data Archive, where data could be compressed, it is possible for the AFDataCache to have higher resolution data (more events within the same time range) than a direct data access call to the source.

Examples
// This example demonstrates how to create an AFDataPipe
// and how to use it to get new events for an attribute

// Get the Database
PISystems myPISystems = new PISystems();
PISystem myPISystem = myPISystems.DefaultPISystem;
AFDatabase myDB = myPISystem.Databases.DefaultDatabase;
AFValue inputValue1;
AFValue inputValue2;
long numEventsCached0 = 0;
long numEventsProcessed0 = 0;
long numEventsCached1 = 0;
long numEventsProcessed1 = 0;
long numEventsCached2 = 0;
long numEventsProcessed2 = 0;
long numHitCount = 0;
long numMissedHitCount = 0;

// Create an Element with some attributes
AFElement myElement = myDB.Elements.Add("MyElement*");
AFAttribute myAttribute1 = myElement.Attributes.Add("MyAttribute1");
AFAttribute myAttribute2 = myElement.Attributes.Add("MyAttribute2");

// Create PIPoints to Update
PIServer piServer = PIServers.GetPIServers().DefaultPIServer;
PIPoint point;
if (!PIPoint.TryFindPIPoint(piServer, "testfloat1", out point))
{
    point = piServer.CreatePIPoint("testfloat1", null);
}

if (!PIPoint.TryFindPIPoint(piServer, "testfloat2", out point))
{
    point = piServer.CreatePIPoint("testfloat2", null);
}

myAttribute1.DefaultUOM = myPISystem.UOMDatabase.UOMs["kelvin"];
myAttribute1.DataReferencePlugIn = AFDataReference.GetPIPointDataReference(myPISystem);
myAttribute1.ConfigString = @"\\%Server%\testfloat1;ReadOnly=false";

myAttribute2.DefaultUOM = myPISystem.UOMDatabase.UOMs["kelvin"];
myAttribute2.DataReferencePlugIn = AFDataReference.GetPIPointDataReference(myPISystem);
myAttribute2.ConfigString = @"\\%Server%\testfloat2;ReadOnly=false";

// Send some values to tags to initialize them
for (int i = 1; i <= 2; i++)
{
    AFTime tmptime = new AFTime("*");
    inputValue1 = new AFValue(5 * i, tmptime);
    inputValue2 = new AFValue(10 * i, tmptime);
    myAttribute1.SetValue(inputValue1);
    myAttribute2.SetValue(inputValue2);
    Thread.Sleep(1000);                    
}

// Sleep for a minute
Thread.Sleep(60000);

// Create data cache object and sign up the attributes for the cache
AFDataCache myAFDataCache = new AFDataCache(1000);
AFKeyedResults<AFAttribute, AFData> addResult = myAFDataCache.Add(myElement.Attributes);

numEventsCached0 = myAFDataCache.EventsCached;
numEventsProcessed0 = myAFDataCache.EventsProcessed;

// Cache only last minute worth of data
myAFDataCache.CacheTimeSpan = new TimeSpan(0, 1, 0);

// Send values to tags
for (int i = 1; i <= 10; i++)
{
    AFTime tmptime = new AFTime("*");
    inputValue1 = new AFValue(5 * i, tmptime);
    inputValue2 = new AFValue(10 * i, tmptime);
    myAttribute1.SetValue(inputValue1);
    myAttribute2.SetValue(inputValue2);
    Thread.Sleep(1000);                    
}

// Get data for cache
// Sleep a little to make sure all events get through update manager
Thread.Sleep(100);
myAFDataCache.UpdateData();

numEventsCached1 = myAFDataCache.EventsCached;
numEventsProcessed1 = myAFDataCache.EventsProcessed;

// Sleep for a minute
Thread.Sleep(60000);

// Send values to tags after a minute so that these events replace the old ones
for (int i = 1; i <= 10; i++)
{
    AFTime tmptime = new AFTime("*");
    inputValue1 = new AFValue(5 * i, tmptime);
    inputValue2 = new AFValue(10 * i, tmptime);
    myAttribute1.SetValue(inputValue1);
    myAttribute2.SetValue(inputValue2);
    Thread.Sleep(1000);
}

// Get data for cache
Thread.Sleep(100);
myAFDataCache.UpdateData();

numEventsCached2 = myAFDataCache.EventsCached;
numEventsProcessed2 = myAFDataCache.EventsProcessed;

int numInterpolatedCalls = 100;

if (!addResult.HasErrors)
{
    AFData tmpData1 = myAttribute1.Data;
    AFTime tmpTime = new AFTime("*-30s");

    // Call made to regular Data object so therefore cache not used
    for (int i = 0; i < numInterpolatedCalls; i++)
        tmpData1.InterpolatedValue(tmpTime, null);

    AFData tmpData2 = addResult[myAttribute1];

    // Call made to cache Data object so cache is used
    for (int i = 0; i < numInterpolatedCalls; i++)
        tmpData2.InterpolatedValue(tmpTime, null);

    numHitCount = myAFDataCache.CacheHitCount;

    // Call made to a time period not covered by the cache and therefore missed hit count should increment by numInterpolatedCalls
    AFTime tmpTimediff = new AFTime(addResult[myAttribute1].CacheStartTime.UtcSeconds - 2);
    for (int i = 0; i < numInterpolatedCalls; i++)
        tmpData2.InterpolatedValue(tmpTimediff , null);

    numMissedHitCount = myAFDataCache.MissedHitCount;
}
Version Information

AFSDK

Supported in: 2.10.5, 2.10, 2.9.5, 2.9, 2.8.5, 2.8, 2.7.5, 2.7, 2.6
See Also
Enabling Operational Intelligence