Skip to content

Commit

Permalink
FilePathLayout - Reduce string-allocation when writing to the same fi…
Browse files Browse the repository at this point in the history
…le (Reuse clean-filename when raw-filename is unchanged)
  • Loading branch information
snakefoot committed Nov 6, 2016
1 parent 35259db commit 9f307d9
Showing 1 changed file with 42 additions and 16 deletions.
58 changes: 42 additions & 16 deletions src/NLog/Internal/FilePathLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ internal class FilePathLayout : IRenderable

private bool _cleanupInvalidChars;

private string _cachedPrevRawFileName;
private string _cachedPrevCleanFileName;

//TODO onInit maken
/// <summary>Initializes a new instance of the <see cref="T:System.Object" /> class.</summary>
public FilePathLayout(Layout layout, bool cleanupInvalidChars, FilePathKind filePathKind)
Expand Down Expand Up @@ -138,56 +141,78 @@ public Layout GetLayout()
#region Implementation of IRenderable

/// <summary>
/// Render, as cleaned if requested.
/// Render the raw filename from Layout
/// </summary>
/// <param name="logEvent">The log event.</param>
/// <returns>String representation of a layout.</returns>
private string GetCleanedFileName(LogEventInfo logEvent)
private string GetRenderedFileName(LogEventInfo logEvent)
{
if (cleanedFixedResult != null)
{
return cleanedFixedResult;
}

if (_layout == null)
{
return null;
}

var result = _layout.Render(logEvent);
if (_cleanupInvalidChars)
{
return CleanupInvalidFilePath(result);
}
return result;
return _layout.Render(logEvent);
}

public string Render(LogEventInfo logEvent)
/// <summary>
/// Convert the raw filename to a correct filename
/// </summary>
/// <param name="rawFileName">The filename generated by Layout.</param>
/// <returns>String representation of a correct filename.</returns>
private string GetCleanFileName(string rawFileName)
{
var rendered = GetCleanedFileName(logEvent);
if (String.IsNullOrEmpty(rendered))
var cleanFileName = rawFileName;
if (_cleanupInvalidChars && cleanedFixedResult == null)
{
return rendered;
cleanFileName = CleanupInvalidFilePath(rawFileName);
}

if (_filePathKind == FilePathKind.Absolute)
{
return rendered;
return cleanFileName;
}

#if !SILVERLIGHT
if (_filePathKind == FilePathKind.Relative)
{
return Path.Combine(_baseDir, rendered);
//use basedir, faster than Path.GetFullPath
cleanFileName = Path.Combine(_baseDir, cleanFileName);
return cleanFileName;
}
#endif
//unknown, use slow method
return Path.GetFullPath(rendered);
cleanFileName = Path.GetFullPath(cleanFileName);
return cleanFileName;
}

public string Render(LogEventInfo logEvent)
{
var rawFileName = GetRenderedFileName(logEvent);
if (string.IsNullOrEmpty(rawFileName))
{
return rawFileName;
}

if ((!_cleanupInvalidChars || cleanedFixedResult != null) && _filePathKind == FilePathKind.Absolute)
return rawFileName;

if (string.CompareOrdinal(_cachedPrevRawFileName, rawFileName) == 0)
return _cachedPrevCleanFileName; // Cache Hit, skip clean filename string-allocation

var cleanFileName = GetCleanFileName(rawFileName);
_cachedPrevCleanFileName = cleanFileName;
_cachedPrevRawFileName = rawFileName;
return cleanFileName;
}

#endregion


/// <summary>
/// Is this (templated/invalid) path an absolute, relative or unknown?
/// </summary>
Expand All @@ -201,6 +226,7 @@ internal static FilePathKind DetectFilePathKind(Layout pathLayout)

return DetectFilePathKind(simpleLayout);
}

/// <summary>
/// Is this (templated/invalid) path an absolute, relative or unknown?
/// </summary>
Expand Down

0 comments on commit 9f307d9

Please sign in to comment.