Skip to content

Commit 5cc7529

Browse files
committed
WIP cache
1 parent 4756289 commit 5cc7529

File tree

4 files changed

+65
-160
lines changed

4 files changed

+65
-160
lines changed

NTDLS.ExpressionParser/Expression.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,13 @@ public Expression(string text, ExpressionOptions? options = null)
6969
State.Reset(Sanitized);
7070
State.ApplyParameters(Sanitized, _definedParameters);
7171

72-
bool isCacheable = ExpressionFunctions.Count == 0;
73-
7472
bool isComplete;
7573
do
7674
{
7775
//Get a sub-expression from the whole expression.
7876
isComplete = AcquireSubexpression(out int startIndex, out int endIndex, out var subExpression);
7977
//Compute the sub-expression.
80-
var resultString = subExpression.Compute(isCacheable);
78+
var resultString = subExpression.Compute();
8179
//Replace the sub-expression in the whole expression with the result from the sub-expression computation.
8280
State.WorkingText = ReplaceRange(State.WorkingText, startIndex, endIndex, resultString);
8381
} while (!isComplete);
@@ -105,8 +103,6 @@ public Expression(string text, ExpressionOptions? options = null)
105103

106104
work.AppendLine("{");
107105

108-
bool isCacheable = ExpressionFunctions.Count == 0;
109-
110106
bool isComplete;
111107
do
112108
{
@@ -117,7 +113,7 @@ public Expression(string text, ExpressionOptions? options = null)
117113
work.Append(" " + friendlySubExpression);
118114

119115
//Compute the sub-expression.
120-
var resultString = subExpression.Compute(isCacheable);
116+
var resultString = subExpression.Compute();
121117

122118
work.AppendLine($" = {SwapInCacheValues(resultString)}");
123119

NTDLS.ExpressionParser/ExpressionState.cs

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@ internal class ExpressionState
1212
public string WorkingText { get; set; } = string.Empty;
1313
public readonly StringBuilder Buffer;
1414

15-
private int _nextPlaceholderCacheSlot = 0;
15+
//private int _nextPreParsedCacheSlot = 0;
16+
//private PreParsedCacheItem[] _preParsedCache = [];
17+
18+
private int _nextParsedResultCacheSlot = 0;
1619
private PreComputedCacheItem[] _preComputedCache = [];
1720
private int _nextPreComputedCacheSlot = 0;
1821
private int _operationCount = 0;
19-
private PlaceholderCacheItem?[] _placeholderCache = [];
22+
private ParsedResultCacheItem[] _parsedResultCache = [];
2023
private readonly ExpressionOptions _options;
21-
private bool _isPlaceholderCacheHydrated = false;
24+
private bool _isParsedResultCacheHydrated = false;
2225

2326
public ExpressionState(Sanitized sanitized, ExpressionOptions options)
2427
{
@@ -28,9 +31,9 @@ public ExpressionState(Sanitized sanitized, ExpressionOptions options)
2831
WorkingText = sanitized.Text;
2932
_operationCount = sanitized.OperationCount;
3033
_nextPreComputedCacheSlot = sanitized.ConsumedPreComputedCacheSlots;
31-
_preComputedCache = new PreComputedCacheItem[sanitized.OperationCount];
32-
_placeholderCache = new PlaceholderCacheItem?[_operationCount];
33-
_nextPlaceholderCacheSlot = 0;
34+
_preComputedCache = new PreComputedCacheItem[_operationCount + 10];
35+
_parsedResultCache = new ParsedResultCacheItem[_operationCount + 10];
36+
_nextParsedResultCacheSlot = 0;
3437

3538
for (int i = 0; i < sanitized.ConsumedPreComputedCacheSlots; i++)
3639
{
@@ -50,37 +53,30 @@ public ExpressionState(ExpressionOptions options, int preAllocation)
5053
_options = options;
5154
}
5255

53-
#region Pre-Parsed Cache Management.
54-
55-
public int ConsumeNextPlaceholderCacheSlot()
56-
{
57-
return _nextPlaceholderCacheSlot++;
58-
}
56+
#region Parsed Result Cache Management.
5957

6058
[MethodImpl(MethodImplOptions.AggressiveInlining)]
61-
public bool TryGetPlaceholderCache(int slot, [NotNullWhen(true)] out PlaceholderCacheItem value)
59+
public bool TryGetParsedResultCache([NotNullWhen(true)] out ParsedResultCacheItem value, out int slot)
6260
{
63-
if (slot < _placeholderCache.Length)
61+
slot = _nextParsedResultCacheSlot++;
62+
63+
if (slot < _nextParsedResultCacheSlot - 1)
6464
{
65-
var cached = _placeholderCache[slot];
66-
if (cached != null)
67-
{
68-
value = cached.Value;
69-
return true;
70-
}
65+
value = _parsedResultCache[slot];
66+
return true;
7167
}
7268
value = default;
7369
return false;
7470
}
7571

7672
[MethodImpl(MethodImplOptions.AggressiveInlining)]
77-
public void StorePlaceholderCache(int slot, PlaceholderCacheItem value)
73+
public void StoreParsedResultCache(int slot, ParsedResultCacheItem value)
7874
{
79-
if (slot >= _placeholderCache.Length) //Resize the cache if needed.
75+
if (slot >= _parsedResultCache.Length) //Resize the cache if needed.
8076
{
81-
Array.Resize(ref _placeholderCache, (_placeholderCache.Length + 1) * 2);
77+
Array.Resize(ref _parsedResultCache, (_parsedResultCache.Length + 1) * 2);
8278
}
83-
_placeholderCache[slot] = value;
79+
_parsedResultCache[slot] = value;
8480
}
8581

8682
#endregion
@@ -130,31 +126,32 @@ public PreComputedCacheItem GetPreComputedCacheItem(ReadOnlySpan<char> span)
130126

131127
public void HydrateTemplateParsedCache(int expressionHash)
132128
{
133-
if (!_isPlaceholderCacheHydrated)
129+
if (!_isParsedResultCacheHydrated)
134130
{
135131
lock (this)
136132
{
137-
if (!_isPlaceholderCacheHydrated)
133+
if (!_isParsedResultCacheHydrated)
138134
{
139135
if (Utility.PersistentCaches.TryGetValue(expressionHash, out CachedState? entry) && entry != null)
140136
{
141-
entry.State.HydratePlaceholderCache(_placeholderCache);
137+
entry.State.HydrateParsedResultCache(_parsedResultCache);
142138
}
143-
_isPlaceholderCacheHydrated = true;
139+
_isParsedResultCacheHydrated = true;
144140
}
145141
}
146142
}
147143
}
148144

149-
private void HydratePlaceholderCache(PlaceholderCacheItem?[] populatedCache)
145+
private void HydrateParsedResultCache(ParsedResultCacheItem[] populatedCache)
150146
{
151-
Interlocked.Exchange(ref _placeholderCache, populatedCache);
147+
Interlocked.Exchange(ref _parsedResultCache, populatedCache);
152148
}
153149

154150
public void Reset(Sanitized sanitized)
155151
{
152+
WorkingText = sanitized.Text;
156153
_nextPreComputedCacheSlot = sanitized.ConsumedPreComputedCacheSlots;
157-
_nextPlaceholderCacheSlot = 0;
154+
_nextParsedResultCacheSlot = 0;
158155
}
159156

160157
public ExpressionState Clone()
@@ -165,13 +162,13 @@ public ExpressionState Clone()
165162
_operationCount = _operationCount,
166163
_nextPreComputedCacheSlot = _nextPreComputedCacheSlot,
167164
_preComputedCache = new PreComputedCacheItem[_preComputedCache.Length],
168-
_placeholderCache = new PlaceholderCacheItem?[_placeholderCache.Length],
169-
_nextPlaceholderCacheSlot = 0,
170-
_isPlaceholderCacheHydrated = _isPlaceholderCacheHydrated
165+
_parsedResultCache = new ParsedResultCacheItem[_parsedResultCache.Length],
166+
_nextParsedResultCacheSlot = 0,
167+
_isParsedResultCacheHydrated = _isParsedResultCacheHydrated
171168
};
172169

173170
Array.Copy(_preComputedCache, clone._preComputedCache, _preComputedCache.Length); //Copy any pre-computed NULLs.
174-
Array.Copy(_placeholderCache, clone._placeholderCache, _placeholderCache.Length);
171+
Array.Copy(_parsedResultCache, clone._parsedResultCache, _parsedResultCache.Length);
175172

176173
return clone;
177174
}

0 commit comments

Comments
 (0)