Skip to content

Commit

Permalink
Added a few more performance optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
jschick04 authored and bill-long committed Dec 2, 2024
1 parent c60e3c0 commit 2ba7da7
Show file tree
Hide file tree
Showing 16 changed files with 88 additions and 82 deletions.
6 changes: 3 additions & 3 deletions src/EventLogExpert.EventDbTool/DbToolCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ public static void LogProviderDetails(ProviderDetails details)
Console.WriteLine(
s_providerDetailFormat,
details.ProviderName,
details.Events.Count,
details.Parameters.Count,
details.Events.Count(),
details.Parameters.Count(),
details.Keywords.Count,
details.Opcodes.Count,
details.Tasks.Count,
details.Messages.Count);
details.Messages.Count());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void EventResolver_MSExchangeReplId4114_ShouldResolve()
var providerDetails = new ProviderDetails
{
Events = [],
Keywords = [],
Keywords = new Dictionary<long, string>(),
Messages =
[
new MessageModel
Expand All @@ -66,7 +66,7 @@ public void EventResolver_MSExchangeReplId4114_ShouldResolve()
Text = "Database redundancy health check passed.%nDatabase copy: %1%nRedundancy count: %2%nIsSuppressed: %4%n%nErrors:%n%3\r\n"
}
],
Opcodes = [],
Opcodes = new Dictionary<int, string>(),
ProviderName = "MSExchangeRepl",
Tasks = new Dictionary<int, string>
{
Expand Down
44 changes: 28 additions & 16 deletions src/EventLogExpert.Eventing/EventResolvers/EventResolverBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using System.Collections.Concurrent;
using System.Security.Principal;
using System.Text.RegularExpressions;
using System.Xml.Linq;

namespace EventLogExpert.Eventing.EventResolvers;

Expand Down Expand Up @@ -77,7 +76,7 @@ public DisplayEventModel ResolveEvent(EventRecord eventRecord) =>
Xml = eventRecord.Xml ?? string.Empty
};

private static ReadOnlySpan<char> CleanupFormatting(string unformattedString)
private static string CleanupFormatting(ReadOnlySpan<char> unformattedString)
{
Span<char> buffer = stackalloc char[unformattedString.Length * 2];
int bufferIndex = 0;
Expand Down Expand Up @@ -136,24 +135,38 @@ private static ReadOnlySpan<char> CleanupFormatting(string unformattedString)
}
}

return new ReadOnlySpan<char>(buffer[..bufferIndex].ToArray());
return new string(buffer[..bufferIndex]);
}

private static List<string> GetFormattedProperties(string? template, IEnumerable<object> properties)
private static List<string> GetFormattedProperties(ReadOnlySpan<char> template, IEnumerable<object> properties)
{
string[]? dataNodes = null;
List<string> providers = [];

if (!string.IsNullOrEmpty(template) && !s_formattedPropertiesCache.TryGetValue(template, out dataNodes))
var cache = s_formattedPropertiesCache.GetAlternateLookup<ReadOnlySpan<char>>();

if (!template.IsEmpty && !cache.TryGetValue(template, out dataNodes))
{
dataNodes = XElement.Parse(template)
.Descendants()
.Attributes()
.Where(a => a.Name == "outType")
.Select(a => a.Value)
.ToArray();

s_formattedPropertiesCache.TryAdd(template, dataNodes);
List<string> temp = [];
ReadOnlySpan<char> outTypeAttribute = "outType=\"";

foreach (var line in template.EnumerateLines())
{
int templateIndex = line.IndexOf(outTypeAttribute, StringComparison.Ordinal);

if (templateIndex == -1) { continue; }

templateIndex += outTypeAttribute.Length;
int endIndex = line[templateIndex..].IndexOf('"');

if (endIndex != -1)
{
temp.Add(new string(line.Slice(templateIndex, endIndex)));
}
}

dataNodes = [.. temp];
cache.TryAdd(template, dataNodes);
}

int index = 0;
Expand Down Expand Up @@ -240,10 +253,9 @@ private static void ResizeBuffer(ref char[] buffer, ref Span<char> source, int s
private string FormatDescription(
List<string> properties,
string? descriptionTemplate,
List<MessageModel> parameters)
IEnumerable<MessageModel> parameters)
{
string returnDescription;

if (string.IsNullOrWhiteSpace(descriptionTemplate))
{
// If there is only one property then this is what certain EventRecords look like
Expand Down Expand Up @@ -297,7 +309,7 @@ private string FormatDescription(
propString = properties[propIndex - 1];
}

if (propString.StartsWith("%%") && parameters.Count > 0)
if (propString.StartsWith("%%") && parameters.Any())
{
int endParameterId = propString.IndexOf(' ');
var parameterIdString = endParameterId > 2 ? propString.Slice(2, endParameterId) : propString[2..];
Expand Down
2 changes: 1 addition & 1 deletion src/EventLogExpert.Eventing/Helpers/EventMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ internal static partial class EventMethods
case (int)EvtVariantType.Null:
return null;
case (int)EvtVariantType.String:
return Marshal.PtrToStringAuto(variant.StringVal);
return Marshal.PtrToStringUni(variant.StringVal);
case (int)EvtVariantType.AnsiString:
return Marshal.PtrToStringAnsi(variant.AnsiString);
case (int)EvtVariantType.SByte:
Expand Down
10 changes: 5 additions & 5 deletions src/EventLogExpert.Eventing/Providers/EventMessageProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ private ProviderDetails LoadMessagesFromModernProvider(ProviderMetadata provider
Task = e.Task,
Template = e.Template,
Version = e.Version
}).ToList();
}).ToArray();
}
catch (Exception ex)
{
Expand All @@ -218,7 +218,7 @@ private ProviderDetails LoadMessagesFromModernProvider(ProviderMetadata provider

try
{
provider.Keywords = new Dictionary<long, string>(providerMetadata.Keywords);
provider.Keywords = providerMetadata.Keywords;

}
catch (Exception ex)
Expand All @@ -228,7 +228,7 @@ private ProviderDetails LoadMessagesFromModernProvider(ProviderMetadata provider

try
{
provider.Opcodes = new Dictionary<int, string>(providerMetadata.Opcodes);
provider.Opcodes = providerMetadata.Opcodes;
}
catch (Exception ex)
{
Expand All @@ -237,14 +237,14 @@ private ProviderDetails LoadMessagesFromModernProvider(ProviderMetadata provider

try
{
provider.Tasks = new Dictionary<int, string>(providerMetadata.Tasks);
provider.Tasks = providerMetadata.Tasks;
}
catch (Exception ex)
{
_logger?.Trace($"Failed to load Tasks for modern provider: {_providerName}. Exception:\n{ex}");
}

_logger?.Trace($"Returning {provider.Events.Count} events for provider {_providerName}");
_logger?.Trace($"Returning {provider.Events.Count()} events for provider {_providerName}");

return provider;
}
Expand Down
12 changes: 6 additions & 6 deletions src/EventLogExpert.Eventing/Providers/ProviderDetails.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ public class ProviderDetails
public string ProviderName { get; set; } = string.Empty;

/// <summary>Messages from legacy provider</summary>
public List<MessageModel> Messages { get; set; } = [];
public IEnumerable<MessageModel> Messages { get; set; } = [];

/// <summary>Parameter strings from legacy provider</summary>
public List<MessageModel> Parameters { get; set; } = [];
public IEnumerable<MessageModel> Parameters { get; set; } = [];

/// <summary>Events and related items from modern provider</summary>
public List<EventModel> Events { get; set; } = [];
public IEnumerable<EventModel> Events { get; set; } = [];

public Dictionary<long, string> Keywords { get; set; } = [];
public IDictionary<long, string> Keywords { get; set; } = new Dictionary<long, string>();

public Dictionary<int, string> Opcodes { get; set; } = [];
public IDictionary<int, string> Opcodes { get; set; } = new Dictionary<int, string>();

public Dictionary<int, string> Tasks { get; set; } = [];
public IDictionary<int, string> Tasks { get; set; } = new Dictionary<int, string>();
}
11 changes: 8 additions & 3 deletions src/EventLogExpert.UI/FilterMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using EventLogExpert.Eventing.Models;
using EventLogExpert.UI.Models;
using System.Collections.ObjectModel;

namespace EventLogExpert.UI;

Expand Down Expand Up @@ -81,11 +82,12 @@ public static bool IsFilteringEnabled(EventFilter eventFilter) =>
eventFilter.Filters.IsEmpty is false;

/// <summary>Sorts events by RecordId if no order is specified</summary>
public static IEnumerable<DisplayEventModel> SortEvents(
public static ReadOnlyCollection<DisplayEventModel> SortEvents(
this IEnumerable<DisplayEventModel> events,
ColumnName? orderBy = null,
bool isDescending = false) =>
orderBy switch
bool isDescending = false)
{
var sortedEvents = orderBy switch
{
ColumnName.Level => isDescending ? events.OrderByDescending(e => e.Level) : events.OrderBy(e => e.Level),
ColumnName.DateAndTime => isDescending ?
Expand Down Expand Up @@ -115,4 +117,7 @@ public static IEnumerable<DisplayEventModel> SortEvents(
ColumnName.User => isDescending ? events.OrderByDescending(e => e.UserId) : events.OrderBy(e => e.UserId),
_ => isDescending ? events.OrderByDescending(e => e.RecordId) : events.OrderBy(e => e.RecordId)
};

return sortedEvents.ToList().AsReadOnly();
}
}
10 changes: 5 additions & 5 deletions src/EventLogExpert.UI/Interfaces/IPreferencesProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ namespace EventLogExpert.UI.Interfaces;

public interface IPreferencesProvider
{
IList<string> DisabledDatabasesPreference { get; set; }
IEnumerable<string> DisabledDatabasesPreference { get; set; }

bool DisplayPaneSelectionPreference { get; set; }

IList<ColumnName> EnabledEventTableColumnsPreference { get; set; }
IEnumerable<ColumnName> EnabledEventTableColumnsPreference { get; set; }

IList<string> FavoriteFiltersPreference { get; set; }
IEnumerable<string> FavoriteFiltersPreference { get; set; }

CopyType KeyboardCopyTypePreference { get; set; }

LogLevel LogLevelPreference { get; set; }

bool PreReleasePreference { get; set; }

IList<string> RecentFiltersPreference { get; set; }
IEnumerable<string> RecentFiltersPreference { get; set; }

IList<FilterGroupModel> SavedFiltersPreference { get; set; }
IEnumerable<FilterGroupModel> SavedFiltersPreference { get; set; }

string TimeZonePreference { get; set; }
}
5 changes: 2 additions & 3 deletions src/EventLogExpert.UI/Store/EventLog/EventLogAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,22 @@
using EventLogExpert.Eventing.Models;
using EventLogExpert.UI.Models;
using System.Collections.Immutable;
using System.Collections.ObjectModel;

namespace EventLogExpert.UI.Store.EventLog;

public sealed record EventLogAction
{
public sealed record AddEvent(DisplayEventModel NewEvent);

public sealed record AddEventBuffered(ReadOnlyCollection<DisplayEventModel> UpdatedBuffer, bool IsFull);
public sealed record AddEventBuffered(IEnumerable<DisplayEventModel> UpdatedBuffer, bool IsFull);

public sealed record AddEventSuccess(ImmutableDictionary<string, EventLogData> ActiveLogs);

public sealed record CloseAll;

public sealed record CloseLog(EventLogId LogId, string LogName);

public sealed record LoadEvents(EventLogData LogData, ReadOnlyCollection<DisplayEventModel> Events);
public sealed record LoadEvents(EventLogData LogData, IEnumerable<DisplayEventModel> Events);

public sealed record LoadNewEvents;

Expand Down
19 changes: 8 additions & 11 deletions src/EventLogExpert.UI/Store/EventLog/EventLogEffects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ public Task HandleAddEvent(EventLogAction.AddEvent action, IDispatcher dispatche
}
else
{
var updatedBuffer = newEvent.Concat(_eventLogState.Value.NewEventBuffer).ToList().AsReadOnly();
var full = updatedBuffer.Count >= EventLogState.MaxNewEvents;
var updatedBuffer = newEvent.Concat(_eventLogState.Value.NewEventBuffer);
var full = updatedBuffer.Count() >= EventLogState.MaxNewEvents;

dispatcher.Dispatch(new EventLogAction.AddEventBuffered(updatedBuffer, full));
}
Expand Down Expand Up @@ -197,7 +197,7 @@ await Parallel.ForEachAsync(
dispatcher.Dispatch(
new EventLogAction.LoadEvents(
logData,
events.OrderByDescending(e => e.RecordId).ToList().AsReadOnly()));
events.OrderByDescending(e => e.RecordId)));

dispatcher.Dispatch(new StatusBarAction.SetEventsLoading(activityId, 0, 0));

Expand Down Expand Up @@ -233,12 +233,9 @@ public Task HandleSetFilters(EventLogAction.SetFilters action, IDispatcher dispa
/// <summary>Adds new events to the currently opened log</summary>
private static EventLogData AddEventsToOneLog(EventLogData logData, IEnumerable<DisplayEventModel> eventsToAdd)
{
var newEvents = eventsToAdd
.Concat(logData.Events)
.ToList()
.AsReadOnly();
var newEvents = eventsToAdd.Concat(logData.Events);

var updatedLogData = logData with { Events = newEvents };
var updatedLogData = logData with { Events = newEvents.ToList().AsReadOnly() };

return updatedLogData;
}
Expand All @@ -248,13 +245,13 @@ private static ImmutableDictionary<string, EventLogData> DistributeEventsToManyL
IEnumerable<DisplayEventModel> eventsToDistribute)
{
var newLogs = logsToUpdate;
var events = eventsToDistribute.ToList();
var events = eventsToDistribute;

foreach (var log in logsToUpdate.Values)
{
var newEventsForThisLog = events.Where(e => e.OwningLog == log.Name).ToList();
var newEventsForThisLog = events.Where(e => e.OwningLog == log.Name);

if (newEventsForThisLog.Count <= 0) { continue; }
if (newEventsForThisLog.Any()) { continue; }

var newLogData = AddEventsToOneLog(log, newEventsForThisLog);
newLogs = newLogs.Remove(log.Name).Add(log.Name, newLogData);
Expand Down
4 changes: 2 additions & 2 deletions src/EventLogExpert.UI/Store/EventLog/EventLogReducers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public sealed class EventLogReducers
{
[ReducerMethod]
public static EventLogState ReduceAddEventBuffered(EventLogState state, EventLogAction.AddEventBuffered action) =>
state with { NewEventBuffer = action.UpdatedBuffer, NewEventBufferIsFull = action.IsFull };
state with { NewEventBuffer = action.UpdatedBuffer.ToList().AsReadOnly(), NewEventBufferIsFull = action.IsFull };

[ReducerMethod]
public static EventLogState ReduceAddEventSuccess(EventLogState state, EventLogAction.AddEventSuccess action) =>
Expand Down Expand Up @@ -54,7 +54,7 @@ public static EventLogState ReduceLoadEvents(EventLogState state, EventLogAction
{
ActiveLogs = newLogsCollection.Add(
action.LogData.Name,
action.LogData with { Events = action.Events })
action.LogData with { Events = action.Events.ToList().AsReadOnly() })
};
}

Expand Down
6 changes: 3 additions & 3 deletions src/EventLogExpert.UI/Store/EventTable/EventTableEffects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public Task HandleLoadColumns(IDispatcher dispatcher)
var columns = new Dictionary<ColumnName, bool>();
var enabledColumns = _preferencesProvider.EnabledEventTableColumnsPreference;

foreach (ColumnName column in Enum.GetValues(typeof(ColumnName)))
foreach (ColumnName column in Enum.GetValues<ColumnName>())
{
columns.Add(column, enabledColumns.Contains(column));
}
Expand All @@ -48,15 +48,15 @@ public Task HandleToggleColumn(EventTableAction.ToggleColumn action, IDispatcher
var columns = new Dictionary<ColumnName, bool>();
var enabledColumns = _preferencesProvider.EnabledEventTableColumnsPreference;

foreach (ColumnName column in Enum.GetValues(typeof(ColumnName)))
foreach (ColumnName column in Enum.GetValues<ColumnName>())
{
columns.Add(column,
column.Equals(action.ColumnName) ?
!enabledColumns.Contains(column) :
enabledColumns.Contains(column));
}

_preferencesProvider.EnabledEventTableColumnsPreference = columns.Keys.Where(column => columns[column]).ToList();
_preferencesProvider.EnabledEventTableColumnsPreference = columns.Keys.Where(column => columns[column]);

dispatcher.Dispatch(new EventTableAction.LoadColumnsCompleted(columns));

Expand Down
Loading

0 comments on commit 2ba7da7

Please sign in to comment.