enhance: improve QueryCommits performance

This commit is contained in:
leo 2024-06-06 20:25:16 +08:00
parent 1a18235a76
commit 064d04fccc
No known key found for this signature in database
GPG key ID: B528468E49CD0E58
7 changed files with 72 additions and 64 deletions

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SourceGit.Commands
{
@ -31,15 +32,14 @@ namespace SourceGit.Commands
{
case 0:
_current = new Models.Commit() { SHA = line };
_isSubjectSet = false;
_commits.Add(_current);
break;
case 1:
if (!string.IsNullOrEmpty(line))
_current.Parents.AddRange(line.Split(' ', StringSplitOptions.RemoveEmptyEntries));
ParseParent(line);
break;
case 2:
if (!string.IsNullOrEmpty(line))
ParseDecorators(line);
ParseDecorators(line);
break;
case 3:
_current.Author = Models.User.FindOrAdd(line);
@ -57,15 +57,17 @@ namespace SourceGit.Commands
if (line.Equals(_endOfBodyToken, StringComparison.Ordinal))
{
_nextPartIdx = 0;
if (!string.IsNullOrEmpty(_current.Message))
_current.Message = _current.Message.Trim();
_current.Message = _messageReader.ToString().Trim();
_messageReader.Clear();
}
else if (!_isSubjectSet)
{
_isSubjectSet = true;
_current.Subject = line;
}
else
{
if (string.IsNullOrEmpty(_current.Subject))
_current.Subject = line;
else
_current.Message += (line + "\n");
_messageReader.AppendLine(line);
}
return;
}
@ -73,8 +75,27 @@ namespace SourceGit.Commands
_nextPartIdx++;
}
private void ParseParent(string data)
{
if (data.Length < 8)
return;
var idx = data.IndexOf(' ', StringComparison.Ordinal);
if (idx == -1)
{
_current.Parents.Add(data);
return;
}
_current.Parents.Add(data.Substring(0, idx));
_current.Parents.Add(data.Substring(idx + 1));
}
private void ParseDecorators(string data)
{
if (data.Length < 3)
return;
var subs = data.Split(',', StringSplitOptions.RemoveEmptyEntries);
foreach (var sub in subs)
{
@ -172,5 +193,7 @@ namespace SourceGit.Commands
private bool _isHeadFounded = false;
private readonly bool _findFirstMerged = true;
private int _nextPartIdx = 0;
private bool _isSubjectSet = false;
private StringBuilder _messageReader = new StringBuilder();
}
}

View file

@ -2,11 +2,23 @@
using System.Collections.Generic;
using Avalonia;
using Avalonia.Media;
namespace SourceGit.Models
{
public class CommitGraph
{
public static readonly Pen[] Pens = [
new Pen(Brushes.Orange, 2),
new Pen(Brushes.ForestGreen, 2),
new Pen(Brushes.Gold, 2),
new Pen(Brushes.Magenta, 2),
new Pen(Brushes.Red, 2),
new Pen(Brushes.Gray, 2),
new Pen(Brushes.Turquoise, 2),
new Pen(Brushes.Olive, 2),
];
public class Path
{
public List<Point> Points = new List<Point>();
@ -101,12 +113,12 @@ namespace SourceGit.Models
public List<Link> Links { get; set; } = new List<Link>();
public List<Dot> Dots { get; set; } = new List<Dot>();
public static CommitGraph Parse(List<Commit> commits, double rowHeight, int colorCount)
public static CommitGraph Parse(List<Commit> commits, int colorCount)
{
double UNIT_WIDTH = 12;
double HALF_WIDTH = 6;
double UNIT_HEIGHT = rowHeight;
double HALF_HEIGHT = rowHeight / 2;
double UNIT_HEIGHT = 28;
double HALF_HEIGHT = 14;
var temp = new CommitGraph();
var unsolved = new List<PathHelper>();

View file

@ -1,11 +1,9 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Platform.Storage;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
@ -24,38 +22,16 @@ namespace SourceGit.ViewModels
set => SetProperty(ref _isLoading, value);
}
public double DataGridRowHeight
{
get => _dataGridRowHeight;
}
public List<Models.Commit> Commits
{
get => _commits;
set
{
var oldAutoSelectedCommitSHA = AutoSelectedCommit?.SHA;
var lastSelected = AutoSelectedCommit;
if (SetProperty(ref _commits, value))
{
Models.Commit newSelectedCommit = null;
if (value.Count > 0 && oldAutoSelectedCommitSHA != null)
{
newSelectedCommit = value.Find(x => x.SHA == oldAutoSelectedCommitSHA);
}
if (newSelectedCommit != AutoSelectedCommit)
{
AutoSelectedCommit = newSelectedCommit;
}
Graph = null;
Task.Run(() =>
{
var graph = Models.CommitGraph.Parse(value, DataGridRowHeight, 8);
Dispatcher.UIThread.Invoke(() =>
{
Graph = graph;
});
});
if (value.Count > 0 && lastSelected != null)
AutoSelectedCommit = value.Find(x => x.SHA == lastSelected.SHA);
}
}
}
@ -652,7 +628,6 @@ namespace SourceGit.ViewModels
}
private Repository _repo = null;
private readonly double _dataGridRowHeight = 28;
private bool _isLoading = true;
private List<Models.Commit> _commits = new List<Models.Commit>();
private Models.CommitGraph _graph = null;

View file

@ -606,12 +606,15 @@ namespace SourceGit.ViewModels
}
var commits = new Commands.QueryCommits(FullPath, limits).Result();
var graph = Models.CommitGraph.Parse(commits, 8);
Dispatcher.UIThread.Invoke(() =>
{
if (_histories != null)
{
_histories.IsLoading = false;
_histories.Commits = commits;
_histories.Graph = graph;
}
});
}

View file

@ -23,7 +23,7 @@
IsReadOnly="True"
HeadersVisibility="None"
Focusable="False"
RowHeight="{Binding DataGridRowHeight}"
RowHeight="28"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto"
LayoutUpdated="OnCommitDataGridLayoutUpdated"

View file

@ -69,17 +69,6 @@ namespace SourceGit.Views
public class CommitGraph : Control
{
public static readonly Pen[] Pens = [
new Pen(Brushes.Orange, 2),
new Pen(Brushes.ForestGreen, 2),
new Pen(Brushes.Gold, 2),
new Pen(Brushes.Magenta, 2),
new Pen(Brushes.Red, 2),
new Pen(Brushes.Gray, 2),
new Pen(Brushes.Turquoise, 2),
new Pen(Brushes.Olive, 2),
];
public static readonly StyledProperty<Models.CommitGraph> GraphProperty =
AvaloniaProperty.Register<CommitGraph, Models.CommitGraph>(nameof(Graph));
@ -151,7 +140,7 @@ namespace SourceGit.Views
if (dot.Center.Y > bottom)
break;
context.DrawEllipse(dotFill, Pens[dot.Color], dot.Center, 3, 3);
context.DrawEllipse(dotFill, Models.CommitGraph.Pens[dot.Color], dot.Center, 3, 3);
}
}
@ -168,7 +157,7 @@ namespace SourceGit.Views
continue;
var geo = new StreamGeometry();
var pen = Pens[line.Color];
var pen = Models.CommitGraph.Pens[line.Color];
using (var ctx = geo.Open())
{
var started = false;
@ -238,7 +227,7 @@ namespace SourceGit.Views
ctx.QuadraticBezierTo(link.Control, link.End);
}
context.DrawGeometry(null, Pens[link.Color], geo);
context.DrawGeometry(null, Models.CommitGraph.Pens[link.Color], geo);
}
}
}

View file

@ -1166,25 +1166,31 @@ namespace SourceGit.Views
{
base.OnPropertyChanged(change);
var data = TextDiff;
if (data == null)
{
Content = null;
SyncScrollOffset = Vector.Zero;
return;
}
if (change.Property == TextDiffProperty)
{
if (TextDiff == null)
Content = null;
else if (UseSideBySideDiff)
if (UseSideBySideDiff)
Content = new ViewModels.TwoSideTextDiff(TextDiff);
else
Content = TextDiff;
SetCurrentValue(SyncScrollOffsetProperty, TextDiff.SyncScrollOffset);
}
else if (change.Property == UseSideBySideDiffProperty)
{
SyncScrollOffset = Vector.Zero;
if (TextDiff == null)
Content = null;
else if (UseSideBySideDiff)
if (UseSideBySideDiff)
Content = new ViewModels.TwoSideTextDiff(TextDiff);
else
Content = TextDiff;
SetCurrentValue(SyncScrollOffsetProperty, Vector.Zero);
}
}