2
0
mirror of synced 2025-02-03 04:03:39 +00:00
cs-codex-dist-tests/SeeTimeline/MainWindow.xaml.cs
2024-12-19 12:10:37 +01:00

200 lines
6.9 KiB
C#

using CodexPlugin;
using Microsoft.Win32;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using TimelinerNet;
namespace SeeTimeline
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Timeliner1.PropertyChanged += Timeliner1_PropertyChanged;
}
private void Timeliner1_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{
Timeliner2.LeftEdge = Timeliner1.LeftEdge;
Timeliner2.RightEdge = Timeliner1.RightEdge;
}
private TimelinerData CreateTimelineData(string logfile, DateTime now)
{
var lines = File.ReadAllLines(logfile);
var handler = new LogLineHandler(now);
foreach (var line in lines)
{
var cline = CodexLogLine.Parse(line);
if (cline != null)
{
handler.Handle(cline);
if (handler.Size > 20) break;
}
}
return handler.GetTimeline();
}
public class LogLineHandler
{
public class BlockReq
{
public string Address { get; set; } = string.Empty;
public DateTime Created { get; set; }
public DateTime[] WantHaveSent { get; set; } = Array.Empty<DateTime>();
public DateTime[] PresenceRecv{ get; set; } = Array.Empty<DateTime>();
public DateTime[] WantBlkSent { get; set; } = Array.Empty<DateTime>();
public DateTime[] BlkRecv { get; set; } = Array.Empty<DateTime>();
public DateTime[] CancelSent { get; set; } = Array.Empty<DateTime>();
public DateTime[] Resolve { get; set; } = Array.Empty<DateTime>();
}
private readonly List<BlockReq> requests = new List<BlockReq>();
private readonly DateTime now;
private long? zero;
public int Size => requests.Count;
public LogLineHandler(DateTime now)
{
this.now = now;
}
public void Handle(CodexLogLine line)
{
if (line.Message != "times for") return;
var addr = line.Attributes["addrs"];
if (!addr.Contains("index")) return;
// addrs="treeCid: zDz*qNvVWp, index: 0"
// reqCreatedTime=4784825696831
// wantHaveSentTimes=@[4784825884225]
// presenceRecvTimes=@[4784826770921]
// wantBlkSentTimes=@[4784826954293]
// blkRecvTimes=@[4784829724756]
// cancelSentTimes=@[4784830399255]
// resolveTimes=@[4784830322141]
var req = new BlockReq
{
Address = line.Attributes["addrs"],
Created = ToUtc(line.Attributes["reqCreatedTime"]),
WantHaveSent = ToUtcs(line.Attributes["wantHaveSentTimes"]),
PresenceRecv = ToUtcs(line.Attributes["presenceRecvTimes"]),
WantBlkSent = ToUtcs(line.Attributes["wantBlkSentTimes"]),
BlkRecv = ToUtcs(line.Attributes["blkRecvTimes"]),
CancelSent = ToUtcs(line.Attributes["cancelSentTimes"]),
Resolve = ToUtcs(line.Attributes["resolveTimes"])
};
requests.Add(req);
}
private DateTime[] ToUtcs(string str)
{
var tokens = str.Split(",");
return tokens
.Select(t => t
.Replace(" ", "")
.Replace("@[", "")
.Replace("]", "")
).Select(t => ToUtc(t)).ToArray();
}
private DateTime ToUtc(string str)
{
// is nanoseconds from arbitrary time point.
var monotime = Convert.ToInt64(str);
if (!zero.HasValue) zero = monotime;
double deltaNanoseconds = (monotime - zero.Value);
var delta = deltaNanoseconds / (1000 * 1000);
return now + TimeSpan.FromSeconds(delta * 5.0);
}
public TimelinerData GetTimeline()
{
return new TimelinerData
{
Items = requests.Select(ToTimelineItem).ToList()
};
}
private TimelinerItem ToTimelineItem(BlockReq req)
{
return new TimelinerItem
{
Name = req.Address,
Jobs = CreateTimelineJobs(req)
};
}
private List<TimelinerJob> CreateTimelineJobs(BlockReq req)
{
var result = new List<TimelinerJob>();
AddJobs(result, "Created", Colors.Red, req.Created);
AddJobs(result, "WantHaveSent", Colors.Orange, req.WantHaveSent);
AddJobs(result, "PresenceRecv", Colors.Yellow, req.PresenceRecv);
AddJobs(result, "WantBlkSent", Colors.Green, req.WantBlkSent);
AddJobs(result, "BlkRecv", Colors.Blue, req.BlkRecv);
AddJobs(result, "CancelSent", Colors.Purple, req.CancelSent);
AddJobs(result, "Resolve", Colors.Pink, req.Resolve);
return result;
}
private void AddJobs(List<TimelinerJob> result, string name, Color color, params DateTime[] moments)
{
var i = 0;
foreach (var dt in moments)
{
result.Add(new TimelinerJob
{
Name = name + i.ToString(),
Begin = dt,
End = dt,
Color = new SolidColorBrush(color),
});
i++;
}
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var now = DateTime.Now;
var dlg = new OpenFileDialog();
if (dlg.ShowDialog() != true) return;
var file1 = dlg.FileName;
Line1Name.Text = file1;
if (dlg.ShowDialog() != true) return;
var file2 = dlg.FileName;
Line2Name.Text = file2;
var data1 = CreateTimelineData(file1, now);
var data2 = CreateTimelineData(file2, now);
Timeliner1.Data = data1;
Timeliner2.Data = data2;
}
}
}