internal static HistoricPerfDataTable Load(LoggingContext loggingContext, Stream stream) { return(ExceptionUtilities.HandleRecoverableIOException( () => { Analysis.IgnoreResult(FileEnvelope.ReadHeader(stream)); using (BuildXLReader reader = new BuildXLReader(debug: false, stream: stream, leaveOpen: true)) { int size = reader.ReadInt32(); var table = new HistoricPerfDataTable(loggingContext, initialCapacity: size); for (int i = 0; i < size; ++i) { long semiStableHash = reader.ReadInt64(); ProcessPipHistoricPerfData historicData; if (ProcessPipHistoricPerfData.Deserialize(reader, out historicData)) { if (!table.m_table.TryAdd(semiStableHash, historicData)) { throw new BuildXLException("Corrupted file has duplicate records"); } } } return table; } }, ex => { throw new BuildXLException("Reading of file failed", ex); })); }
/// <summary> /// Access the runtime data /// </summary> public ProcessPipHistoricPerfData this[long semiStableHash] { get { ProcessPipHistoricPerfData ret; if (m_table.TryGetValue(semiStableHash, out ret)) { Interlocked.Increment(ref m_numHits); if (ret.IsFresh) { return(ret); } ProcessPipHistoricPerfData freshRet = ret.MakeFresh(); m_table[semiStableHash] = freshRet; return(freshRet); } else { Interlocked.Increment(ref m_numMisses); return(default(ProcessPipHistoricPerfData)); } } set { var result = m_table.AddOrUpdate( semiStableHash, value, (key, val) => val, (key, val, oldValue) => val.Merge(oldValue)); if (result.IsFound) { uint oldMilliseconds = result.OldItem.Value.DurationInMs; uint milliseconds = Math.Max(value.DurationInMs, 1); var difference = milliseconds > oldMilliseconds ? milliseconds - oldMilliseconds : oldMilliseconds - milliseconds; long relativeDeviation = (long)(difference * (100.0 / Math.Max(milliseconds, oldMilliseconds))); Interlocked.Add(ref m_sumRelativeRunningTimeDeviation, relativeDeviation); Interlocked.Increment(ref m_numRunningTimeUpdated); Tracing.Logger.Log.HistoricPerfDataUpdated(m_loggingContext, semiStableHash, milliseconds, oldMilliseconds, relativeDeviation); } else { Interlocked.Increment(ref m_numRunningTimeAdded); Tracing.Logger.Log.HistoricPerfDataAdded(m_loggingContext, semiStableHash, value.DurationInMs); } } }