Пример #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DataStoreReader"/> class.
 /// </summary>
 /// <param name="storeName">Store name to read.</param>
 /// <param name="storePath">Store path to read.</param>
 /// <param name="simpleReaderType">Simple reader type.</param>
 public DataStoreReader(string storeName, string storePath, Type simpleReaderType)
 {
     this.simpleReader = (ISimpleReader)simpleReaderType.GetConstructor(new Type[] { }).Invoke(new object[] { });
     this.simpleReader.OpenStore(storeName, storePath);
     this.executionContexts = new List <ExecutionContext>();
     this.streamReaders     = new List <IStreamReader>();
 }
Пример #2
0
 /// <summary>
 /// Reads a single message from a stream identified by a stream binding and an index entry.
 /// </summary>
 /// <typeparam name="T">The type of the message to read.</typeparam>
 /// <param name="streamBinding">The stream binding inidicating which stream to read from.</param>
 /// <param name="indexEntry">The index entry indicating which message to read.</param>
 /// <returns>The message that was read.</returns>
 public T Read <T>(StreamBinding streamBinding, IndexEntry indexEntry)
 {
     using (ISimpleReader reader = this.simpleReader.OpenNew())
     {
         return(this.GetStreamReader <T>(streamBinding, true).Read <T>(reader, indexEntry));
     }
 }
        /// <summary>
        /// Reads instant data from the stream at the given cursor time and pushes it to all registered adapting data providers.
        /// </summary>
        /// <param name="reader">The simple reader that will read the data.</param>
        /// <param name="cursorTime">The cursor time at which to read the data.</param>
        /// <param name="indexCache">The stream reader's index cache.</param>
        public void ReadInstantData(ISimpleReader reader, DateTime cursorTime, ObservableKeyedCache <DateTime, IndexEntry> indexCache)
        {
            // Get the index of the data, given the cursor time
            int index = IndexHelper.GetIndexForTime(cursorTime, indexCache?.Count ?? 0, (idx) => indexCache[idx].OriginatingTime, this.CursorEpsilon);

            T          data       = default;
            IndexEntry indexEntry = default;

            if (index >= 0)
            {
                // Get the index entry
                indexEntry = indexCache[index];

                // Read the data
                data = reader.Read <T>(indexEntry);
            }

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

            // Release the reference to the local copy of the data if it's shared
            if (this.isSharedType && data != null)
            {
                (data as IDisposable).Dispose();
            }
        }
Пример #4
0
        /// <inheritdoc />
        public void Dispose()
        {
            // cancel all stream readers
            this.streamReaders?.ForEach(sr => sr.Cancel());

            // dispose and clean up execution contexts
            this.executionContexts.ForEach(ec =>
            {
                try
                {
                    ec.ReadAllTokenSource.Cancel();
                    ec.ReadAllTask.Wait();
                }
                catch (AggregateException)
                {
                }

                ec.Reader.Dispose();
                ec.ReadAllTask.Dispose();
                ec.ReadAllTokenSource.Dispose();
            });

            this.executionContexts.Clear();
            this.executionContexts = null;

            // dispose all stream readers
            this.streamReaders?.ForEach(sr => sr.Dispose());
            this.streamReaders?.Clear();
            this.streamReaders = null;

            // dispose of simple reader
            this.simpleReader?.Dispose();
            this.simpleReader = null;
        }
Пример #5
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="reader">The simple reader that will read the data.</param>
        /// <param name="cursorTime">The cursor time at which to read the data.</param>
        /// <param name="indexCache">The stream reader's index cache.</param>
        public void ReadInstantData(ISimpleReader reader, DateTime cursorTime, ObservableKeyedCache <DateTime, IndexEntry> indexCache)
        {
            // Get the index of the data, given the cursor time
            int index = IndexHelper.GetIndexForTime(cursorTime, indexCache?.Count ?? 0, (idx) => indexCache[idx].OriginatingTime, this.CursorEpsilon);

            T          data       = default;
            IndexEntry indexEntry = default;

            if (index >= 0)
            {
                // Get the index entry
                indexEntry = indexCache[index];

                // Read the data
                data = reader.Read <T>(indexEntry);
            }

            // Notify all registered adapting data providers of the new data.  If the data is Shared<T> then perform a deep clone
            // (which resolves to an AddRef() for this type) for each provider we call.  The providers are responsible for releasing
            // their reference to the data once they're done with it.
            if (this.isSharedType && data != null)
            {
                Parallel.ForEach(this.dataProviders.ToList(), provider => provider.PushData(data.DeepClone <T>(), indexEntry));

                // Release the reference to the local copy of the data
                (data as IDisposable).Dispose();
            }
            else
            {
                Parallel.ForEach(this.dataProviders.ToList(), provider => provider.PushData(data, indexEntry));
            }
        }
Пример #6
0
 /// <inheritdoc />
 public void ReadInstantData(ISimpleReader reader, DateTime cursorTime)
 {
     // Forward the call to all the instant stream readers
     foreach (EpsilonInstantStreamReader <T> instantStreamReader in this.GetInstantStreamReaderList())
     {
         instantStreamReader.ReadInstantData(reader, cursorTime, this.index);
     }
 }
Пример #7
0
 /// <summary>
 /// Called to ask the reader to read the data for all instant streams.
 /// </summary>
 /// <param name="cursorTime">The time of the visualization container's cursor.</param>
 internal void ReadInstantData(DateTime cursorTime)
 {
     using (ISimpleReader reader = this.simpleReader.OpenNew())
     {
         foreach (IStreamReader streamReader in this.streamReaders.ToList())
         {
             if (streamReader.HasInstantStreamReaders)
             {
                 streamReader.ReadInstantData(reader, cursorTime);
             }
         }
     }
 }
Пример #8
0
 /// <inheritdoc />
 public TDest Read <TDest>(ISimpleReader reader, IndexEntry indexEntry)
 {
     if (this.StreamBinding.StreamAdapter == null)
     {
         return(reader.Read <TDest>(indexEntry));
     }
     else
     {
         var genericRead = typeof(ISimpleReader)
                           .GetMethod("Read", new Type[] { typeof(IndexEntry) })
                           .MakeGenericMethod(this.StreamBinding.StreamAdapter.SourceType);
         var src       = genericRead.Invoke(reader, new object[] { indexEntry });
         var adaptData = typeof(StreamAdapter <,>)
                         .MakeGenericType(this.StreamBinding.StreamAdapter.SourceType, this.StreamBinding.StreamAdapter.DestinationType)
                         .GetMethod("AdaptData");
         return((TDest)adaptData.Invoke(this.StreamBinding.StreamAdapter, new object[] { src }));
     }
 }
Пример #9
0
        /// <inheritdoc />
        public void OpenStream(ISimpleReader reader, bool readIndicesOnly)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            if (readIndicesOnly)
            {
                if (this.streamAdapter == null)
                {
                    reader.OpenStreamIndex <T>(this.StreamName, this.OnReceiveIndex);
                }
                else
                {
                    var genericOpenStreamIndex = typeof(ISimpleReader)
                                                 .GetMethod("OpenStreamIndex", new Type[] { typeof(string), typeof(Action <IndexEntry, Envelope>) })
                                                 .MakeGenericMethod(this.streamAdapter.SourceType);
                    var receiver = new Action <IndexEntry, Envelope>(this.OnReceiveIndex);
                    genericOpenStreamIndex.Invoke(reader, new object[] { this.StreamName, receiver });
                }
            }
            else
            {
                if (this.streamAdapter == null)
                {
                    reader.OpenStream <T>(this.StreamName, this.OnReceiveData, this.Allocator);
                }
                else
                {
                    dynamic dynStreamAdapter   = this.streamAdapter;
                    dynamic dynAdaptedReceiver = dynStreamAdapter.AdaptReceiver(new Action <T, Envelope>(this.OnReceiveData));
                    reader.OpenStream(this.StreamName, dynAdaptedReceiver, dynStreamAdapter.Allocator);
                }
            }
        }