Skip to content

Commit 61991d8

Browse files
committed
readonly struct for GC Pressure
1 parent 51abbf1 commit 61991d8

2 files changed

Lines changed: 38 additions & 36 deletions

File tree

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

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ public BufferIndex (int maxBuffers, int maxLinesPerBuffer)
3232
_lruCacheDict = new(Environment.ProcessorCount, maxBuffers + 1);
3333
}
3434

35-
// ─────────────────────────────────────────────
36-
// Hot path — lookup
37-
// ─────────────────────────────────────────────
35+
#region Hot Path Lookup
3836

3937
/// <summary>
4038
/// 4-layer lookup. Caller must hold at least a read lock. Returns false if lineNum is out of range or the index is
@@ -65,7 +63,7 @@ private LogBufferEntry TryFindBufferWithIndex (int lineNum)
6563

6664
if (count == 0)
6765
{
68-
return new LogBufferEntry { Buffer = null, Index = -1, Found = false };
66+
return new LogBufferEntry(null, -1, false);
6967
}
7068

7169
// Layer 0: Last buffer cache — O(1) for sequential access
@@ -76,7 +74,7 @@ private LogBufferEntry TryFindBufferWithIndex (int lineNum)
7674
if ((uint)(lineNum - buf.StartLine) < (uint)buf.LineCount)
7775
{
7876
//dont UpdateLRUCache, the cache has not changed in layer 0
79-
return new LogBufferEntry { Buffer = buf, Index = lastIdx, Found = true };
77+
return new LogBufferEntry(buf, lastIdx, true);
8078
}
8179

8280
// Layer 1: Adjacent buffer prediction — O(1) for buffer boundary crossings
@@ -87,7 +85,7 @@ private LogBufferEntry TryFindBufferWithIndex (int lineNum)
8785
{
8886
_lastBufferIndex.Value = lastIdx + 1;
8987
UpdateLru(next);
90-
return new LogBufferEntry { Buffer = next, Index = lastIdx + 1, Found = true };
88+
return new LogBufferEntry(next, lastIdx + 1, true);
9189
}
9290
}
9391

@@ -98,7 +96,7 @@ private LogBufferEntry TryFindBufferWithIndex (int lineNum)
9896
{
9997
_lastBufferIndex.Value = lastIdx - 1;
10098
UpdateLru(prev);
101-
return new LogBufferEntry { Buffer = prev, Index = lastIdx - 1, Found = true };
99+
return new LogBufferEntry(prev, lastIdx - 1, true);
102100
}
103101
}
104102
}
@@ -112,7 +110,7 @@ private LogBufferEntry TryFindBufferWithIndex (int lineNum)
112110
{
113111
_lastBufferIndex.Value = guess;
114112
UpdateLru(buf);
115-
return new LogBufferEntry { Buffer = buf, Index = guess, Found = true };
113+
return new LogBufferEntry(buf, guess, true);
116114
}
117115
}
118116

@@ -137,17 +135,19 @@ private LogBufferEntry TryFindBufferWithIndex (int lineNum)
137135
{
138136
_lastBufferIndex.Value = idx;
139137
UpdateLru(buf);
140-
return new LogBufferEntry { Buffer = buf, Index = idx, Found = true };
138+
return new LogBufferEntry(buf, idx, true);
141139
}
142140
}
143141
#if DEBUG
144142
long endTime = Environment.TickCount;
145143
_logger.Debug($"TryFindBufferWithIndex({lineNum}) duration: {endTime - startTime} ms.");
146144
#endif
147-
return new LogBufferEntry { Buffer = null, Index = -1, Found = false };
145+
return new LogBufferEntry(null, -1, false);
148146
}
149147

150-
// --- Navigation: multi-file traversal ---
148+
#endregion
149+
150+
#region Navigation: multi-file traversal
151151

152152
/// <summary>
153153
/// Finds the start line of the next file segment after <paramref name="lineNum"/>. Caller must hold at least a read
@@ -236,9 +236,9 @@ private LogBufferEntry TryFindBufferWithIndex (int lineNum)
236236
return resultBuffer;
237237
}
238238

239-
// ─────────────────────────────────────────────
240-
// Mutation — called during reads and rollover
241-
// ─────────────────────────────────────────────
239+
#endregion
240+
241+
#region Mutation — called during reads and rollover
242242

243243
/// <summary>
244244
/// Adds a buffer to the index and updates LRU tracking. Caller must hold a write lock.
@@ -297,9 +297,9 @@ public void Clear ()
297297
_isLineCountDirty = true;
298298
}
299299

300-
// ─────────────────────────────────────────────
301-
// LRU eviction
302-
// ─────────────────────────────────────────────
300+
#endregion
301+
302+
#region LRU eviction
303303

304304
/// <summary>
305305
/// Removes least-recently-used entries when cache exceeds max size. Evicts content but preserves metadata so
@@ -404,7 +404,7 @@ public void ClearLru (LogBufferPool pool)
404404
_logger.Info(CultureInfo.InvariantCulture, "Clearing done.");
405405
}
406406

407-
// --- Read access ---
407+
#endregion
408408

409409
/// <summary>
410410
/// Gets the number of buffers.
@@ -460,17 +460,17 @@ public int TotalLineCount
460460
/// </summary>
461461
public int LruCacheCount => _lruCacheDict.Count;
462462

463-
// ─────────────────────────────────────────────
464-
// Lock management — using-scoped only
465-
// ─────────────────────────────────────────────
463+
#region Lock management — using-scoped only
466464

467465
public ReadLockScope AcquireReadLock () => new(_lock);
466+
468467
public WriteLockScope AcquireWriteLock () => new(_lock);
468+
469469
public UpgradeableReadLockScope AcquireUpgradeableReadLock () => new(_lock);
470470

471-
// ─────────────────────────────────────────────
472-
// Diagnostics
473-
// ─────────────────────────────────────────────
471+
#endregion
472+
473+
#region Diagnostics
474474

475475
/// <summary>
476476
/// Creates an immutable point-in-time capture of the index state. Acquires its own read lock internally.
@@ -503,9 +503,9 @@ public BufferIndexSnapshot CreateSnapshot ()
503503
};
504504
}
505505

506-
// ─────────────────────────────────────────────
507-
// Internal helpers
508-
// ─────────────────────────────────────────────
506+
#endregion
507+
508+
#region Internal Helpers
509509

510510
public void ResetThreadLocalCache () => _lastBufferIndex.Value = -1;
511511

@@ -526,11 +526,12 @@ public void Dispose ()
526526
_lastBufferIndex.Dispose();
527527
_lock.Dispose();
528528
}
529+
530+
#endregion
529531
}
530532

531-
// ─────────────────────────────────────────────
532-
// Lock scope structs
533-
// ─────────────────────────────────────────────
533+
#region Lock scope structs
534+
534535
public readonly ref struct ReadLockScope
535536
{
536537
private readonly ReaderWriterLockSlim _lock;
@@ -602,11 +603,13 @@ public WriteLockUpgradeScope (ReaderWriterLockSlim rwls)
602603
public void Dispose () => _lock.ExitWriteLock();
603604
}
604605

605-
public sealed record LogBufferEntry
606+
#endregion
607+
608+
public readonly struct LogBufferEntry (LogBuffer? buffer, int index, bool found)
606609
{
607-
public LogBuffer Buffer { get; set; }
610+
public LogBuffer? Buffer { get; } = buffer;
608611

609-
public int Index { get; set; }
612+
public int Index { get; } = index;
610613

611-
public bool Found { get; set; }
614+
public bool Found { get; } = found;
612615
}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ private LogfileReader (string[] fileNames, EncodingOptions encodingOptions, bool
9898

9999
_bufferPool = new LogBufferPool(_max_buffers * 2);
100100

101-
//InitLruBuffers();
102101
_bufferIndex = new BufferIndex(_max_buffers, _maxLinesPerBuffer);
103102

104103
ILogFileInfo fileInfo = null;
@@ -154,7 +153,7 @@ private LogfileReader (string[] fileNames, EncodingOptions encodingOptions, bool
154153

155154
#region Properties
156155

157-
/// <summary>For tests and diagnostics. Replaces GetBufferList().</summary>
156+
/// <summary>For tests and diagnostics.</summary>
158157
internal BufferIndex BufferIndex => _bufferIndex;
159158

160159
/// <summary>

0 commit comments

Comments
 (0)