示例#1
0
文件: ArchiveFile.cs 项目: avs009/gsf
        private void PrepareForRollover()
        {
            try
            {
                DriveInfo archiveDrive = new DriveInfo(Path.GetPathRoot(m_fileName));
                if (archiveDrive.AvailableFreeSpace < archiveDrive.TotalSize * (1 - ((double)m_fileOffloadThreshold / 100)))
                {
                    // We'll start offloading historic files if we've reached the offload threshold.
                    OffloadHistoricFiles();
                }

                OnRolloverPreparationStart();

                // Opening and closing a new archive file in "standby" mode will create a "standby" archive file.
                ArchiveFile standbyArchiveFile = new ArchiveFile();
                standbyArchiveFile.FileName = StandbyArchiveFileName;
                standbyArchiveFile.FileSize = m_fileSize;
                standbyArchiveFile.DataBlockSize = m_dataBlockSize;
                standbyArchiveFile.StateFile = m_stateFile;
                standbyArchiveFile.IntercomFile = m_intercomFile;
                standbyArchiveFile.MetadataFile = m_metadataFile;
                try
                {
                    standbyArchiveFile.Open();
                }
                catch (Exception)
                {
                    string standbyFileName = standbyArchiveFile.FileName;
                    standbyArchiveFile.Close();
                    // We didn't succeed in creating a "standby" archive file, so we'll delete it if it was created
                    // partially (might happen if there isn't enough disk space or thread is aborted). This is to
                    // ensure that this preparation processes is kicked off again until a valid "standby" archive
                    // file is successfully created.
                    if (File.Exists(standbyFileName))
                    {
                        File.Delete(standbyFileName);
                    }

                    throw; // Rethrow the exception so the appropriate action is taken.
                }
                finally
                {
                    standbyArchiveFile.Dispose();
                }

                OnRolloverPreparationComplete();
            }
            catch (ThreadAbortException)
            {
                // This thread must die now...
            }
            catch (Exception ex)
            {
                OnRolloverPreparationException(ex);
            }
        }
示例#2
0
文件: ArchiveFile.cs 项目: avs009/gsf
        /// <summary>
        /// Reads <see cref="ArchiveData"/> points.
        /// </summary>
        /// <param name="historianID">Historian identifier for which <see cref="ArchiveData"/> points are to be retrieved.</param>
        /// <param name="startTime">Start <see cref="TimeTag"/> (in GMT) for the <see cref="ArchiveData"/> points to be retrieved.</param>
        /// <param name="endTime">End <see cref="TimeTag"/> (in GMT) for the <see cref="ArchiveData"/> points to be retrieved.</param>
        /// <returns><see cref="IEnumerable{T}"/> object containing zero or more <see cref="ArchiveData"/> points.</returns>
        public IEnumerable<IDataPoint> ReadData(int historianID, TimeTag startTime, TimeTag endTime)
        {
            // Ensure that the current file is open.
            if (!IsOpen)
                throw new InvalidOperationException(string.Format("\"{0}\" file is not open.", m_fileName));

            // Ensure that the current file is active.
            if (m_fileType != ArchiveFileType.Active)
                throw new InvalidOperationException("Data can only be directly read from files that are Active.");

            // Ensure that the start and end time are valid.
            if (startTime > endTime)
                throw new ArgumentException("End Time preceeds Start Time in the specified timespan.");

            // Yeild to the rollover process if it is in progress.
            m_rolloverWaitHandle.WaitOne();

            List<Info> dataFiles = new List<Info>();
            if (startTime < m_fat.FileStartTime)
            {
                // Data is to be read from historic file(s).
                if (m_buildHistoricFileListThread.IsAlive)
                    m_buildHistoricFileListThread.Join();

                m_readSearchStartTimeTag = startTime;
                m_readSearchEndTimeTag = endTime;
                lock (m_historicArchiveFiles)
                {
                    dataFiles.AddRange(m_historicArchiveFiles.FindAll(FindHistoricArchiveFileForRead));
                }
            }

            if (endTime >= m_fat.FileStartTime)
            {
                // Data is to be read from the active file.
                Info activeFileInfo = new Info();
                activeFileInfo.FileName = m_fileName;
                activeFileInfo.StartTimeTag = m_fat.FileStartTime;
                activeFileInfo.EndTimeTag = m_fat.FileEndTime;
                dataFiles.Add(activeFileInfo);
            }

            // Read data from all qualifying files.
            foreach (Info dataFile in dataFiles)
            {
                ArchiveFile file = new ArchiveFile();
                IList<ArchiveDataBlock> dataBlocks;
                try
                {
                    file.FileName = dataFile.FileName;
                    file.StateFile = m_stateFile;
                    file.IntercomFile = m_intercomFile;
                    file.MetadataFile = m_metadataFile;
                    file.Open();

                    dataBlocks = file.Fat.FindDataBlocks(historianID, startTime, endTime);
                    if (dataBlocks.Count > 0)
                    {
                        // Data block before the first data block matching the search criteria might contain some data 
                        // for the specified search criteria, so look for such a data block and process its data.
                        lock (file.Fat.DataBlockPointers)
                        {
                            for (int i = dataBlocks[0].Index - 1; i >= 0; i--)
                            {
                                if (file.Fat.DataBlockPointers[i].HistorianID == historianID)
                                {
                                    foreach (ArchiveData data in file.Fat.DataBlockPointers[i].DataBlock.Read())
                                    {
                                        if (data.Time >= startTime)
                                            yield return data;
                                    }

                                    break;
                                }
                            }
                        }

                        // Read data from rest of the data blocks and scan the last data block for data matching the
                        // the search criteria as it may contain data beyond the timespan specified in the search.
                        for (int i = 0; i < dataBlocks.Count; i++)
                        {
                            if (i < dataBlocks.Count - 1)
                            {
                                // Read all the data.
                                foreach (ArchiveData data in dataBlocks[i].Read())
                                {
                                    yield return data;
                                }
                            }
                            else
                            {
                                // Scan through the data block.
                                foreach (ArchiveData data in dataBlocks[i].Read())
                                {
                                    if (data.Time <= endTime)
                                        yield return data;
                                    else
                                        yield break;
                                }
                            }
                        }
                    }
                }
                finally
                {
                    if (file.IsOpen)
                    {
                        file.Close();
                    }
                }
            }
        }