Skip to content

Commit

Permalink
Cache padding strings up to 120 spaces (PowerShell#3036)
Browse files Browse the repository at this point in the history
  • Loading branch information
lzybkr authored and vors committed Jan 26, 2017
1 parent f41b94f commit 110878c
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1752,7 +1752,7 @@ private string ReadLineFromConsole(bool endOnTab, string initialContent, bool ca
// is overridden by the tab
char charUnderCursor = GetCharacterUnderCursor(c);

Write(new string(' ', leftover));
Write(StringUtil.Padding(leftover));
RawUI.CursorPosition = c;

restOfLine = s[i] + (charUnderCursor + s.Substring(i + 1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ internal override
}

ArrayList result = new ArrayList();
string border = new string(' ', maxWidth);
string border = StringUtil.Padding(maxWidth);

result.Add(border);
RenderHelper(result, _topLevelNodes, 0, maxWidth, rawUI);
Expand Down
14 changes: 7 additions & 7 deletions src/Microsoft.PowerShell.ConsoleHost/host/msh/ProgressNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ namespace Microsoft.PowerShell
void
RenderFull(ArrayList strCollection, int indentation, int maxWidth, PSHostRawUserInterface rawUI, bool isFullPlus)
{
string indent = new string(' ', indentation);
string indent = StringUtil.Padding(indentation);

// First line: the activity

Expand All @@ -180,7 +180,7 @@ namespace Microsoft.PowerShell
rawUI, StringUtil.Format(" {0}{1} ", indent, this.Activity), maxWidth));

indentation += 3;
indent = new string(' ', indentation);
indent = StringUtil.Padding(indentation);

// Second line: the status description

Expand Down Expand Up @@ -209,7 +209,7 @@ namespace Microsoft.PowerShell
" {0}[{1}{2}] ",
indent,
new string('o', mercuryWidth),
new string(' ', thermoWidth - mercuryWidth)),
StringUtil.Padding(thermoWidth - mercuryWidth)),
maxWidth));
}

Expand Down Expand Up @@ -291,7 +291,7 @@ private static void RenderFullDescription(string description, string indent, int
void
RenderCompact(ArrayList strCollection, int indentation, int maxWidth, PSHostRawUserInterface rawUI)
{
string indent = new string(' ', indentation);
string indent = StringUtil.Padding(indentation);

// First line: the activity

Expand All @@ -301,7 +301,7 @@ private static void RenderFullDescription(string description, string indent, int
StringUtil.Format(" {0}{1} ", indent, this.Activity), maxWidth));

indentation += 3;
indent = new string(' ', indentation);
indent = StringUtil.Padding(indentation);

// Second line: the status description with percentage and time remaining, if applicable.

Expand Down Expand Up @@ -372,7 +372,7 @@ private static void RenderFullDescription(string description, string indent, int
void
RenderMinimal(ArrayList strCollection, int indentation, int maxWidth, PSHostRawUserInterface rawUI)
{
string indent = new string(' ', indentation);
string indent = StringUtil.Padding(indentation);

// First line: Everything mushed into one line

Expand Down Expand Up @@ -512,7 +512,7 @@ private int LinesRequiredInFullStyleMethod(PSHostRawUserInterface rawUi, int max
// Start with 1 for the Activity
int lines = 1;
// Use 5 spaces as the heuristic indent. 5 spaces stand for the indent for the CurrentOperation of the first-level child node
var indent = new string(' ', 5);
var indent = StringUtil.Padding(5);
var temp = new ArrayList();

if (isFullPlus)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Collections.Specialized;
using System.Text;
using System.Globalization;
using System.Management.Automation.Internal;

namespace Microsoft.PowerShell.Commands.Internal.Format
{
Expand Down Expand Up @@ -715,7 +716,7 @@ internal static string TruncateAtNewLine(string s)

internal static string PadLeft(string val, int count)
{
return new string(' ', count) + val;
return StringUtil.Padding(count) + val;
}

private static readonly char[] s_newLineChar = new char[] { '\n' };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

using System.Collections.Specialized;
using System.Diagnostics;
using System.Management.Automation.Internal;

namespace Microsoft.PowerShell.Commands.Internal.Format
{
Expand Down Expand Up @@ -86,7 +87,7 @@ internal void Initialize(string[] propertyNames, int screenColumnWidth, DisplayC
if (propertyNameCellCounts[k] < _propertyLabelsDisplayLength)
{
// shorter than the max, add padding
_propertyLabels[k] = propertyNames[k] + new string(' ', _propertyLabelsDisplayLength - propertyNameCellCounts[k]);
_propertyLabels[k] = propertyNames[k] + StringUtil.Padding(_propertyLabelsDisplayLength - propertyNameCellCounts[k]);
}
else if (propertyNameCellCounts[k] > _propertyLabelsDisplayLength)
{
Expand Down Expand Up @@ -181,7 +182,7 @@ private void WriteProperty(int k, string propertyValue, LineOutput lo)
else
{
if (padding == null)
padding = prependString = new string(' ', _propertyLabelsDisplayLength);
padding = StringUtil.Padding(_propertyLabelsDisplayLength);

prependString = padding;
}
Expand Down Expand Up @@ -209,7 +210,7 @@ private void WriteSingleLineHelper(string prependString, string line, LineOutput
StringCollection sc = StringManipulationHelper.GenerateLines(lo.DisplayCells, line, fieldCellCount, fieldCellCount);

// padding to use in the lines after the first
string padding = new string(' ', _propertyLabelsDisplayLength);
string padding = StringUtil.Padding(_propertyLabelsDisplayLength);

// display the string collection
for (int k = 0; k < sc.Count; k++)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
--********************************************************************/

using System.Collections.Specialized;
using System.Management.Automation.Internal;
using System.Text;

namespace Microsoft.PowerShell.Commands.Internal.Format
Expand Down Expand Up @@ -248,7 +249,7 @@ private string[] GenerateTableRow(string[] values, int[] alignment, DisplayCells
// skipping the first ones, add a separator for catenation
for (int j = 0; j < scArray[k].Count; j++)
{
scArray[k][j] = new string(' ', ScreenInfo.separatorCharacterCount) + scArray[k][j];
scArray[k][j] = StringUtil.Padding(ScreenInfo.separatorCharacterCount) + scArray[k][j];
}
}
else
Expand All @@ -258,7 +259,7 @@ private string[] GenerateTableRow(string[] values, int[] alignment, DisplayCells
{
for (int j = 0; j < scArray[k].Count; j++)
{
scArray[k][j] = new string(' ', _startColumn) + scArray[k][j];
scArray[k][j] = StringUtil.Padding(_startColumn) + scArray[k][j];
}
}
}
Expand Down Expand Up @@ -288,7 +289,7 @@ private string[] GenerateTableRow(string[] values, int[] alignment, DisplayCells
{
for (int j = 0; j < paddingEntries; j++)
{
scArray[col].Add(new string(' ', paddingBlanks));
scArray[col].Add(StringUtil.Padding(paddingBlanks));
}
}
}
Expand Down Expand Up @@ -339,14 +340,14 @@ private string GenerateRow(string[] values, int[] alignment, DisplayCells dc)
// pad with a blank (or any character that ALWAYS maps to a single screen cell
if (k > 0)
{
sb.Append(new string(' ', ScreenInfo.separatorCharacterCount));
sb.Append(StringUtil.Padding(ScreenInfo.separatorCharacterCount));
}
else
{
// add indentation padding if needed
if (_startColumn > 0)
{
sb.Append(new string(' ', _startColumn));
sb.Append(StringUtil.Padding(_startColumn));
}
}
sb.Append(GenerateRowField(values[k], _si.columnInfo[k].width, alignment[k], dc));
Expand All @@ -372,7 +373,7 @@ private static string GenerateRowField(string val, int width, int alignment, Dis
{
case TextAlignment.Right:
{
s = new string(' ', padCount) + s;
s = StringUtil.Padding(padCount) + s;
}
break;

Expand All @@ -382,14 +383,14 @@ private static string GenerateRowField(string val, int width, int alignment, Dis
int padLeft = padCount / 2;
int padRight = padCount - padLeft;

s = new string(' ', padLeft) + s + new string(' ', padRight);
s = StringUtil.Padding(padLeft) + s + StringUtil.Padding(padRight);
}
break;

default:
{
// left align is the default
s += new string(' ', padCount);
s += StringUtil.Padding(padCount);
}
break;
}
Expand Down
11 changes: 6 additions & 5 deletions src/System.Management.Automation/engine/parser/token.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Management.Automation.Internal;
using System.Text;

namespace System.Management.Automation.Language
Expand Down Expand Up @@ -1236,7 +1237,7 @@ public override string ToString()

internal virtual string ToDebugString(int indent)
{
return string.Format(CultureInfo.InvariantCulture, "{0}{1}: <{2}>", new string(' ', indent), _kind, Text);
return string.Format(CultureInfo.InvariantCulture, "{0}{1}: <{2}>", StringUtil.Padding(indent), _kind, Text);
}
}

Expand All @@ -1256,7 +1257,7 @@ internal NumberToken(InternalScriptExtent scriptExtent, object value, TokenFlags
internal override string ToDebugString(int indent)
{
return string.Format(CultureInfo.InvariantCulture,
"{0}{1}: <{2}> Value:<{3}> Type:<{4}>", new string(' ', indent), Kind, Text, _value, _value.GetType().Name);
"{0}{1}: <{2}> Value:<{3}> Type:<{4}>", StringUtil.Padding(indent), Kind, Text, _value, _value.GetType().Name);
}

/// <summary>
Expand Down Expand Up @@ -1298,7 +1299,7 @@ internal ParameterToken(InternalScriptExtent scriptExtent, string parameterName,
internal override string ToDebugString(int indent)
{
return string.Format(CultureInfo.InvariantCulture,
"{0}{1}: <-{2}{3}>", new string(' ', indent), Kind, _parameterName, _usedColon ? ":" : "");
"{0}{1}: <-{2}{3}>", StringUtil.Padding(indent), Kind, _parameterName, _usedColon ? ":" : "");
}
}

Expand Down Expand Up @@ -1326,7 +1327,7 @@ internal VariableToken(InternalScriptExtent scriptExtent, VariablePath path, Tok
internal override string ToDebugString(int indent)
{
return string.Format(CultureInfo.InvariantCulture,
"{0}{1}: <{2}> Name:<{3}>", new string(' ', indent), Kind, Text, Name);
"{0}{1}: <{2}> Name:<{3}>", StringUtil.Padding(indent), Kind, Text, Name);
}
}

Expand All @@ -1349,7 +1350,7 @@ internal StringToken(InternalScriptExtent scriptExtent, TokenKind kind, TokenFla
internal override string ToDebugString(int indent)
{
return string.Format(CultureInfo.InvariantCulture,
"{0}{1}: <{2}> Value:<{3}>", new string(' ', indent), Kind, Text, Value);
"{0}{1}: <{2}> Value:<{3}>", StringUtil.Padding(indent), Kind, Text, Value);
}
}

Expand Down
20 changes: 20 additions & 0 deletions src/System.Management.Automation/utils/StringUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
--********************************************************************/

using System.Management.Automation.Host;
using System.Threading;
using Dbg = System.Management.Automation.Diagnostics;

namespace System.Management.Automation.Internal
Expand Down Expand Up @@ -68,6 +69,25 @@ internal static

return result;
}

// Typical padding is at most a screen's width, any more than that and we won't bother caching.
private const int IndentCacheMax = 120;
private static readonly string[] IndentCache = new string[IndentCacheMax];
internal static string Padding(int countOfSpaces)
{
if (countOfSpaces >= IndentCacheMax)
return new string(' ', countOfSpaces);

var result = IndentCache[countOfSpaces];

if (result == null)
{
Interlocked.CompareExchange(ref IndentCache[countOfSpaces], new string(' ', countOfSpaces), null);
result = IndentCache[countOfSpaces];
}

return result;
}
}
} // namespace

0 comments on commit 110878c

Please sign in to comment.