/// <summary>
        /// Processes the rollover of this file.
        /// </summary>
        private void m_rolloverTask_Running(object sender, EventArgs <ScheduledTaskRunningReason> e)
        {
            //the nature of how the ScheduledTask works
            //gaurentees that this function will not be called concurrently

            //The worker can be disposed either via the Stop() method or
            //the Dispose() method.  If via the dispose method, then
            //don't do any cleanup.
            if (m_disposed && e.Argument == ScheduledTaskRunningReason.Disposing)
            {
                Log.Publish(MessageLevel.Info, "Rollover thread is Disposing");

                m_waitForEmptyActiveQueue.Dispose();
                return;
            }

            lock (m_syncRoot)
            {
                int count = m_activeQueue.Count;
                if (count == 0)
                {
                    m_waitForEmptyActiveQueue.Set();
                    return;
                }

                //Swap active and processing.
                SortedPointBuffer <TKey, TValue> swap = m_activeQueue;
                m_activeQueue               = m_processingQueue;
                m_processingQueue           = swap;
                m_activeQueue.IsReadingMode = false; //Should do nothing, but just to be sure.

                m_waitForEmptyActiveQueue.Set();
                m_currentTransactionIdRollingOver = m_latestTransactionId;
                m_currentlyRollingOverFullQueue   = m_processingQueue.IsFull;
            }

            //ToDo: The current inner loop for inserting random data is the sorting process here.
            //ToDo:  If the current speed isn't fast enough, this can be multithreaded to improve
            //ToDo:  the insert performance. However, at this time, the added complexity is
            //ToDo:  not worth it since write speeds are already blazing fast.
            try
            {
                m_processingQueue.IsReadingMode = true; //Very CPU intensive. This does a sort on the incoming measurements. Profiling shows that about 33% of the time is spent sorting elements.
                PrebufferRolloverArgs <TKey, TValue> args = new PrebufferRolloverArgs <TKey, TValue>(m_processingQueue, m_currentTransactionIdRollingOver);
                m_onRollover(args);
                m_processingQueue.IsReadingMode = false; //Clears the queue
            }
            catch (Exception ex)
            {
                Log.Publish(MessageLevel.Critical, "Rollover process unhandled exception", "The rollover process threw an unhandled exception. There is likely data loss that will result from this exception", null, ex);
            }
            m_currentlyRollingOverFullQueue = false;
        }
示例#2
0
        private void RolloverTask_Running(object sender, EventArgs <ScheduledTaskRunningReason> e)
        {
            //The worker can be disposed either via the Stop() method or
            //the Dispose() method.  If via the dispose method, then
            //don't do any cleanup.
            if (m_disposed && e.Argument == ScheduledTaskRunningReason.Disposing)
            {
                Log.Publish(MessageLevel.Info, "Rollover thread is Disposing");

                m_rolloverComplete.Dispose();
                return;
            }

            List <SortedTreeTable <TKey, TValue> > pendingTables1;
            List <SortedTreeTable <TKey, TValue> > pendingTables2;
            List <SortedTreeTable <TKey, TValue> > pendingTables3;
            long sequenceNumber;

            lock (m_syncRoot)
            {
                pendingTables1   = m_pendingTables1;
                pendingTables2   = m_pendingTables2;
                pendingTables3   = m_pendingTables3;
                sequenceNumber   = m_lastCommitedSequenceNumber;
                m_pendingTables1 = new List <SortedTreeTable <TKey, TValue> >();
                m_pendingTables2 = new List <SortedTreeTable <TKey, TValue> >();
                m_pendingTables3 = new List <SortedTreeTable <TKey, TValue> >();
                m_rolloverComplete.Set();
            }

            TKey startKey = new TKey();
            TKey endKey   = new TKey();

            startKey.SetMax();
            endKey.SetMin();

            Log.Publish(MessageLevel.Info, "Pending Tables Report", "Pending Tables V1: " + pendingTables1.Count + " V2: " + pendingTables2.Count + " V3: " + pendingTables3.Count);

            List <ArchiveTableSummary <TKey, TValue> > summaryTables = new List <ArchiveTableSummary <TKey, TValue> >();

            foreach (SortedTreeTable <TKey, TValue> table in pendingTables1)
            {
                ArchiveTableSummary <TKey, TValue> summary = new ArchiveTableSummary <TKey, TValue>(table);
                if (!summary.IsEmpty)
                {
                    summaryTables.Add(summary);
                    if (startKey.IsGreaterThan(summary.FirstKey))
                    {
                        summary.FirstKey.CopyTo(startKey);
                    }
                    if (endKey.IsLessThan(summary.LastKey))
                    {
                        summary.LastKey.CopyTo(endKey);
                    }
                }
            }
            foreach (SortedTreeTable <TKey, TValue> table in pendingTables2)
            {
                ArchiveTableSummary <TKey, TValue> summary = new ArchiveTableSummary <TKey, TValue>(table);
                if (!summary.IsEmpty)
                {
                    summaryTables.Add(summary);
                    if (startKey.IsGreaterThan(summary.FirstKey))
                    {
                        summary.FirstKey.CopyTo(startKey);
                    }
                    if (endKey.IsLessThan(summary.LastKey))
                    {
                        summary.LastKey.CopyTo(endKey);
                    }
                }
            }
            foreach (SortedTreeTable <TKey, TValue> table in pendingTables3)
            {
                ArchiveTableSummary <TKey, TValue> summary = new ArchiveTableSummary <TKey, TValue>(table);
                if (!summary.IsEmpty)
                {
                    summaryTables.Add(summary);
                    if (startKey.IsGreaterThan(summary.FirstKey))
                    {
                        summary.FirstKey.CopyTo(startKey);
                    }
                    if (endKey.IsLessThan(summary.LastKey))
                    {
                        summary.LastKey.CopyTo(endKey);
                    }
                }
            }


            long size = summaryTables.Sum(x => x.SortedTreeTable.BaseFile.ArchiveSize);

            if (summaryTables.Count > 0)
            {
                using (UnionTreeStream <TKey, TValue> reader = new UnionTreeStream <TKey, TValue>(summaryTables.Select(x => new ArchiveTreeStreamWrapper <TKey, TValue>(x)), true))
                {
                    SortedTreeTable <TKey, TValue> newTable = m_createNextStageFile.CreateArchiveFile(startKey, endKey, size, reader, null);

                    using (ArchiveListEditor <TKey, TValue> edit = m_list.AcquireEditLock())
                    {
                        //Add the newly created file.
                        edit.Add(newTable);

                        foreach (SortedTreeTable <TKey, TValue> table in pendingTables1)
                        {
                            edit.TryRemoveAndDelete(table.ArchiveId);
                        }

                        foreach (SortedTreeTable <TKey, TValue> table in pendingTables2)
                        {
                            edit.TryRemoveAndDelete(table.ArchiveId);
                        }


                        foreach (SortedTreeTable <TKey, TValue> table in pendingTables3)
                        {
                            edit.TryRemoveAndDelete(table.ArchiveId);
                        }
                    }
                }
            }

            m_lastRolledOverSequenceNumber.Value = sequenceNumber;

            if (RolloverComplete != null)
            {
                RolloverComplete(sequenceNumber);
            }
        }