3886 lines · 170.6 KB · C#
RawDownload
//******************************************************************************************************//  ArchiveFile.cs - Gbtc////  Copyright © 2012, Grid Protection Alliance.  All Rights Reserved.////  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See//  the NOTICE file distributed with this work for additional information regarding copyright ownership.//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may//  not use this file except in compliance with the License. You may obtain a copy of the License at:////      http://www.opensource.org/licenses/MIT////  Unless agreed to in writing, the subject software distributed under the License is distributed on an//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the//  License for the specific language governing permissions and limitations.////  Code Modification History://  ----------------------------------------------------------------------------------------------------//  02/18/2007 - Pinal C. Patel//       Generated original version of source code.//  01/23/2008 - Pinal C. Patel//       Added code to better utilize memory by disposing inactive data blocks.//       Added ProcessAlarmNotification event to notify the service that alarm notifications are to be //       issued for the specified point.//  03/31/2008 - Pinal C. Patel//       Added CacheWrites and ConserveMemory properties for performance improvement.//  04/21/2009 - Pinal C. Patel//       Converted to C#.//  06/18/2009 - Pinal C. Patel//       Fixed the implementation of Enabled property.//  07/02/2009 - Pinal C. Patel//       Modified state alternating properties to reopen the file when changed.//  09/02/2009 - Pinal C. Patel//       Modified code to prevent writes to dependency files when their access mode doesn't allow writes.//  09/10/2009 - Pinal C. Patel//       Modified ReadMetaData(), ReadStateData(), ReadMetaDataSummary() and ReadStateDataSummary() to//       check for null references, indicating no matching record, before returning the binary image.//  09/11/2009 - Pinal C. Patel//       Modified code to ensure the validity of dependency files by synchronizing them.//       Removed event handler on StateFile.FileModified event to avoid unnecessary processing.//  09/14/2009 - Pinal C. Patel//       Fixed NullReferenceException encountered in Statistics if accessed when file is being opened.//       Fixed issue in MetadataFile property related to event handlers.//  09/15/2009 - Stephen C. Wills//       Added new header and license agreement.//  09/17/2009 - Pinal C. Patel//       Implemented the IProvideStatus interface.//  09/23/2009 - Pinal C. Patel//       Edited code comments.//       Removed the dependency on ArchiveDataPoint.//  10/14/2009 - Pinal C. Patel//       Re-coded the way current data was being written for maximum write throughput.//       Fixed DivideByZero exception in Statistics property.//       Fixed a issue in quality-based alarm processing.//       Removed unused/unnecessary event raised during the write process.//  11/06/2009 - Pinal C. Patel//       Modified Read() and Write() methods to wait on the rollover process.//  12/01/2009 - Pinal C. Patel//       Removed unused RolloverOnFull property.//       Fixed a issue in the rollover process that is encountered only when dependency files are //       configured to not load records in memory.//  12/02/2009 - Pinal C. Patel//       Modified Status property to show the total number of historic archive files.//       Fixed a issue in the update of historic archive file list.//  12/03/2009 - Pinal C. Patel//       Updated Read() to incorporate changes made to ArchiveFileAllocationTable.FindDataBlocks().//  12/08/2009 - Pinal C. Patel//       Modified to save the FAT at the end of rollover process.//  03/03/2010 - Pinal C. Patel//       Added MaxHistoricArchiveFiles property to limit the number of history files to be kept.//  03/18/2010 - Pinal C. Patel//       Modified ReadData() to use the current ArchiveFile instance for reading data from the current//       file instead of creating a new instance to avoid complications when rolling over to a new file.//  04/28/2010 - Pinal C. Patel//       Modified WriteData() overload that takes a collection of IDataPoint to not check file state.//  10/11/2010 - Mihir Brahmbhatt//       Updated header and license agreement.//  11/18/2010 - J. Ritchie Carroll//       Added a exception handler for reading (exposed via DataReadException event) to make sure//       bad data or corruption in an archive file does not stop the read process.//  11/30/2011 - J. Ritchie Carroll//       Modified to support buffer optimized ISupportBinaryImage.//  10/03/2012 - J. Ritchie Carroll//       Modified to support resumable read after roll-over completes.//  12/14/2012 - Starlynn Danyelle Gilliam//       Modified Header.//  01/22/2014 - J. Ritchie Carroll//       Fixed issue with *DELETE* setting for ArchiveOffloadLocation.////****************************************************************************************************** using System;using System.Collections.Generic;using System.ComponentModel;using System.Configuration;using System.Diagnostics.CodeAnalysis;using System.Drawing;using System.IO;using System.Text;using System.Text.RegularExpressions;using System.Threading;using System.Timers;using GSF.Collections;using GSF.Configuration;using GSF.IO;using GSF.Parsing;using Timer = System.Timers.Timer; namespace GSF.Historian.Files{    #region [ Enumerations ]     /// <summary>    /// Indicates the type of <see cref="ArchiveFile"/>.    /// </summary>    public enum ArchiveFileType    {        /// <summary>        /// <see cref="ArchiveFile"/> is being used for archiving current data.        /// </summary>        Active,        /// <summary>        /// <see cref="ArchiveFile"/> to be used in the rollover process.        /// </summary>        Standby,        /// <summary>        /// <see cref="ArchiveFile"/> is full and is not to be used for current data.        /// </summary>        Historic    }     #endregion     /// <summary>    /// Represents a file that contains <see cref="ArchiveDataPoint"/>s.    /// </summary>    /// <seealso cref="ArchiveDataPoint"/>    /// <seealso cref="ArchiveFileAllocationTable"/>    [ToolboxBitmap(typeof(ArchiveFile))]    public class ArchiveFile : Component, IArchive, ISupportLifecycle, ISupportInitialize, IProvideStatus, IPersistSettings    {        #region [ Members ]         // Nested Types         /// <summary>        /// Represents information about an <see cref="ArchiveFile"/>.        /// </summary>        private class Info : IComparable        {            public Info(string fileName)            {                FileName = fileName;            }             /// <summary>            /// Name of the <see cref="ArchiveFile"/>.            /// </summary>            public readonly string FileName;             /// <summary>            /// Start <see cref="TimeTag"/> of the <see cref="ArchiveFile"/>.            /// </summary>            public TimeTag StartTimeTag;             /// <summary>            /// End <see cref="TimeTag"/> of the <see cref="ArchiveFile"/>.            /// </summary>            public TimeTag EndTimeTag;             public int CompareTo(object obj)            {                Info other = obj as Info;                 if ((object)other == null)                    return 1;                 int result = StartTimeTag.CompareTo(other.StartTimeTag);                 if (result != 0)                    return result;                 return EndTimeTag.CompareTo(other.EndTimeTag);            }             public override bool Equals(object obj)            {                Info other = obj as Info;                 if ((object)other == null)                    return false;                 // We will only compare file name for equality because the result will be incorrect if one of                // the ArchiveFileInfo instance is created from the filename by GetHistoricFileInfo() function.                return string.Compare(FilePath.GetFileName(FileName), FilePath.GetFileName(other.FileName), StringComparison.OrdinalIgnoreCase) == 0;            }             public override int GetHashCode()            {                return FileName.GetHashCode();            }        }         // Constants         /// <summary>        /// Specifies the default value for the <see cref="FileName"/> property.        /// </summary>        public const string DefaultFileName = "ArchiveFile" + FileExtension;         /// <summary>        /// Specifies the default value for the <see cref="FileType"/> property.        /// </summary>        public const ArchiveFileType DefaultFileType = ArchiveFileType.Active;         /// <summary>        /// Specifies the default value for the <see cref="FileSize"/> property.        /// </summary>        public const int DefaultFileSize = 1500;         /// <summary>        /// Specifies the default value for the <see cref="FileAccessMode"/> property.        /// </summary>        public const FileAccess DefaultFileAccessMode = FileAccess.ReadWrite;         /// <summary>        /// Specifies the default value for the <see cref="DataBlockSize"/> property.        /// </summary>        public const int DefaultDataBlockSize = 8;         /// <summary>        /// Specifies the default value for the <see cref="RolloverPreparationThreshold"/> property.        /// </summary>        public const double DefaultRolloverPreparationThreshold = 75.0D;         /// <summary>        /// Specifies the default value for the <see cref="ArchiveOffloadCount"/> property.        /// </summary>        public const int DefaultArchiveOffloadCount = 5;         /// <summary>        /// Specifies the default value for the <see cref="ArchiveOffloadLocation"/> property.        /// </summary>        public const string DefaultArchiveOffloadLocation = "";         /// <summary>        /// Specifies the default value for the <see cref="ArchiveOffloadThreshold"/> property.        /// </summary>        public const double DefaultArchiveOffloadThreshold = 90.0D;         /// <summary>        /// Specifies the default value for the <see cref="ArchiveOffloadMaxAge"/> property.        /// </summary>        public const int DefaultArchiveOffloadMaxAge = -1;         /// <summary>        /// Specifies the default value for the <see cref="MaxHistoricArchiveFiles"/> property.        /// </summary>        public const int DefaultMaxHistoricArchiveFiles = -1;         /// <summary>        /// Specifies the default value for the <see cref="LeadTimeTolerance"/> property.        /// </summary>        public const int DefaultLeadTimeTolerance = 15;         /// <summary>        /// Specifies the default value for the <see cref="CompressData"/> property.        /// </summary>        public const bool DefaultCompressData = true;         /// <summary>        /// Specifies the default value for the <see cref="DiscardOutOfSequenceData"/> property.        /// </summary>        public const bool DefaultDiscardOutOfSequenceData = true;         /// <summary>        /// Specifies the default value for the <see cref="CacheWrites"/> property.        /// </summary>        public const bool DefaultCacheWrites = false;         /// <summary>        /// Specifies the default value for the <see cref="ConserveMemory"/> property.        /// </summary>        public const bool DefaultConserveMemory = true;         /// <summary>        /// Specifies the default value for the <see cref="MonitorNewArchiveFiles"/> property.        /// </summary>        public const bool DefaultMonitorNewArchiveFiles = false;         /// <summary>        /// Specifies the default value for the <see cref="PersistSettings"/> property.        /// </summary>        public const bool DefaultPersistSettings = false;         /// <summary>        /// Specifies the default value for the <see cref="SettingsCategory"/> property.        /// </summary>        public const string DefaultSettingsCategory = "ArchiveFile";         /// <summary>        /// Specifies the extension for current and historic <see cref="ArchiveFile"/>.        /// </summary>        private const string FileExtension = ".d";         /// <summary>        /// Specifies the extension for a standby <see cref="ArchiveFile"/>.        /// </summary>        private const string StandbyFileExtension = ".standby";         /// <summary>        /// Specifies the interval (in milliseconds) for the memory conservation process to run.        /// </summary>        private const int DataBlockCheckInterval = 60000;         // Events         /// <summary>        /// Occurs when the active <see cref="ArchiveFile"/> if full.        /// </summary>        [Category("File"),        Description("Occurs when the active ArchiveFile if full.")]        public event EventHandler FileFull;         /// <summary>        /// Occurs when the process of offloading historic <see cref="ArchiveFile"/>s is started.        /// </summary>        [Category("Archive"),        Description("Occurs when the process of offloading historic ArchiveFiles is started.")]        public event EventHandler OffloadStart;         /// <summary>        /// Occurs when the process of offloading historic <see cref="ArchiveFile"/>s is complete.        /// </summary>        [Category("Archive"),        Description("Occurs when the process of offloading historic ArchiveFiles is complete.")]        public event EventHandler OffloadComplete;         /// <summary>        /// Occurs when an <see cref="Exception"/> is encountered during the historic <see cref="ArchiveFile"/> offload process.        /// </summary>        [Category("Archive"),        Description("Occurs when an Exception is encountered during the historic ArchiveFile offload process.")]        public event EventHandler<EventArgs<Exception>> OffloadException;         /// <summary>        /// Occurs when an historic <see cref="ArchiveFile"/> is being offloaded.        /// </summary>        [Category("Archive"),        Description("Occurs when an historic ArchiveFile is being offloaded.")]        public event EventHandler<EventArgs<ProcessProgress<int>>> OffloadProgress;         /// <summary>        /// Occurs when <see cref="Rollover()"/> to a new <see cref="ArchiveFile"/> is started.        /// </summary>        [Category("Rollover"),        Description("Occurs when Rollover to a new ArchiveFile is started.")]        public event EventHandler RolloverStart;         /// <summary>        /// Occurs when <see cref="Rollover()"/> to a new <see cref="ArchiveFile"/> is complete.        /// </summary>        [Category("Rollover"),        Description("Occurs when Rollover to a new ArchiveFile is complete.")]        public event EventHandler RolloverComplete;         /// <summary>        /// Occurs when an <see cref="Exception"/> is encountered during the <see cref="Rollover()"/> process.        /// </summary>        [Category("Rollover"),        Description("Occurs when an Exception is encountered during the Rollover() process.")]        public event EventHandler<EventArgs<Exception>> RolloverException;         /// <summary>        /// Occurs when the process of creating a standby <see cref="ArchiveFile"/> is started.        /// </summary>        [Category("Rollover"),        Description("Occurs when the process of creating a standby ArchiveFile is started.")]        public event EventHandler RolloverPreparationStart;         /// <summary>        /// Occurs when the process of creating a standby <see cref="ArchiveFile"/> is complete.        /// </summary>        [Category("Rollover"),        Description("Occurs when the process of creating a standby ArchiveFile is complete.")]        public event EventHandler RolloverPreparationComplete;         /// <summary>        /// Occurs when an <see cref="Exception"/> is encountered during the standby <see cref="ArchiveFile"/> creation process.        /// </summary>        [Category("Rollover"),        Description("Occurs when an Exception is encountered during the standby ArchiveFile creation process.")]        public event EventHandler<EventArgs<Exception>> RolloverPreparationException;         /// <summary>        /// Occurs when the process of building historic <see cref="ArchiveFile"/> list is started.        /// </summary>        [Category("File"),        Description("Occurs when the process of building historic ArchiveFile list is started.")]        public event EventHandler HistoricFileListBuildStart;         /// <summary>        /// Occurs when the process of building historic <see cref="ArchiveFile"/> list is complete.        /// </summary>        [Category("File"),        Description("Occurs when the process of building historic ArchiveFile list is complete.")]        public event EventHandler HistoricFileListBuildComplete;         /// <summary>        /// Occurs when an <see cref="Exception"/> is encountered in historic <see cref="ArchiveFile"/> list building process.        /// </summary>        [Category("File"),        Description("Occurs when an Exception is encountered in historic ArchiveFile list building process.")]        public event EventHandler<EventArgs<Exception>> HistoricFileListBuildException;         /// <summary>        /// Occurs when the historic <see cref="ArchiveFile"/> list is updated to reflect addition or deletion of historic <see cref="ArchiveFile"/>s.        /// </summary>        [Category("File"),        Description("Occurs when the historic ArchiveFile list is updated to reflect addition or deletion of historic ArchiveFiles.")]        public event EventHandler HistoricFileListUpdated;         /// <summary>        /// Occurs when <see cref="IDataPoint"/> is received for which a <see cref="StateRecord"/> or <see cref="MetadataRecord"/> does not exist or is marked as disabled.        /// </summary>        [Category("Data"),        Description("Occurs when IDataPoint is received for which a StateRecord or MetadataRecord does not exist or is marked as disabled.")]        public event EventHandler<EventArgs<IDataPoint>> OrphanDataReceived;         /// <summary>        /// Occurs when <see cref="IDataPoint"/> is received with <see cref="TimeTag"/> ahead of the local clock by more than the <see cref="LeadTimeTolerance"/>.        /// </summary>        [Category("Data"),        Description("Occurs when IDataPoint is received with TimeTag ahead of the local clock by more than the LeadTimeTolerance.")]        public event EventHandler<EventArgs<IDataPoint>> FutureDataReceived;         /// <summary>        /// Occurs when <see cref="IDataPoint"/> that belongs to a historic <see cref="ArchiveFile"/> is received for archival.        /// </summary>        [Category("Data"),        Description("Occurs when IDataPoint that belongs to a historic ArchiveFile is received for archival.")]        public event EventHandler<EventArgs<IDataPoint>> HistoricDataReceived;         /// <summary>        /// Occurs when misaligned (by time) <see cref="IDataPoint"/> is received for archival.        /// </summary>        [Category("Data"),        Description("Occurs when misaligned (by time) IDataPoint is received for archival.")]        public event EventHandler<EventArgs<IDataPoint>> OutOfSequenceDataReceived;         /// <summary>        /// Occurs when an <see cref="Exception"/> is encountered while reading <see cref="IDataPoint"/> from the current or historic <see cref="ArchiveFile"/>.        /// </summary>        [Category("Data"),        Description("Occurs when an Exception is encountered while reading IDataPoint from the current or historic ArchiveFile.")]        public event EventHandler<EventArgs<Exception>> DataReadException;         /// <summary>        /// Occurs when an <see cref="Exception"/> is encountered while writing <see cref="IDataPoint"/> to the current or historic <see cref="ArchiveFile"/>.        /// </summary>        [Category("Data"),        Description("Occurs when an Exception is encountered while writing IDataPoint to the current or historic ArchiveFile.")]        public event EventHandler<EventArgs<Exception>> DataWriteException;         /// <summary>        /// Occurs when <see cref="IDataPoint"/> triggers an alarm notification.        /// </summary>        [Category("File"),        Description("Occurs when IDataPoint triggers an alarm notification.")]        public event EventHandler<EventArgs<StateRecord>> ProcessAlarmNotification;         /// <summary>        /// Occurs when associated Metadata file is updated.        /// </summary>        [Category("Metadata"),        Description("Occurs when associated Metadata file is updated.")]        public event EventHandler MetadataUpdated;         // Fields         // Component        private string m_fileName;        private ArchiveFileType m_fileType;        private double m_fileSize;        private FileAccess m_fileAccessMode;        private int m_dataBlockSize;        private double m_rolloverPreparationThreshold;        private string m_archiveOffloadLocation;        private int m_archiveOffloadCount;        private double m_archiveOffloadThreshold;        private int m_archiveOffloadMaxAge;        private int m_maxHistoricArchiveFiles;        private double m_leadTimeTolerance;        private bool m_compressData;        private bool m_discardOutOfSequenceData;        private bool m_cacheWrites;        private bool m_conserveMemory;        private bool m_monitorNewArchiveFiles;        private bool m_persistSettings;        private string m_settingsCategory;

Lines 1–500 of 3886.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t