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(); } }
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); }
// 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."); }