Skip to content

Commit 056c712

Browse files
committed
updates
1 parent 08db763 commit 056c712

13 files changed

Lines changed: 302 additions & 84 deletions

File tree

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
using System.Text;
2+
3+
using LogExpert.Core.Classes.Log;
4+
using LogExpert.Core.Entities;
5+
6+
namespace LogExpert.Benchmarks;
7+
8+
/// <summary>
9+
/// Quick test to verify PositionAwareStreamReaderPipelineNew works correctly
10+
/// before running full benchmarks
11+
/// </summary>
12+
public class QuickPipelineTest
13+
{
14+
public static void Run ()
15+
{
16+
Console.WriteLine("Testing PositionAwareStreamReaderPipelineNew...");
17+
18+
// Generate test data
19+
var sb = new StringBuilder();
20+
for (int i = 0; i < 100; i++)
21+
{
22+
sb.AppendLine($"Line {i}: This is a test line with some content");
23+
}
24+
var testData = Encoding.UTF8.GetBytes(sb.ToString());
25+
26+
try
27+
{
28+
// Test 1: Read all lines
29+
Console.WriteLine("\nTest 1: Reading all lines...");
30+
using (var stream = new MemoryStream(testData))
31+
using (var reader = new PositionAwareStreamReaderPipelineNew(stream, new EncodingOptions(), 10000))
32+
{
33+
int lineCount = 0;
34+
while (reader.ReadLine() != null)
35+
{
36+
lineCount++;
37+
}
38+
Console.WriteLine($"✓ Read {lineCount} lines");
39+
}
40+
41+
// Test 2: Memory API
42+
Console.WriteLine("\nTest 2: Testing memory API...");
43+
using (var stream = new MemoryStream(testData))
44+
using (var reader = new PositionAwareStreamReaderPipelineNew(stream, new EncodingOptions(), 10000))
45+
{
46+
int lineCount = 0;
47+
while (reader.TryReadLine(out var lineMemory))
48+
{
49+
lineCount++;
50+
// Verify we can access the memory
51+
_ = lineMemory.Length;
52+
}
53+
Console.WriteLine($"✓ Read {lineCount} lines via memory API");
54+
}
55+
56+
// Test 3: Position seeking
57+
Console.WriteLine("\nTest 3: Testing position seeking...");
58+
using (var stream = new MemoryStream(testData))
59+
using (var reader = new PositionAwareStreamReaderPipelineNew(stream, new EncodingOptions(), 10000))
60+
{
61+
// Read first 10 lines
62+
for (int i = 0; i < 10; i++)
63+
{
64+
_ = reader.ReadLine();
65+
}
66+
67+
// Seek back to beginning
68+
reader.Position = 0;
69+
70+
// Read all lines again
71+
int lineCount = 0;
72+
while (reader.ReadLine() != null)
73+
{
74+
lineCount++;
75+
}
76+
Console.WriteLine($"✓ Seek and read {lineCount} lines");
77+
}
78+
79+
Console.WriteLine("\n✅ All tests passed!");
80+
Console.WriteLine("\nReady to run benchmarks:");
81+
Console.WriteLine(" cd LogExpert.Benchmarks");
82+
Console.WriteLine(" dotnet run -c Release --filter \"*Pipeline*\"");
83+
}
84+
catch (Exception ex)
85+
{
86+
Console.WriteLine($"\n❌ Test failed: {ex.Message}");
87+
Console.WriteLine($"Stack trace:\n{ex.StackTrace}");
88+
Environment.Exit(1);
89+
}
90+
}
91+
}

src/LogExpert.Benchmarks/StreamReaderBenchmarks.cs

Lines changed: 13 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ private static byte[] GenerateUnicodeTestData (int lineCount)
7272
}
7373

7474
[Benchmark(Baseline = true)]
75+
[BenchmarkCategory("Legacy", "Small", "ReadAll")]
7576
public void Legacy_ReadAll_Small ()
7677
{
7778
using var stream = new MemoryStream(_smallTestData);
@@ -80,6 +81,7 @@ public void Legacy_ReadAll_Small ()
8081
}
8182

8283
[Benchmark]
84+
[BenchmarkCategory("System", "Small", "ReadAll")]
8385
public void System_ReadAll_Small ()
8486
{
8587
using var stream = new MemoryStream(_smallTestData);
@@ -88,14 +90,7 @@ public void System_ReadAll_Small ()
8890
}
8991

9092
[Benchmark]
91-
public void Pipeline_ReadAll_Small ()
92-
{
93-
using var stream = new MemoryStream(_smallTestData);
94-
using var reader = new PositionAwareStreamReaderPipeline(stream, new EncodingOptions(), 10000);
95-
ReadAllLines(reader);
96-
}
97-
98-
[Benchmark]
93+
[BenchmarkCategory("Legacy", "Medium", "ReadAll")]
9994
public void Legacy_ReadAll_Medium ()
10095
{
10196
using var stream = new MemoryStream(_mediumTestData);
@@ -104,6 +99,7 @@ public void Legacy_ReadAll_Medium ()
10499
}
105100

106101
[Benchmark]
102+
[BenchmarkCategory("System", "Medium", "ReadAll")]
107103
public void System_ReadAll_Medium ()
108104
{
109105
using var stream = new MemoryStream(_mediumTestData);
@@ -112,14 +108,7 @@ public void System_ReadAll_Medium ()
112108
}
113109

114110
[Benchmark]
115-
public void Pipeline_ReadAll_Medium ()
116-
{
117-
using var stream = new MemoryStream(_mediumTestData);
118-
using var reader = new PositionAwareStreamReaderPipeline(stream, new EncodingOptions(), 10000);
119-
ReadAllLines(reader);
120-
}
121-
122-
[Benchmark]
111+
[BenchmarkCategory("Legacy", "Large", "ReadAll")]
123112
public void Legacy_ReadAll_Large ()
124113
{
125114
using var stream = new MemoryStream(_largeTestData);
@@ -128,6 +117,7 @@ public void Legacy_ReadAll_Large ()
128117
}
129118

130119
[Benchmark]
120+
[BenchmarkCategory("System", "Large", "ReadAll")]
131121
public void System_ReadAll_Large ()
132122
{
133123
using var stream = new MemoryStream(_largeTestData);
@@ -136,37 +126,20 @@ public void System_ReadAll_Large ()
136126
}
137127

138128
[Benchmark]
139-
public void Pipeline_ReadAll_Large ()
140-
{
141-
using var stream = new MemoryStream(_largeTestData);
142-
using var reader = new PositionAwareStreamReaderPipeline(stream, new EncodingOptions(), 10000);
143-
ReadAllLines(reader);
144-
}
145-
146-
[Benchmark]
147-
public void Pipeline_ReadAll_Unicode ()
129+
[BenchmarkCategory("System", "Unicode", "ReadAll")]
130+
public void System_ReadAll_Unicode ()
148131
{
149132
using var stream = new MemoryStream(_unicodeTestData);
150-
using var reader = new PositionAwareStreamReaderPipeline(stream, new EncodingOptions { Encoding = Encoding.UTF8 }, 10000);
133+
using var reader = new PositionAwareStreamReaderSystem(stream, new EncodingOptions(), 10000);
151134
ReadAllLines(reader);
152135
}
153136

154137
[Benchmark]
155-
public void Pipeline_Seek_And_Read ()
138+
[BenchmarkCategory("Legacy", "Unicode", "ReadAll")]
139+
public void Legacy_ReadAll_Unicode ()
156140
{
157-
using var stream = new MemoryStream(_mediumTestData);
158-
using var reader = new PositionAwareStreamReaderPipeline(stream, new EncodingOptions(), 10000);
159-
160-
// Read first 100 lines
161-
for (int i = 0; i < 100; i++)
162-
{
163-
_ = reader.ReadLine();
164-
}
165-
166-
// Seek back to beginning
167-
reader.Position = 0;
168-
169-
// Read all lines
141+
using var stream = new MemoryStream(_unicodeTestData);
142+
using var reader = new PositionAwareStreamReaderLegacy(stream, new EncodingOptions(), 10000);
170143
ReadAllLines(reader);
171144
}
172145

src/LogExpert.Core/Classes/Log/PositionAwareStreamReaderPipeline.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,6 @@ private void RestartPipelineInternal (long startPosition)
186186
// Create PipeReader
187187
_pipeReader = PipeReader.Create(_stream, _streamPipeReaderOptions);
188188

189-
// CRITICAL: Create a NEW BlockingCollection instance
190-
// Once CompleteAdding() is called, a BlockingCollection cannot be reused
191189
_lineQueue = new BlockingCollection<LineSegment>(new ConcurrentQueue<LineSegment>(), DEFAULT_CHANNEL_CAPACITY);
192190

193191
Volatile.Write(ref _producerException, null);

src/LogExpert.Core/Classes/SysoutPipe.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
using NLog;
2-
31
using System.Diagnostics;
42
using System.Globalization;
53
using System.Text;
64

5+
using NLog;
6+
77
namespace LogExpert.Core.Classes;
88

99
public class SysoutPipe : IDisposable
@@ -20,10 +20,10 @@ public class SysoutPipe : IDisposable
2020

2121
#region cTor
2222

23-
public SysoutPipe(StreamReader sysout)
23+
public SysoutPipe (StreamReader sysout)
2424
{
2525
_disposed = false;
26-
this._sysout = sysout;
26+
_sysout = sysout;
2727
FileName = Path.GetTempFileName();
2828
_logger.Info(CultureInfo.InvariantCulture, "sysoutPipe created temp file: {0}", FileName);
2929

@@ -47,19 +47,19 @@ public SysoutPipe(StreamReader sysout)
4747

4848
#region Public methods
4949

50-
public void ClosePipe()
50+
public void ClosePipe ()
5151
{
5252
_writer.Close();
5353
_writer = null;
5454
}
5555

5656

57-
public void DataReceivedEventHandler(object sender, DataReceivedEventArgs e)
57+
public void DataReceivedEventHandler (object sender, DataReceivedEventArgs e)
5858
{
5959
_writer.WriteLine(e.Data);
6060
}
6161

62-
public void ProcessExitedEventHandler(object sender, System.EventArgs e)
62+
public void ProcessExitedEventHandler (object sender, EventArgs e)
6363
{
6464
//ClosePipe();
6565
if (sender.GetType() == typeof(Process))
@@ -71,7 +71,7 @@ public void ProcessExitedEventHandler(object sender, System.EventArgs e)
7171

7272
#endregion
7373

74-
protected void ReaderThread()
74+
protected void ReaderThread ()
7575
{
7676
var buff = new char[256];
7777

@@ -97,13 +97,13 @@ protected void ReaderThread()
9797
ClosePipe();
9898
}
9999

100-
public void Dispose()
100+
public void Dispose ()
101101
{
102102
Dispose(true);
103103
GC.SuppressFinalize(this); // Suppress finalization (not needed but best practice)
104104
}
105105

106-
protected virtual void Dispose(bool disposing)
106+
protected virtual void Dispose (bool disposing)
107107
{
108108
if (!_disposed)
109109
{

src/LogExpert.Core/Helpers/RegexHelper.cs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,30 +64,26 @@ public static Regex GetOrCreateCached (string pattern, RegexOptions options = Re
6464
/// <param name="pattern">The pattern to validate.</param>
6565
/// <param name="error">Output parameter containing error message if validation fails.</param>
6666
/// <returns>True if the pattern is valid, false otherwise.</returns>
67-
public static bool IsValidPattern (string pattern, out string? error)
67+
public static (bool isValid, string error) IsValidPattern (string pattern)
6868
{
6969
if (string.IsNullOrEmpty(pattern))
7070
{
71-
error = "Pattern cannot be null or empty.";
72-
return false;
71+
return (false, "Pattern cannot be null or empty.");
7372
}
7473

7574
try
7675
{
7776
_ = new Regex(pattern, RegexOptions.None, TimeSpan.FromMilliseconds(100));
78-
error = null;
79-
return true;
77+
return (true, string.Empty);
8078
}
8179
catch (ArgumentException ex)
8280
{
83-
error = ex.Message;
84-
return false;
81+
return (false, ex.Message);
8582
}
8683
catch (RegexMatchTimeoutException)
8784
{
8885
// Pattern is valid syntactically, but may be complex
89-
error = null;
90-
return true;
86+
return (true, string.Empty);
9187
}
9288
}
9389

0 commit comments

Comments
 (0)