private static void Save(string fileName) { int profiledFuncsCount; OuterHeader outerHeader = new OuterHeader(); outerHeader.Magic = _outerHeaderMagic; outerHeader.InfoFileVersion = InternalVersion; outerHeader.Endianness = Ptc.GetEndianness(); outerHeader.SetHeaderHash(); using (MemoryStream stream = new MemoryStream()) { Debug.Assert(stream.Seek(0L, SeekOrigin.Begin) == 0L && stream.Length == 0L); stream.Seek((long)Unsafe.SizeOf <Hash128>(), SeekOrigin.Begin); lock (_lock) { Serialize(stream, ProfiledFuncs); profiledFuncsCount = ProfiledFuncs.Count; } Debug.Assert(stream.Position == stream.Length); stream.Seek((long)Unsafe.SizeOf <Hash128>(), SeekOrigin.Begin); Hash128 hash = XXHash128.ComputeHash(GetReadOnlySpan(stream)); stream.Seek(0L, SeekOrigin.Begin); SerializeStructure(stream, hash); if (hash == _lastHash) { return; } using (FileStream compressedStream = new(fileName, FileMode.OpenOrCreate)) using (DeflateStream deflateStream = new(compressedStream, SaveCompressionLevel, true)) { try { SerializeStructure(compressedStream, outerHeader); stream.WriteTo(deflateStream); _lastHash = hash; } catch { compressedStream.Position = 0L; _lastHash = default; } if (compressedStream.Position < compressedStream.Length) { compressedStream.SetLength(compressedStream.Position); } } } long fileSize = new FileInfo(fileName).Length; if (fileSize != 0L) { Logger.Info?.Print(LogClass.Ptc, $"Saved Profiling Info (size: {fileSize} bytes, profiled functions: {profiledFuncsCount})."); } }
private static bool Load(string fileName, bool isBackup) { using (FileStream compressedStream = new(fileName, FileMode.Open)) using (DeflateStream deflateStream = new(compressedStream, CompressionMode.Decompress, true)) { OuterHeader outerHeader = DeserializeStructure <OuterHeader>(compressedStream); if (!outerHeader.IsHeaderValid()) { InvalidateCompressedStream(compressedStream); return(false); } if (outerHeader.Magic != _outerHeaderMagic) { InvalidateCompressedStream(compressedStream); return(false); } if (outerHeader.InfoFileVersion != InternalVersion) { InvalidateCompressedStream(compressedStream); return(false); } if (outerHeader.Endianness != Ptc.GetEndianness()) { InvalidateCompressedStream(compressedStream); return(false); } using (MemoryStream stream = new MemoryStream()) { Debug.Assert(stream.Seek(0L, SeekOrigin.Begin) == 0L && stream.Length == 0L); try { deflateStream.CopyTo(stream); } catch { InvalidateCompressedStream(compressedStream); return(false); } Debug.Assert(stream.Position == stream.Length); stream.Seek(0L, SeekOrigin.Begin); Hash128 expectedHash = DeserializeStructure <Hash128>(stream); Hash128 actualHash = XXHash128.ComputeHash(GetReadOnlySpan(stream)); if (actualHash != expectedHash) { InvalidateCompressedStream(compressedStream); return(false); } ProfiledFuncs = Deserialize(stream); Debug.Assert(stream.Position == stream.Length); _lastHash = actualHash; } } long fileSize = new FileInfo(fileName).Length; Logger.Info?.Print(LogClass.Ptc, $"{(isBackup ? "Loaded Backup Profiling Info" : "Loaded Profiling Info")} (size: {fileSize} bytes, profiled functions: {ProfiledFuncs.Count})."); return(true); }