/// <summary> /// Default data processing entry point for <see cref="DataWriter"/>. /// </summary> /// <param name="timestamp">Timestamp of <paramref name="dataBlock"/>.</param> /// <param name="dataBlock">Points values read at current timestamp.</param> public void Write(DateTime timestamp, DataPoint[] dataBlock) { if (m_settings.WriteToOpenHistorian) // Write to openHistorian { foreach (DataPoint point in dataBlock) { m_historianKey.Timestamp = point.Timestamp; m_historianKey.PointID = point.PointID; m_historianValue.Value1 = point.Value; m_historianValue.Value3 = point.Flags; m_historianArchive.Write(m_historianKey, m_historianValue); } } if (m_settings.WriteToBerkeleyDB) // Write to Berkeley DB { //// Create a new pointList each time *slow //KeyValuePair<DatabaseEntry, DatabaseEntry>[] pointList = new KeyValuePair<DatabaseEntry, DatabaseEntry>[dataBlock.Length]; //Parallel.For(0, pointList.Length, (i) => pointList[i] = new KeyValuePair<DatabaseEntry, DatabaseEntry>( // new DatabaseEntry(BitConverter.GetBytes(timestamp.Ticks).Concat(BitConverter.GetBytes(dataBlock[i].PointID)).ToArray()), // new DatabaseEntry(BitConverter.GetBytes(dataBlock[i].Value)))); //using (MultipleKeyDatabaseEntry buffer = new MultipleKeyDatabaseEntry(pointList, false)) //{ // m_berkeleyDb.Put(buffer); //} //Parallel.For(0, pointList.Length, (i) => //{ // pointList[i].Key.Dispose(); // pointList[i].Value.Dispose(); //}); //// Single writes using the same key and value each time *medium speed //foreach (DataPoint point in dataBlock) //{ // m_berkeleyDbKey.Data = BitConverter.GetBytes(timestamp.Ticks).Concat(BitConverter.GetBytes(point.PointID)).ToArray(); // m_berkeleyDbValue.Data = BitConverter.GetBytes(point.Value).ToArray(); // m_berkeleyDb.Put(m_berkeleyDbKey, m_berkeleyDbValue); //} // Bulk writes using the same pointList *fastest method found so far* Parallel.For(0, dataBlock.Length, (i) => { m_berkeleyDbPointList[i].Key.Data = BitConverter.GetBytes(timestamp.Ticks).Concat(BitConverter.GetBytes(dataBlock[i].PointID)).ToArray(); m_berkeleyDbPointList[i].Value.Data = BitConverter.GetBytes(dataBlock[i].Value); }); using (MultipleKeyDatabaseEntry buffer = new MultipleKeyDatabaseEntry(m_berkeleyDbPointList.Take(dataBlock.Length), false)) { m_berkeleyDb.Put(buffer); } } }
/// <summary> /// Archives <paramref name="measurements"/> locally. /// </summary> /// <param name="measurements">Measurements to be archived.</param> /// <exception cref="InvalidOperationException">Local archive is closed.</exception> protected override void ProcessMeasurements(IMeasurement[] measurements) { foreach (IMeasurement measurement in measurements) { m_key.Timestamp = (ulong)(long)measurement.Timestamp; m_key.PointID = measurement.Key.ID; // Since current time-series measurements are basically all floats - values fit into first value, // this will change as value types for time-series framework expands m_value.Value1 = BitConvert.ToUInt64((float)measurement.AdjustedValue); m_value.Value3 = (ulong)measurement.StateFlags; m_archive.Write(m_key, m_value); } m_archivedMeasurements += measurements.Length; }