Beispiel #1
0
 /// <summary>
 /// Creates a view of the messages identified by the matching parameters and asynchronously fills it in.
 /// View mode can be one of three values:
 ///     Fixed - fixed range based on start and end times
 ///     TailCount - sliding dynamic range that includes the tail of the underlying data based on quantity
 ///     TailRange - sliding dynamic range that includes the tail of the underlying data based on function.
 /// </summary>
 /// <typeparam name="T">The type of the message to read.</typeparam>
 /// <param name="streamSource">The stream source indicating which stream to read from.</param>
 /// <param name="viewMode">Mode the view will be created in.</param>
 /// <param name="startTime">Start time of messages to read.</param>
 /// <param name="endTime">End time of messages to read.</param>
 /// <param name="tailCount">Number of messages to included in tail.</param>
 /// <param name="tailRange">Function to determine range included in tail.</param>
 /// <returns>Observable view of data.</returns>
 internal ObservableKeyedCache <DateTime, Message <T> > .ObservableKeyedView ReadStream <T>(
     StreamSource streamSource,
     ObservableKeyedCache <DateTime, Message <T> > .ObservableKeyedView.ViewMode viewMode,
     DateTime startTime,
     DateTime endTime,
     uint tailCount,
     Func <DateTime, DateTime> tailRange)
 {
     return(this.GetOrCreateStreamCacheByStreamSource <T>(streamSource, streamSource.StreamAdapter).ReadStream <T>(viewMode, startTime, endTime, tailCount, tailRange));
 }
Beispiel #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="StreamDataProvider{T}"/> class.
        /// </summary>
        /// <param name="streamSource">The stream source.</param>
        public StreamDataProvider(StreamSource streamSource)
        {
            this.Allocator   = streamSource.Allocator != null ? () => streamSource.Allocator() : null;
            this.Deallocator = streamSource.Deallocator != null ? t => streamSource.Deallocator(t) : null;

            this.StreamName = streamSource.StreamName;

            this.ReadRequestsInternal = new List <ReadRequest>();
            this.ReadRequests         = new ReadOnlyCollection <ReadRequest>(this.ReadRequestsInternal);
        }
Beispiel #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="StreamIntervalProvider{T}"/> class.
        /// </summary>
        /// <param name="streamSource">The stream source.</param>
        public StreamIntervalProvider(StreamSource streamSource)
            : base(streamSource)
        {
            this.StreamAdapter = streamSource.StreamAdapter;

            var itemComparer = Comparer <Message <T> > .Create((m1, m2) => m1.OriginatingTime.CompareTo(m2.OriginatingTime));

            this.data = new ObservableKeyedCache <DateTime, Message <T> >(null, itemComparer, m => m.OriginatingTime);
            this.data.CollectionChanged += this.OnCollectionChanged;
            this.dataBuffer              = new List <Message <T> >(1000);
        }
Beispiel #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="StreamSummaryManager"/> class.
        /// </summary>
        /// <param name="streamSource">A stream source that specifies the store and stream that will be summarized.</param>
        public StreamSummaryManager(StreamSource streamSource)
        {
            if (streamSource == null)
            {
                throw new ArgumentNullException(nameof(streamSource));
            }

            this.streamSource  = streamSource;
            this.summaryCaches = new Dictionary <TimeSpan, IStreamSummary>();
            this.consumers     = new List <Guid>();
        }
Beispiel #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="StreamValueProvider{T}"/> class.
        /// </summary>
        /// <param name="streamSource">The stream source.</param>
        public StreamValueProvider(StreamSource streamSource)
            : base(streamSource)
        {
            this.indexView  = null;
            this.publishers = new Dictionary <RelativeTimeInterval, List <IStreamValuePublisher <TSource> > >();

            var indexComparer = Comparer <MessageIndex <TSource> > .Create((i1, i2) => i1.OriginatingTime.CompareTo(i2.OriginatingTime));

            this.index       = new ObservableKeyedCache <DateTime, MessageIndex <TSource> >(null, indexComparer, ie => ie.OriginatingTime);
            this.indexBuffer = new List <MessageIndex <TSource> >(1000);
        }
Beispiel #6
0
        /// <summary>
        /// Gets or creates a stream value provider for a specified stream source.
        /// </summary>
        /// <typeparam name="T">The type of messages in the stream.</typeparam>
        /// <param name="streamSource">The stream source.</param>
        /// <returns>The stream value provider.</returns>
        internal IStreamValueProvider GetOrCreateStreamValueProvider <T>(StreamSource streamSource)
        {
            var streamValueProvider = this.GetStreamValueProviderOrDefault(streamSource.StreamName);

            if (streamValueProvider == null)
            {
                streamValueProvider = new StreamValueProvider <T>(streamSource);
                (streamValueProvider as StreamDataProvider <T>).StreamReadError += this.OnStreamReadError;
                lock (this.streamDataProviders)
                {
                    this.streamDataProviders.Add(streamValueProvider);
                }
            }

            return(streamValueProvider);
        }
Beispiel #7
0
        /// <summary>
        /// Gets or creates a stream interval provider for a specified stream source.
        /// </summary>
        /// <typeparam name="T">The type of messages in the stream.</typeparam>
        /// <param name="streamSource">The stream source.</param>
        /// <returns>The stream interval provider.</returns>
        internal IStreamIntervalProvider GetOrCreateStreamIntervalProvider <T>(StreamSource streamSource)
        {
            var streamIntervalProvider = this.GetStreamIntervalProviderOrDefault(streamSource.StreamName, streamSource.StreamAdapter);

            if (streamIntervalProvider == null)
            {
                streamIntervalProvider = new StreamIntervalProvider <T>(streamSource);
                streamIntervalProvider.NoRemainingSubscribers += this.StreamDataProvider_NoRemainingSubscribers;
                (streamIntervalProvider as StreamDataProvider <T>).StreamReadError += this.OnStreamReadError;
                lock (this.streamDataProviders)
                {
                    this.streamDataProviders.Add(streamIntervalProvider);
                }
            }

            return(streamIntervalProvider);
        }
Beispiel #8
0
        private IStreamSummary GetOrCreateStreamSummary <T>(StreamSource streamSource, TimeSpan interval)
        {
            // Get the summary cache if it exists.
            IStreamSummary summaryCache = this.GetStreamSummaryOrDefault(interval);

            // A summary cache with the required interval does not exist, so create it now.
            if (summaryCache == null)
            {
                summaryCache = typeof(StreamSummary <,>)
                               .MakeGenericType(streamSource.Summarizer.SourceType, streamSource.Summarizer.DestinationType)
                               .GetConstructor(new Type[] { typeof(StreamSource), typeof(TimeSpan), typeof(uint) })
                               .Invoke(new object[] { streamSource, interval, DefaultCacheCapacity }) as IStreamSummary;
                this.summaryCaches[interval] = summaryCache ?? throw new InvalidOperationException("Unable to create instance of summary cache");
            }

            return(summaryCache);
        }
Beispiel #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="StreamSummary{TSource, TDestination}"/> class.
        /// </summary>
        /// <param name="streamSource">Stream source indicating which stream to summarize.</param>
        /// <param name="interval">The time interval over which summary <see cref="IntervalData"/> values are calculated.</param>
        /// <param name="maxCacheSize">The maximum amount of data to cache before purging older summarized data.</param>
        public StreamSummary(StreamSource streamSource, TimeSpan interval, uint maxCacheSize)
        {
            this.streamSource = streamSource;
            this.interval     = interval;
            this.maxCacheSize = maxCacheSize;

            this.summaryDataBuffer = new List <List <IntervalData <TDestination> > >();

            this.keySelector = s => Summarizer <TSource, TDestination> .GetIntervalStartTime(s.OriginatingTime, interval);

            this.itemComparer = Comparer <IntervalData <TDestination> > .Create((r1, r2) => this.keySelector(r1).CompareTo(this.keySelector(r2)));

            this.summaryCache = new ObservableKeyedCache <DateTime, IntervalData <TDestination> >(null, this.itemComparer, this.keySelector);

            this.activeStreamViews  = new Dictionary <Tuple <DateTime, DateTime, uint, Func <DateTime, DateTime> >, ObservableKeyedCache <DateTime, Message <TSource> > .ObservableKeyedView>();
            this.cachedSummaryViews = new Dictionary <Tuple <DateTime, DateTime, uint, Func <DateTime, DateTime> >, ObservableKeyedCache <DateTime, IntervalData <TDestination> > .ObservableKeyedView>();

            // Cache the summarizer (cast to the correct type) to call its methods later on without dynamic binding
            this.summarizer = this.streamSource.Summarizer as ISummarizer <TSource, TDestination>;
        }
Beispiel #10
0
        /// <summary>
        /// Gets a view over the specified time range of the cached summary data.
        /// </summary>
        /// <typeparam name="T">The summary data type.</typeparam>
        /// <param name="streamSource">The stream source indicating which stream to read from.</param>
        /// <param name="viewMode">The view mode, which may be either fixed or live data.</param>
        /// <param name="startTime">The start time of the view range.</param>
        /// <param name="endTime">The end time of the view range.</param>
        /// <param name="interval">The time interval each summary value should cover.</param>
        /// <param name="tailCount">Not yet supported and should be set to zero.</param>
        /// <param name="tailRange">Tail duration function. Computes the view range start time given an end time. Applies to live view mode only.</param>
        /// <returns>A view over the cached summary data that covers the specified time range.</returns>
        public ObservableKeyedCache <DateTime, IntervalData <T> > .ObservableKeyedView ReadSummary <T>(
            StreamSource streamSource,
            ObservableKeyedCache <DateTime, IntervalData <T> > .ObservableKeyedView.ViewMode viewMode,
            DateTime startTime,
            DateTime endTime,
            TimeSpan interval,
            uint tailCount,
            Func <DateTime, DateTime> tailRange)
        {
            if (startTime > DateTime.MinValue)
            {
                // Extend the start time to include the preceding data point to facilitate continuous plots.
                startTime = this.FindPreviousDataPoint <T>(startTime, interval);
            }

            if (endTime < DateTime.MaxValue)
            {
                // Extend the start time to include the next data point to facilitate continuous plots.
                endTime = this.FindNextDataPoint <T>(endTime, interval);
            }

            return(this.GetOrCreateSummaryCache(streamSource, interval).ReadSummary <T>(viewMode, startTime, endTime, tailCount, tailRange));
        }
Beispiel #11
0
 /// <summary>
 /// Performs a series of updates to the messages in a stream.
 /// </summary>
 /// <typeparam name="T">The type of the messages in the stream.</typeparam>
 /// <param name="streamSource">The stream source indicating which stream to read from.</param>
 /// <param name="updates">A collection of updates to perform.</param>
 internal void UpdateStream <T>(StreamSource streamSource, IEnumerable <StreamUpdate <T> > updates) =>
 this.GetStreamIntervalProviderOrDefault(streamSource.StreamName, streamSource.StreamAdapter)
 .UpdateStream <T>(updates);
Beispiel #12
0
 /// <summary>
 /// Gets the time of the nearest message to a specified time, on a specified stream.
 /// </summary>
 /// <param name="streamSource">The stream source specifying the stream of interest.</param>
 /// <param name="time">The time to find the nearest message to.</param>
 /// <param name="nearestMessageType">The type of nearest message to find.</param>
 /// <returns>The time of the nearest message, if one is found or null otherwise.</returns>
 internal DateTime?GetTimeOfNearestMessage(StreamSource streamSource, DateTime time, NearestMessageType nearestMessageType) =>
 this.GetStreamProviderOrDefault(streamSource.StreamName)
 .GetTimeOfNearestMessage(time, nearestMessageType);
Beispiel #13
0
 /// <summary>
 /// Performs a series of updates to the messages in a stream.
 /// </summary>
 /// <typeparam name="T">The type of the messages in the stream.</typeparam>
 /// <param name="streamSource">The stream source indicating which stream to read from.</param>
 /// <param name="updates">A collection of updates to perform.</param>
 internal void UpdateStream <T>(StreamSource streamSource, IEnumerable <StreamUpdate <T> > updates)
 {
     this.GetExistingStreamCache(streamSource, streamSource.StreamAdapter).UpdateStream <T>(updates);
 }
Beispiel #14
0
 /// <summary>
 /// Gets the supplemental metadata for a stream.
 /// </summary>
 /// <typeparam name="TSupplementalMetadata">The type of the supplemental metadata.</typeparam>
 /// <param name="streamSource">The stream source indicating which stream to read from.</param>
 /// <returns>The supplemental metadata for the stream.</returns>
 internal TSupplementalMetadata GetSupplementalMetadata <TSupplementalMetadata>(StreamSource streamSource)
 {
     return(this.streamReader.GetSupplementalMetadata <TSupplementalMetadata>(streamSource.StreamName));
 }