diff --git a/ChangeLogs/1.0.3-ChangeLog.md b/ChangeLogs/1.0.3-ChangeLog.md new file mode 100644 index 0000000..93dcaa8 --- /dev/null +++ b/ChangeLogs/1.0.3-ChangeLog.md @@ -0,0 +1,13 @@ +# V1.0.3 + +## New Property + +| Property | Type | Default | Description | +|----------|------|---------|-------------| +| `CachingEnabled` | `bool` | `true` |When `true`, the generated table string is cached when the ToTable method is called. Cache will be cleared on any property change or method call. | + +## New Method + +| Method | Description | +|--------|-------------| +| `ClearCache()` | Clears the cached generated table string. | diff --git a/ConsoleTable.Text.Examples/Program.cs b/ConsoleTable.Text.Examples/Program.cs index d0771ce..b57ad4d 100644 --- a/ConsoleTable.Text.Examples/Program.cs +++ b/ConsoleTable.Text.Examples/Program.cs @@ -26,6 +26,8 @@ static void Main(string[] args) WriteTableFluent(); + WriteBigTable(); + Console.Read(); } @@ -54,6 +56,7 @@ private static void WriteDefaultTableWithProperties() var table = new Table { + CachingEnabled = true, Headers = new string[] { "Name", "Age", "City" }, Rows = new List { @@ -156,6 +159,7 @@ private static void WriteTableWithStyling(bool headerTextAlignRight, bool rowTex var table = new Table { + CachingEnabled = true, Padding = padding, HeaderTextAlignmentRight = headerTextAlignRight, RowTextAlignmentRight = rowTextAlignRight @@ -192,4 +196,43 @@ private static void WriteTableFluent() Console.WriteLine(tableString); Console.WriteLine(); } + + private static void WriteBigTable() + { + Console.WriteLine(); + Console.WriteLine("Big table (may take some seconds to generate):"); + + var table = new Table + { + CachingEnabled = true, + HeaderTextAlignmentRight = false, + RowTextAlignmentRight = false, + Padding = 2 + }; + + var columnCount = 5; + var headers = new List(); + for (var columnPos = 1; columnPos <= columnCount; columnPos++) + { + headers.Add($"Header {columnPos}"); + } + table.Headers = headers.ToArray(); + + var rows = new List(); + for (var rowPos = 1; rowPos <= 100000; rowPos++) + { + var row = new string[columnCount]; + for (var columnPos = 1; columnPos <= columnCount; columnPos++) + { + row[columnPos - 1] = $"Row {rowPos} -> Column {columnPos}"; + } + rows.Add(row); + } + table.Rows = rows; + + var tableString = table.ToTable(); + + Console.WriteLine(tableString); + Console.WriteLine(); + } } diff --git a/ConsoleTable.Text/Table.cs b/ConsoleTable.Text/Table.cs index 4db99d4..6592221 100644 --- a/ConsoleTable.Text/Table.cs +++ b/ConsoleTable.Text/Table.cs @@ -9,6 +9,23 @@ public class Table { private string _tableCache = null; + private bool _cachingEnabled = true; + /// + /// Enables the caching of the generated table string when the ToTable method is called. Default is true. + /// Cache will be cleared on any property change or method call. + /// + public bool CachingEnabled + { + get => _cachingEnabled; + set + { + _cachingEnabled = value; + + if (!_cachingEnabled) + ClearCache(); + } + } + private string[] _headers = Array.Empty(); /// /// Gets or sets the headers of the table. This is a single optional top row. @@ -282,9 +299,13 @@ private StringBuilder CreateSeperatorLine(int[] maximumCellWidths, int previousR return formattedTable; } - private void ClearCache() + /// + /// Clears the cached generated table string + /// + public Table ClearCache() { _tableCache = null; + return this; } /// @@ -303,7 +324,7 @@ public Table Clear() /// public string ToTable() { - if (!string.IsNullOrEmpty(_tableCache)) + if (CachingEnabled && !string.IsNullOrEmpty(_tableCache)) return _tableCache; var table = new List(); @@ -365,9 +386,12 @@ public string ToTable() formattedTable = CreateBottomLine(maximumCellWidths, previousRow.Count(), formattedTable); - _tableCache = formattedTable.ToString(); + var generatedTable = formattedTable.ToString(); + + if (CachingEnabled) + _tableCache = generatedTable; - return _tableCache; + return generatedTable; } public override string ToString() diff --git a/ConsoleTable.slnx b/ConsoleTable.slnx index 1328dc0..717850d 100644 --- a/ConsoleTable.slnx +++ b/ConsoleTable.slnx @@ -7,6 +7,7 @@ + diff --git a/README.md b/README.md index c2fb267..1420407 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ Output: | `Padding` | `int` | `1` | The number of spaces on each side of cell content | | `HeaderTextAlignmentRight` | `bool` | `false` | When `true`, header text is right-aligned otherwise left aligned | | `RowTextAlignmentRight` | `bool` | `false` | When `true`, row text is right-aligned otherwise left aligned | +| `CachingEnabled` | `bool` | `true` | When `true`, the generated table string is cached when the ToTable method is called. Cache will be cleared on any property change or method call. | ### Methods @@ -94,6 +95,7 @@ Output: | `AddRows(params string[][] rows)` | Adds multiple data rows to the table. Rows are not required. | | `ClearRows()` | Removes all data rows from the table (headers are preserved). | | `Clear()` | Clear all the headers and rows from the table. | +| `ClearCache()` | Clears the generated table string cache. This can be done to save memory. | | `ToTable() / ToString()` | Returns the formatted table as a string. | ## Examples diff --git a/Tests/ConsoleTable.Text.Tests/TableTests.cs b/Tests/ConsoleTable.Text.Tests/TableTests.cs index e9880ea..1ad5f3e 100644 --- a/Tests/ConsoleTable.Text.Tests/TableTests.cs +++ b/Tests/ConsoleTable.Text.Tests/TableTests.cs @@ -4,6 +4,46 @@ namespace ConsoleTable.Text.Tests; public class TableTests { + [Theory] + [InlineData(true)] + [InlineData(false)] + public void PerformanceCheck(bool cacheEnabled) + { + var table = new Table + { + CachingEnabled = cacheEnabled, + HeaderTextAlignmentRight = true, + RowTextAlignmentRight = false, + Padding = 5 + }; + + var columnCount = 100; + var headers = new List(); + for (var columnPos = 1; columnPos <= columnCount; columnPos++) + { + headers.Add($"Header {columnPos}"); + } + table.Headers = headers.ToArray(); + + var rows = new List(); + for (var rowPos = 1; rowPos <= 100000; rowPos++) + { + var row = new string[columnCount]; + for (var columnPos = 1; columnPos <= columnCount; columnPos++) + { + row[columnPos - 1] = $"Row {rowPos} -> Column {columnPos}"; + } + rows.Add(row); + } + table.Rows = rows; + + var tableResult1 = table.ToTable(); + Assert.NotEmpty(tableResult1); + + var tableResult2 = table.ToTable(); + Assert.NotEmpty(tableResult2); + } + [Fact] public void ToTable_EmptyTable_ReturnsEmptyString() { @@ -555,6 +595,43 @@ public void AddRows_ClearsCache() Assert.Contains("NewRow", secondResult); } + [Fact] + public void ClearCache() + { + var table = new Table + { + CachingEnabled = true + }; + + table.AddRow("1"); + var firstResult = table.ToTable(); + + table.ClearCache(); + var secondResult = table.ToTable(); + + Assert.Contains("1", firstResult); + Assert.Contains("1", secondResult); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void CachingEnabled(bool cachingEnabled) + { + var table = new Table + { + CachingEnabled = cachingEnabled + }; + + table.AddRow("1"); + + var firstResult = table.ToTable(); + var secondResult = table.ToTable(); + + Assert.Contains("1", firstResult); + Assert.Contains("1", secondResult); + } + [Fact] public void ToString_ReturnsFormattedTable() {