internal static PipRuntimeTimeTable Load(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 PipRuntimeTimeTable(initialCapacity: size); for (int i = 0; i < size; ++i) { long semiStableHash = reader.ReadInt64(); PipHistoricPerfData historicData; if (PipHistoricPerfData.Deserialize(reader, out historicData)) { if (!table.m_runtimeData.TryAdd(semiStableHash, historicData)) { throw new BuildXLException("Corrupted file has duplicate records"); } } } return table; } }, ex => { throw new BuildXLException("Reading of file failed", ex); }); }
internal static Task <PipRuntimeTimeTable> LoadAsync(Stream fileStream) { return(ExceptionUtilities.HandleRecoverableIOExceptionAsync( async() => { int size = await ReadFileFormatMarkerAsync(fileStream); var table = new PipRuntimeTimeTable(LoggingContext); using (BuildXLReader reader = new BuildXLReader(false, fileStream, true)) { for (int i = 0; i < size; ++i) { long semiStableHash = reader.ReadInt64(); PipHistoricPerfData historicData; if (PipHistoricPerfData.Deserialize(reader, out historicData)) { if (!table.m_runtimeData.TryAdd(semiStableHash, historicData)) { throw new BuildXLException("Corrupted file has duplicate records"); } } } } if (fileStream.Position != fileStream.Length) { throw new BuildXLException("Corrupted file has excess bytes"); } return table; }, ex => { throw new BuildXLException("Reading of file failed", ex); })); }
/// <summary> /// Access the runtime data /// </summary> public PipHistoricPerfData this[long semiStableHash] { get { PipHistoricPerfData ret; if (m_runtimeData.TryGetValue(semiStableHash, out ret)) { Interlocked.Increment(ref m_numHits); if (ret.IsFresh) { return ret; } PipHistoricPerfData freshRet = ret.MakeFresh(); m_runtimeData[semiStableHash] = freshRet; return freshRet; } else { Interlocked.Increment(ref m_numMisses); return default(PipHistoricPerfData); } } set { var result = m_runtimeData.AddOrUpdate( semiStableHash, value, (key, val) => val, (key, val, oldValue) => val.Merge(oldValue)); if (result.IsFound) { uint oldMilliseconds = result.OldItem.Value.DurationInMs; uint milliseconds = value.DurationInMs; var difference = milliseconds > oldMilliseconds ? milliseconds - oldMilliseconds : oldMilliseconds - milliseconds; var relativeDeviation = (int)(difference * 100 / Math.Max(milliseconds, oldMilliseconds)); Interlocked.Add(ref m_sumRelativeRunningTimeDeviation, relativeDeviation); Interlocked.Increment(ref m_numRunningTimeUpdated); Tracing.Logger.Log.RunningTimeUpdated(Events.StaticContext, semiStableHash, milliseconds, oldMilliseconds, relativeDeviation); } else { Interlocked.Increment(ref m_numRunningTimeAdded); Tracing.Logger.Log.RunningTimeAdded(Events.StaticContext, semiStableHash, value.DurationInMs); } } }