Example #1
0
        /// <summary>
        /// Reads instant data from the stream at the given cursor time and pushes it to all registered adapting data providers.
        /// </summary>
        /// <param name="streamReader">The stream reader that will read the data.</param>
        /// <param name="cursorTime">The cursor time at which to read the data.</param>
        /// <param name="streamCache">The stream reader's cache.</param>
        public void ReadInstantData(IStreamReader streamReader, DateTime cursorTime, ObservableKeyedCache <DateTime, StreamCacheEntry> streamCache)
        {
            // Get the index of the data, given the cursor time
            int index = IndexHelper.GetIndexForTime(cursorTime, streamCache?.Count ?? 0, (idx) => streamCache[idx].OriginatingTime, this.CursorEpsilon);

            T data = default;
            StreamCacheEntry cacheEntry = default;

            if (index >= 0)
            {
                // Get the index entry
                cacheEntry = streamCache[index];

                // Read the data
                data = cacheEntry.Read <T>(streamReader);
            }

            // Notify each adapting data provider of the new data
            foreach (IAdaptingInstantDataProvider <T> adaptingInstantDataProvider in this.dataProviders.ToList())
            {
                adaptingInstantDataProvider.PushData(data, cacheEntry);
            }

            // Release the reference to the local copy of the data if it's shared
            if (this.isSharedType && data != null)
            {
                (data as IDisposable).Dispose();
            }
        }
        /// <inheritdoc/>
        public void PushData(TSource sourceData, StreamCacheEntry streamCacheEntry)
        {
            // Adapt the data to the type required by target.
            TDestination adaptedData = this.streamAdapter.AdaptData(sourceData);

            // Call each of the targets with the adapted data, cloning it if it's shared.
            foreach (InstantDataTarget instantDataTarget in this.targets.Values.ToList())
            {
                instantDataTarget.Callback.Invoke(adaptedData, streamCacheEntry);
            }

            // We're done with the adapted data, so decrement its reference count if it's shared
            if (this.adaptedDataIsSharedType && adaptedData != null)
            {
                (adaptedData as IDisposable).Dispose();
            }
        }
        /// <summary>
        /// Reads instant data from the stream at the given cursor time and pushes it to all registered adapting data providers.
        /// </summary>
        /// <param name="streamReader">The stream reader that will read the data.</param>
        /// <param name="cursorTime">The cursor time at which to read the data.</param>
        /// <param name="streamCache">The stream reader's cache.</param>
        public void ReadInstantData(IStreamReader streamReader, DateTime cursorTime, ObservableKeyedCache <DateTime, StreamCacheEntry> streamCache)
        {
            // Get the index of the data, given the cursor time
            int index = IndexHelper.GetIndexForTime(cursorTime, streamCache?.Count ?? 0, (idx) => streamCache[idx].OriginatingTime, this.CursorEpsilon);

            T data = default;
            StreamCacheEntry cacheEntry = default;

            if (index >= 0)
            {
                // Get the index entry
                cacheEntry = streamCache[index];

                // Read the data
                data = cacheEntry.Read <T>(streamReader);
            }
            else
            {
                // cache miss, attempt to seek directly while the cache is presumably being populated
                streamReader.Seek(cursorTime + this.CursorEpsilon, true);
                streamReader.OpenStream <T>(this.streamName, (m, e) =>
                {
                    cacheEntry = new StreamCacheEntry(null, e.CreationTime, e.OriginatingTime);
                    data       = m;
                });
                streamReader.MoveNext(out var envelope);
            }

            // Notify each adapting data provider of the new data
            foreach (IAdaptingInstantDataProvider <T> adaptingInstantDataProvider in this.dataProviders.ToList())
            {
                adaptingInstantDataProvider.PushData(data, cacheEntry);
            }

            // Release the reference to the local copy of the data if it's shared
            if (this.isSharedType && data != null)
            {
                (data as IDisposable).Dispose();
            }
        }