Пример #1
0
        /// <summary>
        /// Gets the trend table from the cache, creating a table if necessary.
        /// </summary>
        private TrendTable GetTrendTable(DateTime timestamp)
        {
            DateTime tableDate = timestamp.Date;

            if (currentTable != null && currentTable.TableDate == tableDate)
            {
                return(currentTable);
            }
            else if (updatedTable != null && updatedTable.TableDate == tableDate)
            {
                return(updatedTable);
            }
            else
            {
                TrendTable trendTable = tableCache.Get(tableDate);

                if (trendTable == null)
                {
                    trendTable = new TrendTable(tableDate, writingPeriod)
                    {
                        CnlNumList = cnlNumList
                    };
                    tableCache.Add(tableDate, trendTable);
                }

                return(trendTable);
            }
        }
Пример #2
0
        /// <summary>
        /// Gets the trends of the specified channels.
        /// </summary>
        public override TrendBundle GetTrends(TimeRange timeRange, int[] cnlNums)
        {
            stopwatch.Restart();
            TrendBundle        trendBundle;
            List <TrendBundle> bundles = new List <TrendBundle>();
            int totalCapacity          = 0;

            foreach (DateTime date in EnumerateDates(timeRange))
            {
                TrendTable  trendTable = GetTrendTable(date);
                TrendBundle bundle     = adapter.ReadTrends(trendTable, timeRange, cnlNums);
                bundles.Add(bundle);
                totalCapacity += bundle.Timestamps.Count;
            }

            if (bundles.Count <= 0)
            {
                trendBundle = new TrendBundle(cnlNums, 0);
            }
            else if (bundles.Count == 1)
            {
                trendBundle = bundles[0];
            }
            else
            {
                // unite bundles
                trendBundle = new TrendBundle(cnlNums, totalCapacity);

                foreach (TrendBundle bundle in bundles)
                {
                    trendBundle.Timestamps.AddRange(bundle.Timestamps);

                    for (int i = 0, trendCnt = trendBundle.Trends.Count; i < trendCnt; i++)
                    {
                        trendBundle.Trends[i].AddRange(bundle.Trends[i]);
                    }
                }
            }

            stopwatch.Stop();
            arcLog?.WriteAction(ServerPhrases.ReadingTrendsCompleted,
                                trendBundle.Timestamps.Count, stopwatch.ElapsedMilliseconds);
            return(trendBundle);
        }
Пример #3
0
        /// <summary>
        /// Gets the available timestamps.
        /// </summary>
        public override List <DateTime> GetTimestamps(TimeRange timeRange)
        {
            stopwatch.Restart();
            List <DateTime>         resultTimestamps;
            List <List <DateTime> > listOfTimestamps = new List <List <DateTime> >();
            int totalCapacity = 0;

            foreach (DateTime date in EnumerateDates(timeRange))
            {
                TrendTable      trendTable = GetTrendTable(date);
                List <DateTime> timestamps = adapter.ReadTimestamps(trendTable, timeRange);
                listOfTimestamps.Add(timestamps);
                totalCapacity += timestamps.Count;
            }

            if (listOfTimestamps.Count <= 0)
            {
                resultTimestamps = new List <DateTime>();
            }
            else if (listOfTimestamps.Count == 1)
            {
                resultTimestamps = listOfTimestamps[0];
            }
            else
            {
                // unite timestamps
                resultTimestamps = new List <DateTime>(totalCapacity);

                foreach (List <DateTime> timestamps in listOfTimestamps)
                {
                    resultTimestamps.AddRange(timestamps);
                }
            }

            stopwatch.Stop();
            arcLog?.WriteAction(ServerPhrases.ReadingTimestampsCompleted,
                                resultTimestamps.Count, stopwatch.ElapsedMilliseconds);
            return(resultTimestamps);
        }
Пример #4
0
        /// <summary>
        /// Gets the trend of the specified channel.
        /// </summary>
        public override Trend GetTrend(TimeRange timeRange, int cnlNum)
        {
            stopwatch.Restart();
            Trend        resultTrend;
            List <Trend> trends        = new List <Trend>();
            int          totalCapacity = 0;

            foreach (DateTime date in EnumerateDates(timeRange))
            {
                TrendTable trendTable = GetTrendTable(date);
                Trend      trend      = adapter.ReadTrend(trendTable, timeRange, cnlNum);
                trends.Add(trend);
                totalCapacity += trend.Points.Count;
            }

            if (trends.Count <= 0)
            {
                resultTrend = new Trend(cnlNum, 0);
            }
            else if (trends.Count == 1)
            {
                resultTrend = trends[0];
            }
            else
            {
                // unite trends
                resultTrend = new Trend(cnlNum, totalCapacity);

                foreach (Trend trend in trends)
                {
                    resultTrend.Points.AddRange(trend.Points);
                }
            }

            stopwatch.Stop();
            arcLog?.WriteAction(ServerPhrases.ReadingTrendCompleted,
                                resultTrend.Points.Count, stopwatch.ElapsedMilliseconds);
            return(resultTrend);
        }
Пример #5
0
        private TrendTable updatedTable;                                // the trend table that is currently being updated


        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        public BasicHAL(IArchiveContext archiveContext, ArchiveConfig archiveConfig, int[] cnlNums,
                        ModuleConfig moduleConfig) : base(archiveContext, archiveConfig, cnlNums)
        {
            this.moduleConfig = moduleConfig ?? throw new ArgumentNullException(nameof(moduleConfig));
            options           = new BasicHAO(archiveConfig.CustomOptions);
            appLog            = archiveContext.Log;
            arcLog            = options.LogEnabled ? CreateLog(ModuleUtils.ModuleCode) : null;
            stopwatch         = new Stopwatch();
            adapter           = new TrendTableAdapter
            {
                ArchiveCode = Code,
                CnlNumCache = new MemoryCache <long, CnlNumList>(ModuleUtils.CacheExpiration, ModuleUtils.CacheCapacity)
            };
            tableCache    = new MemoryCache <DateTime, TrendTable>(ModuleUtils.CacheExpiration, ModuleUtils.CacheCapacity);
            slice         = new Slice(DateTime.MinValue, cnlNums);
            writingPeriod = GetPeriodInSec(options.WritingPeriod, options.WritingUnit);

            nextWriteTime = DateTime.MinValue;
            cnlIndexes    = null;
            cnlNumList    = new CnlNumList(cnlNums);
            currentTable  = null;
            updatedTable  = null;
        }
Пример #6
0
        private TrendTable updatedTable;                                // the trend table that is currently being updated


        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        public BasicHAL(IArchiveContext archiveContext, ArchiveConfig archiveConfig, int[] cnlNums)
            : base(archiveContext, archiveConfig, cnlNums)
        {
            options   = new BasicHAO(archiveConfig.CustomOptions);
            appLog    = archiveContext.Log;
            arcLog    = options.LogEnabled ? CreateLog(ModuleUtils.ModuleCode) : null;
            stopwatch = new Stopwatch();
            adapter   = new TrendTableAdapter
            {
                ParentDirectory = Path.Combine(archiveContext.AppConfig.PathOptions.GetArcDir(options.IsCopy), Code),
                ArchiveCode     = Code,
                CnlNumCache     = new MemoryCache <long, CnlNumList>(ModuleUtils.CacheExpiration, ModuleUtils.CacheCapacity)
            };
            tableCache    = new MemoryCache <DateTime, TrendTable>(ModuleUtils.CacheExpiration, ModuleUtils.CacheCapacity);
            slice         = new Slice(DateTime.MinValue, cnlNums);
            writingPeriod = GetPeriodInSec(options.WritingPeriod, options.WritingUnit);

            nextWriteTime = DateTime.MinValue;
            cnlIndexes    = null;
            cnlNumList    = new CnlNumList(cnlNums);
            currentTable  = null;
            updatedTable  = null;
        }
Пример #7
0
        /// <summary>
        /// Processes new data.
        /// </summary>
        public override bool ProcessData(ICurrentData curData)
        {
            if (options.WritingMode == WritingMode.AutoWithPeriod && nextWriteTime <= curData.Timestamp)
            {
                DateTime writeTime = GetClosestWriteTime(curData.Timestamp, writingPeriod);
                nextWriteTime = writeTime.AddSeconds(writingPeriod);

                stopwatch.Restart();
                TrendTable trendTable = GetCurrentTrendTable(writeTime);
                InitCnlIndexes(curData, ref cnlIndexes);
                CopyCnlData(curData, slice, cnlIndexes);
                slice.Timestamp = writeTime;
                adapter.WriteSlice(trendTable, slice);

                stopwatch.Stop();
                arcLog?.WriteAction(ServerPhrases.WritingSliceCompleted,
                                    slice.CnlNums.Length, stopwatch.ElapsedMilliseconds);
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #8
0
        /// <summary>
        /// Gets the today's trend table, creating it if necessary.
        /// </summary>
        private TrendTable GetCurrentTrendTable(DateTime nowDT)
        {
            DateTime today = nowDT.Date;

            if (currentTable == null)
            {
                currentTable = new TrendTable(today, writingPeriod)
                {
                    CnlNumList = cnlNumList
                };
                currentTable.SetDefaultMetadata();
            }
            else if (currentTable.TableDate != today) // current date is changed
            {
                tableCache.Add(currentTable.TableDate, currentTable);
                currentTable = new TrendTable(today, writingPeriod)
                {
                    CnlNumList = cnlNumList
                };
                currentTable.SetDefaultMetadata();
            }

            return(currentTable);
        }
Пример #9
0
        /// <summary>
        /// Checks and updates the today's trend table.
        /// </summary>
        private void CheckCurrentTrendTable(DateTime nowDT)
        {
            currentTable = GetCurrentTrendTable(nowDT);
            string tableDir     = adapter.GetTablePath(currentTable);
            string metaFileName = adapter.GetMetaPath(currentTable);

            if (Directory.Exists(tableDir))
            {
                TrendTableMeta srcTableMeta = adapter.ReadMetadata(metaFileName);

                if (srcTableMeta == null)
                {
                    // the existing table is invalid and should be deleted
                    Directory.Delete(tableDir, true);
                }
                else if (srcTableMeta.Equals(currentTable.Metadata))
                {
                    if (currentTable.GetDataPosition(nowDT, PositionKind.Ceiling,
                                                     out TrendTablePage page, out _))
                    {
                        string     pageFileName = adapter.GetPagePath(page);
                        CnlNumList srcCnlNums   = adapter.ReadCnlNums(pageFileName);

                        if (srcCnlNums == null)
                        {
                            // make sure that there is no page file
                            File.Delete(pageFileName);
                        }
                        else if (srcCnlNums.Equals(cnlNumList))
                        {
                            // re-create the channel list to use the existing list ID
                            cnlNumList = new CnlNumList(srcCnlNums.ListID, cnlNumList);
                        }
                        else
                        {
                            // update the current page
                            string msg = string.Format(Locale.IsRussian ?
                                                       "Обновление номеров каналов страницы {0}" :
                                                       "Update channel numbers of the page {0}", pageFileName);
                            appLog.WriteAction(ServerPhrases.ArchiveMessage, Code, msg);
                            arcLog?.WriteAction(msg);
                            adapter.UpdatePageChannels(page, srcCnlNums);
                        }
                    }
                }
                else
                {
                    // updating the entire table structure would take too long, so just backup the table
                    string msg = string.Format(Locale.IsRussian ?
                                               "Резервное копирование таблицы {0}" :
                                               "Backup the table {0}", tableDir);
                    appLog.WriteAction(ServerPhrases.ArchiveMessage, Code, msg);
                    arcLog?.WriteAction(msg);
                    adapter.BackupTable(currentTable);
                }
            }

            // create an empty table if it does not exist
            if (!Directory.Exists(tableDir))
            {
                adapter.WriteMetadata(metaFileName, currentTable.Metadata);
                currentTable.IsReady = true;
            }

            // add the archive channel list to the cache
            adapter.CnlNumCache.Add(cnlNumList.ListID, cnlNumList);
        }
Пример #10
0
 /// <summary>
 /// Completes the update operation.
 /// </summary>
 public override void EndUpdate(DateTime timestamp, int deviceNum)
 {
     updatedTable = null;
     stopwatch.Stop();
     arcLog?.WriteAction(ServerPhrases.UpdateCompleted, stopwatch.ElapsedMilliseconds);
 }
Пример #11
0
 /// <summary>
 /// Maintains performance when data is written one at a time.
 /// </summary>
 public override void BeginUpdate(DateTime timestamp, int deviceNum)
 {
     stopwatch.Restart();
     updatedTable = GetTrendTable(timestamp);
 }