public SignalIndexCache GetSignalIndexCache()
        {
            global::System.IntPtr cPtr = CommonPINVOKE.SubscriberConnection_GetSignalIndexCache(swigCPtr);
            SignalIndexCache      ret  = (cPtr == global::System.IntPtr.Zero) ? null : new SignalIndexCache(cPtr, true);

            if (CommonPINVOKE.SWIGPendingException.Pending)
            {
                throw CommonPINVOKE.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
 public virtual void SubscriptionUpdated(SignalIndexCache signalIndexCache)
 {
     if (SwigDerivedClassHasMethod("SubscriptionUpdated", swigMethodTypes7))
     {
         CommonPINVOKE.SubscriberInstanceBase_SubscriptionUpdatedSwigExplicitSubscriberInstanceBase(swigCPtr, SignalIndexCache.getCPtr(signalIndexCache));
     }
     else
     {
         CommonPINVOKE.SubscriberInstanceBase_SubscriptionUpdated(swigCPtr, SignalIndexCache.getCPtr(signalIndexCache));
     }
     if (CommonPINVOKE.SWIGPendingException.Pending)
     {
         throw CommonPINVOKE.SWIGPendingException.Retrieve();
     }
 }
Exemple #3
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(SignalIndexCache obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }
Exemple #4
0
        // Retrieves the measurements from the database.
        private void GetDbMeasurements(object state)
        {
            IDbConnection connection = null;

            // Get measurements from the database.
            try
            {
                SignalIndexCache   signalIndexCache = new SignalIndexCache();
                CompactMeasurement measurement;
                long startTime = DateTime.UtcNow.Ticks;

                if (m_cacheFileName != null && File.Exists(m_cacheFileName))
                {
                    OnStatusMessage(MessageLevel.Info, "Loading cached input data...");

                    try
                    {
                        using (FileStream data = File.OpenRead(m_cacheFileName))
                        {
                            byte[] buffer = new byte[4];
                            int    signalIndexCacheImageSize;
                            int    compactMeasurementSize;
                            int    totalMeasurements;

                            // Read the signal index cache image size from the file
                            if (data.Read(buffer, 0, 4) != 4)
                            {
                                throw new EndOfStreamException();
                            }

                            signalIndexCacheImageSize = LittleEndian.ToInt32(buffer, 0);

                            // Resize buffer to accommodate exact signal index cache
                            buffer = new byte[signalIndexCacheImageSize];

                            // Read the signal index cache image from the file
                            if (data.Read(buffer, 0, signalIndexCacheImageSize) != signalIndexCacheImageSize)
                            {
                                throw new EndOfStreamException();
                            }

                            // Deserialize the signal index cache
                            signalIndexCache = Serialization.Deserialize <SignalIndexCache>(buffer, SerializationFormat.Binary);

                            // Read the size of each compact measurement from the file
                            if (data.Read(buffer, 0, 4) != 4)
                            {
                                throw new EndOfStreamException();
                            }

                            compactMeasurementSize = LittleEndian.ToInt32(buffer, 0);

                            // Read the total number of compact measurements from the file
                            if (data.Read(buffer, 0, 4) != 4)
                            {
                                throw new EndOfStreamException();
                            }

                            totalMeasurements = LittleEndian.ToInt32(buffer, 0);

                            // Resize buffer to accommodate compact measurement if needed (not likely)
                            if (buffer.Length < compactMeasurementSize)
                            {
                                buffer = new byte[compactMeasurementSize];
                            }

                            // Read each compact measurement image from the file
                            for (int i = 0; i < totalMeasurements; i++)
                            {
                                if (data.Read(buffer, 0, compactMeasurementSize) != compactMeasurementSize)
                                {
                                    throw new EndOfStreamException();
                                }

                                // Parse compact measurement
                                measurement = new CompactMeasurement(signalIndexCache);
                                measurement.ParseBinaryImage(buffer, 0, compactMeasurementSize);

                                m_dbMeasurements.Add(measurement);

                                if (m_dbMeasurements.Count % 50000 == 0)
                                {
                                    OnStatusMessage(MessageLevel.Info, $"Loaded {m_dbMeasurements.Count:N0} records so far...");
                                }
                            }

                            OnStatusMessage(MessageLevel.Info, $"Completed data load in {((Ticks)(DateTime.UtcNow.Ticks - startTime)).ToElapsedTimeString(2)}");
                        }
                    }
                    catch (Exception ex)
                    {
                        // ReSharper disable once CanBeReplacedWithTryCastAndCheckForNull
                        if (ex is EndOfStreamException)
                        {
                            throw (EndOfStreamException)ex;
                        }

                        throw new EndOfStreamException(ex.Message, ex);
                    }
                }
                else
                {
                    OnStatusMessage(MessageLevel.Info, "Loading database input data...");

                    const string MeasurementTable = "ActiveMeasurements";

                    Dictionary <string, string> dataProviderSettings = m_dataProviderString.ParseKeyValuePairs();
                    Assembly assm           = Assembly.Load(dataProviderSettings["AssemblyName"]);
                    Type     connectionType = assm.GetType(dataProviderSettings["ConnectionType"]);

                    Dictionary <Guid, MeasurementKey> lookupCache = new Dictionary <Guid, MeasurementKey>();
                    IDbCommand     command;
                    IDataReader    dbReader;
                    MeasurementKey key;
                    Guid           id;
                    ushort         index = 0;

                    connection = (IDbConnection)Activator.CreateInstance(connectionType);
                    connection.ConnectionString = m_dbConnectionString;
                    connection.Open();

                    command             = connection.CreateCommand();
                    command.CommandText = $"SELECT * FROM {m_dbTableName}";

                    using (dbReader = command.ExecuteReader())
                    {
                        while (dbReader.Read())
                        {
                            measurement = new CompactMeasurement(signalIndexCache);

                            foreach (string fieldName in m_fieldNames.Keys)
                            {
                                object value        = dbReader[fieldName];
                                string propertyName = m_fieldNames[fieldName];

                                switch (propertyName)
                                {
                                case "Timestamp":
                                    // If the value is a timestamp, use the timestamp format
                                    // specified by the user when reading the timestamp.
                                    if (m_timestampFormat == null)
                                    {
                                        measurement.Timestamp = long.Parse(value.ToNonNullString());
                                    }
                                    else
                                    {
                                        measurement.Timestamp = DateTime.ParseExact(value.ToNonNullString(), m_timestampFormat, CultureInfo.CurrentCulture);
                                    }
                                    break;

                                case "ID":
                                    if (Guid.TryParse(value.ToString(), out id))
                                    {
                                        if (!lookupCache.TryGetValue(id, out key))
                                        {
                                            if (DataSource.Tables.Contains(MeasurementTable))
                                            {
                                                DataRow[] filteredRows = DataSource.Tables[MeasurementTable].Select($"SignalID = '{id}'");

                                                if (filteredRows.Length > 0)
                                                {
                                                    key = MeasurementKey.LookUpOrCreate(id, filteredRows[0]["ID"].ToString());
                                                }
                                            }

                                            if (key != MeasurementKey.Undefined)
                                            {
                                                // Cache measurement key associated with ID
                                                lookupCache[id] = key;

                                                // Assign a runtime index optimization for distinct measurements
                                                signalIndexCache.Reference.TryAdd(index++, key);
                                            }
                                        }

                                        measurement.Metadata = key.Metadata;
                                    }
                                    break;

                                case "Key":
                                    if (MeasurementKey.TryParse(value.ToString(), out key))
                                    {
                                        if (!lookupCache.ContainsKey(key.SignalID))
                                        {
                                            // Cache measurement key associated with ID
                                            lookupCache[key.SignalID] = key;

                                            // Assign a runtime index optimization for distinct measurements
                                            signalIndexCache.Reference.TryAdd(index++, key);
                                        }

                                        measurement.Metadata = key.Metadata;
                                    }
                                    break;

                                case "Value":
                                    measurement.Value = Convert.ToDouble(value);
                                    break;

                                default:
                                    PropertyInfo property = GetAllProperties(typeof(IMeasurement)).FirstOrDefault(propertyInfo => propertyInfo.Name == propertyName);

                                    if (property != null)
                                    {
                                        Type propertyType = property.PropertyType;
                                        Type valueType    = value.GetType();

                                        // ReSharper disable once UseMethodIsInstanceOfType
                                        if (property.PropertyType.IsAssignableFrom(value.GetType()))
                                        {
                                            property.SetValue(measurement, value, null);
                                        }
                                        else if (property.PropertyType == typeof(string))
                                        {
                                            property.SetValue(measurement, value.ToNonNullString(), null);
                                        }
                                        else if (valueType == typeof(string))
                                        {
                                            MethodInfo parseMethod = propertyType.GetMethod("Parse", new[] { typeof(string) });

                                            if (parseMethod != null && parseMethod.IsStatic)
                                            {
                                                property.SetValue(measurement, parseMethod.Invoke(null, new[] { value }), null);
                                            }
                                        }
                                        else
                                        {
                                            string exceptionMessage = $"The type of field {fieldName} could not be converted to the type of property {propertyName}.";
                                            OnProcessException(MessageLevel.Warning, new InvalidCastException(exceptionMessage));
                                        }
                                    }
                                    else
                                    {
                                        string exceptionMessage = $"The type of field {fieldName} could not be converted to the type of property {propertyName} - no property match was found.";
                                        OnProcessException(MessageLevel.Warning, new InvalidCastException(exceptionMessage));
                                    }
                                    break;
                                }

                                m_dbMeasurements.Add(measurement);

                                if (m_dbMeasurements.Count % 50000 == 0)
                                {
                                    OnStatusMessage(MessageLevel.Info, $"Loaded {m_dbMeasurements.Count:N0} records so far...");
                                }
                            }
                        }
                    }

                    OnStatusMessage(MessageLevel.Info, "Sorting data by time...");

                    m_dbMeasurements = m_dbMeasurements.OrderBy(m => (long)m.Timestamp).ToList();

                    OnStatusMessage(MessageLevel.Info, $"Completed data load in {((Ticks)(DateTime.UtcNow.Ticks - startTime)).ToElapsedTimeString(2)}");

                    if (m_cacheFileName != null)
                    {
                        OnStatusMessage(MessageLevel.Info, "Caching data for next initialization...");

                        using (FileStream data = File.OpenWrite(m_cacheFileName))
                        {
                            byte[] signalIndexCacheImage  = Serialization.Serialize(signalIndexCache, SerializationFormat.Binary);
                            int    compactMeasurementSize = (new CompactMeasurement(signalIndexCache)).BinaryLength;

                            // Write the signal index cache image size to the file
                            data.Write(LittleEndian.GetBytes(signalIndexCacheImage.Length), 0, 4);

                            // Write the signal index cache image to the file
                            data.Write(signalIndexCacheImage, 0, signalIndexCacheImage.Length);

                            // Write the size of each compact measurement to the file
                            data.Write(LittleEndian.GetBytes(compactMeasurementSize), 0, 4);

                            // Write the total number of compact measurements to the file
                            data.Write(LittleEndian.GetBytes(m_dbMeasurements.Count), 0, 4);

                            // Write each compact measurement image to the file
                            for (int i = 0; i < m_dbMeasurements.Count; i++)
                            {
                                ((ISupportBinaryImage)m_dbMeasurements[i]).CopyBinaryImageToStream(data);
                            }
                        }
                    }
                }

                OnStatusMessage(MessageLevel.Info, "Entering data read cycle...");
                ThreadPool.QueueUserWorkItem(PublishData);
            }
            catch (EndOfStreamException ex)
            {
                OnProcessException(MessageLevel.Warning, new EndOfStreamException($"Failed load cached data from {m_cacheFileName} due to file corruption{(string.IsNullOrWhiteSpace(ex.Message) ? "," : ": " + ex.Message + " - ")} cache will be recreated from database"));

                // If the cached file is corrupt, delete it and load from the database
                if (File.Exists(m_cacheFileName))
                {
                    File.Delete(m_cacheFileName);
                }

                m_dbMeasurements.Clear();
                GetDbMeasurements(null);
            }
            catch (Exception ex)
            {
                OnProcessException(MessageLevel.Warning, new InvalidOperationException("Failed during data load: " + ex.Message, ex));
            }
            finally
            {
                if (connection != null)
                {
                    connection.Close();
                }
            }
        }
 public override void SubscriptionUpdated(SignalIndexCache signalIndexCache)
 {
     StatusMessage($"Publisher provided {signalIndexCache.Count:N0} measurements in response to subscription.");
 }