/// <summary>
        /// 返回上一步操作
        /// </summary>
        /// <typeparam name="T">需要接受的数据对象类型</typeparam>
        /// <param name="refadd">需要接受的数据对象引用</param>
        public void Previous <T>(out T refadd) where T : class, new()
        {
            Transaction tran = _tranStack.Pop();

            if (tran == null)//顶层事务
            {
                Transaction.Current.Rollback();
            }
            // tran.Rollback();//回滚本事务,将触发所有克隆事务的回滚。
            if (PreviousEvent != null)
            {
                if (PreviousEvent.GetInvocationList().Length > 0)
                {
                    //设置上一步数据对象
                    refadd = (_resourceStack.Pop() as IReversibleGetResourceData <T>).GetPreviousData();
                    PreviousEvent(Transaction.Current);
                    return;
                }
            }
            refadd = new T();//事务处理异常
        }
Example #2
0
        void InitializeFromPrimary()
        {
            atomsFields     = new ByteAtomTable();
            atomsRecords    = new ByteAtomTable();
            atomsProcesses  = new ByteAtomTable();
            listEventFields = new List <List <int> >();

            byte[] byRecordEscape = ByteWindow.MakeBytes("$R");
            idRecordEscape = atomsFields.EnsureContains(byRecordEscape);

            byte[] byTimeEscape = ByteWindow.MakeBytes("$T");
            idTimeEscape = atomsFields.EnsureContains(byTimeEscape);

            byte[] byTimeOffsetEscape = ByteWindow.MakeBytes("$TimeOffset");
            idTimeOffsetEscape = atomsFields.EnsureContains(byTimeOffsetEscape);

            byte[] byWhenEscape = ByteWindow.MakeBytes("$When");
            idWhenEscape = atomsFields.EnsureContains(byWhenEscape);

            byte[] byFirstEscape = ByteWindow.MakeBytes("$First");
            idFirstEscape = atomsFields.EnsureContains(byFirstEscape);

            byte[] byLastEscape = ByteWindow.MakeBytes("$Last");
            idLastEscape = atomsFields.EnsureContains(byLastEscape);

            byte[] byBeginHeader = ByteWindow.MakeBytes("BeginHeader");
            byte[] byEndHeader   = ByteWindow.MakeBytes("EndHeader");

            ByteWindow b = new ByteWindow();

            threads.Clear();
            offsets.Clear();

            while (stm.ReadLine(b))
            {
                if (b.StartsWith(byBeginHeader))
                {
                    break;
                }
            }

            while (stm.ReadLine(b))
            {
                if (b.StartsWith(byEndHeader))
                {
                    break;
                }

                b.Field(0).Trim();

                int iCountBefore = atomsRecords.Count;
                atomsRecords.EnsureContains(b);
                if (atomsRecords.Count == iCountBefore)
                {
                    continue;
                }

                List <int> listFields = new List <int>();
                listEventFields.Add(listFields);

                listFields.Add(0); // the ID for $R, the record escape field

                // start from field 1 -- that skips only field 0 which is already mapped to $R
                for (int i = 1; i < b.fieldsLen; i++)
                {
                    b.Field(i).Trim();
                    int id = atomsFields.EnsureContains(b);
                    listFields.Add(id);
                }
            }

            stackIgnoreEvents = new bool[atomsRecords.Count];

            foreach (string strEvent in stackIgnoreEventStrings)
            {
                int id = atomsRecords.Lookup(strEvent);
                if (id >= 0)
                {
                    stackIgnoreEvents[id] = true;
                }
            }

            recordInfo = new RecordInfo[atomsRecords.Count];

            int idThreadField      = atomsFields.Lookup("ThreadID");
            int idFileNameField    = atomsFields.Lookup("FileName");
            int idTypeField        = atomsFields.Lookup("Type");
            int idSizeField        = atomsFields.Lookup("Size");
            int idIOSizeField      = atomsFields.Lookup("IOSize");
            int idElapsedTimeField = atomsFields.Lookup("ElapsedTime");

            for (int i = 0; i < recordInfo.Length; i++)
            {
                List <int> fieldList = listEventFields[i];
                recordInfo[i].threadField = fieldList.IndexOf(idThreadField);
                recordInfo[i].sizeField   = fieldList.IndexOf(idSizeField);

                if (-1 == recordInfo[i].sizeField)
                {
                    recordInfo[i].sizeField = fieldList.IndexOf(idIOSizeField);
                }

                recordInfo[i].goodNameField = fieldList.IndexOf(idFileNameField);
                if (-1 == recordInfo[i].goodNameField)
                {
                    recordInfo[i].goodNameField = fieldList.IndexOf(idTypeField);
                }

                recordInfo[i].elapsedTimeField = fieldList.IndexOf(idElapsedTimeField);
            }

            int idT_DCEnd   = atomsRecords.Lookup("T-DCEnd");
            int idT_DCStart = atomsRecords.Lookup("T-DCStart");
            int idT_Start   = atomsRecords.Lookup("T-Start");
            int idT_End     = atomsRecords.Lookup("T-End");
            int idCSwitch   = atomsRecords.Lookup("CSwitch");
            int idStack     = atomsRecords.Lookup("Stack");
            int idAlloc     = atomsRecords.Lookup("Allocation");

            int idFirstReliableEventTimeStamp        = atomsRecords.Lookup("FirstReliableEventTimeStamp");
            int idFirstReliableCSwitchEventTimeStamp = atomsRecords.Lookup("FirstReliableCSwitchEventTimeStamp");

            long tNext = 100000;
            long t     = 0;

            // seed offsets for the 0th record
            offsets.Add(stm.Position);

            listInitialTime = new List <TimeMark>();

            maxCPU = 64;
            CPUState[] state = new CPUState[maxCPU];

            const int maxEvent = 16;

            PreviousEvent[] prev       = new PreviousEvent[maxEvent];
            int             iNextEvent = 0;

            stackTypes = new bool[atomsRecords.Count];

            Dictionary <int, int> dictStartedThreads = new Dictionary <int, int>();

            ByteWindow record      = new ByteWindow();
            ByteWindow bThreadProc = new ByteWindow();
            ByteWindow bProcess    = new ByteWindow();

            // the first line of the trace is the trace info, that, importantly, has the OSVersion tag
            if (stm.ReadLine(b))
            {
                traceinfo = b.GetString();
            }
            else
            {
                traceinfo = "None";
            }

            while (stm.ReadLine(b))
            {
                if (b.len < typeLen)
                {
                    continue;
                }

                record.Assign(b, 0).Trim();
                int idrec = atomsRecords.Lookup(record);

                if (idrec < 0)
                {
                    continue;
                }

                if (idrec == idFirstReliableCSwitchEventTimeStamp ||
                    idrec == idFirstReliableEventTimeStamp)
                {
                    continue;
                }

                recordInfo[idrec].count++;

                t = b.GetLong(1);
                while (t >= tNext)
                {
                    tNext = AddTimeRow(tNext, state);
                }

                if (idrec != idStack && !stackIgnoreEvents[idrec])
                {
                    prev[iNextEvent].time    = t;
                    prev[iNextEvent].eventId = idrec;
                    iNextEvent = (iNextEvent + 1) % maxEvent;
                }

                if (idrec == idStack)
                {
                    int i = iNextEvent;
                    for (; ;)
                    {
                        if (--i < 0)
                        {
                            i = maxEvent - 1;
                        }

                        if (i == iNextEvent)
                        {
                            break;
                        }

                        if (prev[i].time == t)
                        {
                            stackTypes[prev[i].eventId] = true;
                            break;
                        }
                    }
                }
                else if (idrec == idT_Start ||
                         idrec == idT_End ||
                         idrec == idT_DCStart ||
                         idrec == idT_DCEnd)
                {
                    ThreadInfo ti = new ThreadInfo();

                    ti.threadid = b.GetInt(fldTStartThreadId);

                    bool fStarted = dictStartedThreads.ContainsKey(ti.threadid);

                    if (idrec == idT_Start)
                    {
                        ti.timestamp = t;
                    }
                    else if (idrec == idT_DCStart)
                    {
                        ti.timestamp = 0;
                    }
                    else
                    {
                        if (fStarted)
                        {
                            continue;
                        }

                        ti.timestamp = 0;
                    }

                    if (!fStarted)
                    {
                        dictStartedThreads.Add(ti.threadid, 0);
                    }

                    bThreadProc.Assign(b, fldTStartThreadProc).Trim();
                    bProcess.Assign(b, fldTStartProcess).Trim();

                    ti.processPid = bProcess.Clone();

                    if (atomsProcesses.Lookup(bProcess) == -1)
                    {
                        atomsProcesses.EnsureContains(ti.processPid);
                        ProcessInfo pi = new ProcessInfo();
                        pi.processPid = ti.processPid;
                        processes.Add(pi);
                    }

                    bProcess.Truncate((byte)'(').Trim();

                    ti.processNopid = bProcess.Clone();
                    ti.threadproc   = bThreadProc.Clone();

                    threads.Add(ti);
                }
                else if (idrec == idCSwitch)
                {
                    int newTid = b.GetInt(fldCSwitchNewTID);
                    int oldTid = b.GetInt(fldCSwitchOldTID);
                    int cpu    = b.GetInt(fldCSwitchCPU);

                    if (cpu < 0 || cpu > state.Length)
                    {
                        continue;
                    }

                    int tusage = (int)(t - state[cpu].time);

                    if (state[cpu].tid != 0 && tusage > 0)
                    {
                        state[cpu].usage += tusage;
                    }

                    state[cpu].time   = t;
                    state[cpu].tid    = newTid;
                    state[cpu].active = true;
                }
            }

            AddTimeRow(t, state);

            threads.Sort();
            int tid = -1;

            mp_tid_firstindex = new Dictionary <int, int>();

            for (int i = 0; i < threads.Count; i++)
            {
                if (tid != threads[i].threadid)
                {
                    tid = threads[i].threadid;
                    mp_tid_firstindex.Add(tid, i);
                }
            }

            sortedThreads = new int[threads.Count];
            for (int i = 0; i < sortedThreads.Length; i++)
            {
                sortedThreads[i] = i;
            }

            Array.Sort(sortedThreads,
                       delegate(int id1, int id2)
            {
                byte[] b1 = threads[id1].processPid;
                byte[] b2 = threads[id2].processPid;

                int cmp = ByteWindow.CompareBytes(b1, b2, true);
                if (cmp != 0)
                {
                    return(cmp);
                }

                if (threads[id1].threadid < threads[id2].threadid)
                {
                    return(-1);
                }

                if (threads[id1].threadid > threads[id2].threadid)
                {
                    return(1);
                }

                return(0);
            }
                       );


            sortedProcesses = new int[processes.Count];
            for (int i = 0; i < sortedProcesses.Length; i++)
            {
                sortedProcesses[i] = i;
            }

            Array.Sort(sortedProcesses,
                       delegate(int id1, int id2)
            {
                byte[] b1 = processes[id1].processPid;
                byte[] b2 = processes[id2].processPid;

                return(ByteWindow.CompareBytes(b1, b2, true));
            }
                       );

            tmax = t;

            TrySaveState();
        }