Skip to content

Commit e5d66a3

Browse files
committed
WIP: Cache.
1 parent 5cc7529 commit e5d66a3

File tree

7 files changed

+80
-202
lines changed

7 files changed

+80
-202
lines changed

NTDLS.ExpressionParser/Expression.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ public Expression(string text, ExpressionOptions? options = null)
8282

8383
if (State.WorkingText[0] == '$')
8484
{
85-
State.HydrateTemplateParsedCache(_expressionHash);
86-
return State.GetPreComputedCacheItem(State.WorkingText.AsSpan()[1..^1]).ComputedValue;
85+
//State.HydrateTemplateParsedCache(_expressionHash);
86+
return State.GetPlaceholderCacheItem(State.WorkingText.AsSpan()[1..^1]).ComputedValue;
8787
}
8888

89-
State.HydrateTemplateParsedCache(_expressionHash);
89+
//State.HydrateTemplateParsedCache(_expressionHash);
9090
return StringToDouble(State.WorkingText);
9191
}
9292

@@ -126,13 +126,13 @@ public Expression(string text, ExpressionOptions? options = null)
126126
if (State.WorkingText[0] == '$')
127127
{
128128
showWork = work.ToString();
129-
State.HydrateTemplateParsedCache(_expressionHash);
130-
return State.GetPreComputedCacheItem(State.WorkingText.AsSpan()[1..^1]).ComputedValue;
129+
//State.HydrateTemplateParsedCache(_expressionHash);
130+
return State.GetPlaceholderCacheItem(State.WorkingText.AsSpan()[1..^1]).ComputedValue;
131131
}
132132

133133
showWork = work.ToString();
134134

135-
State.HydrateTemplateParsedCache(_expressionHash);
135+
//State.HydrateTemplateParsedCache(_expressionHash);
136136
return StringToDouble(State.WorkingText);
137137
}
138138

@@ -270,7 +270,7 @@ private string SwapInCacheValues(string text)
270270
if (begIndex >= 0 && endIndex > begIndex)
271271
{
272272
var cacheKey = copy.Substring(begIndex + 1, (endIndex - begIndex) - 1);
273-
copy = copy.Replace($"${cacheKey}$", State.GetPreComputedCacheItem(cacheKey).ComputedValue?.ToString(_precisionFormat) ?? "null");
273+
copy = copy.Replace($"${cacheKey}$", State.GetPlaceholderCacheItem(cacheKey).ComputedValue?.ToString(_precisionFormat) ?? "null");
274274
}
275275
else
276276
{
@@ -358,7 +358,7 @@ internal bool AcquireSubexpression(out int outStartIndex, out int outEndIndex, o
358358
}
359359
else if (span[0] == '$')
360360
{
361-
return State.GetPreComputedCacheItem(span[1..^1]).ComputedValue;
361+
return State.GetPlaceholderCacheItem(span[1..^1]).ComputedValue;
362362
}
363363

364364
if (Options.UseFastFloatingPointParser)

NTDLS.ExpressionParser/ExpressionState.cs

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

15-
//private int _nextPreParsedCacheSlot = 0;
16-
//private PreParsedCacheItem[] _preParsedCache = [];
17-
18-
private int _nextParsedResultCacheSlot = 0;
19-
private PreComputedCacheItem[] _preComputedCache = [];
20-
private int _nextPreComputedCacheSlot = 0;
15+
private int _nextPositionStepCacheSlot = 0;
16+
private PlaceholderCacheItem[] _placeholderCache = [];
17+
private int _nextPlaceholderCacheSlot = 0;
2118
private int _operationCount = 0;
22-
private ParsedResultCacheItem[] _parsedResultCache = [];
19+
private PositionStepCacheItem[] _positionStepCache = [];
2320
private readonly ExpressionOptions _options;
24-
private bool _isParsedResultCacheHydrated = false;
21+
private bool _isPositionStepCacheHydrated = false;
2522

2623
public ExpressionState(Sanitized sanitized, ExpressionOptions options)
2724
{
@@ -30,14 +27,14 @@ public ExpressionState(Sanitized sanitized, ExpressionOptions options)
3027

3128
WorkingText = sanitized.Text;
3229
_operationCount = sanitized.OperationCount;
33-
_nextPreComputedCacheSlot = sanitized.ConsumedPreComputedCacheSlots;
34-
_preComputedCache = new PreComputedCacheItem[_operationCount + 10];
35-
_parsedResultCache = new ParsedResultCacheItem[_operationCount + 10];
36-
_nextParsedResultCacheSlot = 0;
30+
_nextPlaceholderCacheSlot = sanitized.ConsumedPlaceholderCacheSlots;
31+
_placeholderCache = new PlaceholderCacheItem[_operationCount + 10];
32+
_positionStepCache = new PositionStepCacheItem[_operationCount + 10];
33+
_nextPositionStepCacheSlot = 0;
3734

38-
for (int i = 0; i < sanitized.ConsumedPreComputedCacheSlots; i++)
35+
for (int i = 0; i < sanitized.ConsumedPlaceholderCacheSlots; i++)
3936
{
40-
_preComputedCache[i] = new PreComputedCacheItem()
37+
_placeholderCache[i] = new PlaceholderCacheItem()
4138
{
4239
ComputedValue = options.DefaultNullValue,
4340
IsVariable = false,
@@ -53,53 +50,53 @@ public ExpressionState(ExpressionOptions options, int preAllocation)
5350
_options = options;
5451
}
5552

56-
#region Parsed Result Cache Management.
53+
#region Position Step Cache Management.
5754

5855
[MethodImpl(MethodImplOptions.AggressiveInlining)]
59-
public bool TryGetParsedResultCache([NotNullWhen(true)] out ParsedResultCacheItem value, out int slot)
56+
public bool TryGetPositionStepCache([NotNullWhen(true)] out PositionStepCacheItem value, out int slot)
6057
{
61-
slot = _nextParsedResultCacheSlot++;
58+
slot = _nextPositionStepCacheSlot++;
6259

63-
if (slot < _nextParsedResultCacheSlot - 1)
60+
if (slot < _nextPositionStepCacheSlot - 1)
6461
{
65-
value = _parsedResultCache[slot];
62+
value = _positionStepCache[slot];
6663
return true;
6764
}
6865
value = default;
6966
return false;
7067
}
7168

7269
[MethodImpl(MethodImplOptions.AggressiveInlining)]
73-
public void StoreParsedResultCache(int slot, ParsedResultCacheItem value)
70+
public void StorePositionStepCache(int slot, PositionStepCacheItem value)
7471
{
75-
if (slot >= _parsedResultCache.Length) //Resize the cache if needed.
72+
if (slot >= _positionStepCache.Length) //Resize the cache if needed.
7673
{
77-
Array.Resize(ref _parsedResultCache, (_parsedResultCache.Length + 1) * 2);
74+
Array.Resize(ref _positionStepCache, (_positionStepCache.Length + 1) * 2);
7875
}
79-
_parsedResultCache[slot] = value;
76+
_positionStepCache[slot] = value;
8077
}
8178

8279
#endregion
8380

84-
#region Pre-Computed Cache Management.
81+
#region Placeholder Cache Management.
8582

86-
public int ConsumeNextPreComputedCacheSlot(out string cacheKey)
83+
public int ConsumeNextPlaceholderCacheSlot(out string cacheKey)
8784
{
88-
int cacheSlot = _nextPreComputedCacheSlot++;
85+
int cacheSlot = _nextPlaceholderCacheSlot++;
8986
cacheKey = $"${cacheSlot}$";
9087
return cacheSlot;
9188
}
9289

93-
public string StorePreComputedCacheItem(double? value, bool isVariable = false)
90+
public string StorePlaceholderCacheItem(double? value, bool isVariable = false)
9491
{
95-
var cacheSlot = ConsumeNextPreComputedCacheSlot(out var cacheKey);
92+
var cacheSlot = ConsumeNextPlaceholderCacheSlot(out var cacheKey);
9693

97-
if (cacheSlot >= _preComputedCache.Length) //Resize the cache if needed.
94+
if (cacheSlot >= _placeholderCache.Length) //Resize the cache if needed.
9895
{
99-
Array.Resize(ref _preComputedCache, (_preComputedCache.Length + 1) * 2);
96+
Array.Resize(ref _placeholderCache, (_placeholderCache.Length + 1) * 2);
10097
}
10198

102-
_preComputedCache[cacheSlot] = new PreComputedCacheItem()
99+
_placeholderCache[cacheSlot] = new PlaceholderCacheItem()
103100
{
104101
IsVariable = isVariable,
105102
ComputedValue = value
@@ -108,50 +105,52 @@ public string StorePreComputedCacheItem(double? value, bool isVariable = false)
108105
return cacheKey;
109106
}
110107

111-
public PreComputedCacheItem GetPreComputedCacheItem(ReadOnlySpan<char> span)
108+
public PlaceholderCacheItem GetPlaceholderCacheItem(ReadOnlySpan<char> span)
112109
{
113110
switch (span.Length)
114111
{
115112
case 1:
116-
return _preComputedCache[span[0] - '0'];
113+
return _placeholderCache[span[0] - '0'];
117114
default:
118115
int index = 0;
119116
for (int i = 0; i < span.Length; i++)
120117
index = index * 10 + (span[i] - '0');
121-
return _preComputedCache[index];
118+
return _placeholderCache[index];
122119
}
123120
}
124121

125122
#endregion
126123

124+
/*
127125
public void HydrateTemplateParsedCache(int expressionHash)
128126
{
129-
if (!_isParsedResultCacheHydrated)
127+
if (!_isPositionStepCacheHydrated)
130128
{
131129
lock (this)
132130
{
133-
if (!_isParsedResultCacheHydrated)
131+
if (!_isPositionStepCacheHydrated)
134132
{
135133
if (Utility.PersistentCaches.TryGetValue(expressionHash, out CachedState? entry) && entry != null)
136134
{
137-
entry.State.HydrateParsedResultCache(_parsedResultCache);
135+
entry.State.HydratePositionStepCache(_positionStepCache);
138136
}
139-
_isParsedResultCacheHydrated = true;
137+
_isPositionStepCacheHydrated = true;
140138
}
141139
}
142140
}
143141
}
144142
145-
private void HydrateParsedResultCache(ParsedResultCacheItem[] populatedCache)
143+
private void HydratePositionStepCache(PositionStepCacheItem[] populatedCache)
146144
{
147-
Interlocked.Exchange(ref _parsedResultCache, populatedCache);
145+
Interlocked.Exchange(ref _positionStepCache, populatedCache);
148146
}
147+
*/
149148

150149
public void Reset(Sanitized sanitized)
151150
{
152151
WorkingText = sanitized.Text;
153-
_nextPreComputedCacheSlot = sanitized.ConsumedPreComputedCacheSlots;
154-
_nextParsedResultCacheSlot = 0;
152+
_nextPlaceholderCacheSlot = sanitized.ConsumedPlaceholderCacheSlots;
153+
_nextPositionStepCacheSlot = 0;
155154
}
156155

157156
public ExpressionState Clone()
@@ -160,15 +159,15 @@ public ExpressionState Clone()
160159
{
161160
WorkingText = WorkingText,
162161
_operationCount = _operationCount,
163-
_nextPreComputedCacheSlot = _nextPreComputedCacheSlot,
164-
_preComputedCache = new PreComputedCacheItem[_preComputedCache.Length],
165-
_parsedResultCache = new ParsedResultCacheItem[_parsedResultCache.Length],
166-
_nextParsedResultCacheSlot = 0,
167-
_isParsedResultCacheHydrated = _isParsedResultCacheHydrated
162+
_nextPlaceholderCacheSlot = _nextPlaceholderCacheSlot,
163+
_placeholderCache = new PlaceholderCacheItem[_placeholderCache.Length],
164+
_positionStepCache = new PositionStepCacheItem[_positionStepCache.Length],
165+
_nextPositionStepCacheSlot = 0,
166+
_isPositionStepCacheHydrated = _isPositionStepCacheHydrated
168167
};
169168

170-
Array.Copy(_preComputedCache, clone._preComputedCache, _preComputedCache.Length); //Copy any pre-computed NULLs.
171-
Array.Copy(_parsedResultCache, clone._parsedResultCache, _parsedResultCache.Length);
169+
Array.Copy(_placeholderCache, clone._placeholderCache, _placeholderCache.Length); //Copy any pre-computed NULLs.
170+
Array.Copy(_positionStepCache, clone._positionStepCache, _positionStepCache.Length);
172171

173172
return clone;
174173
}
@@ -180,8 +179,8 @@ public void ApplyParameters(Sanitized sanitized, Dictionary<string, double?> def
180179
{
181180
if (definedParameters.TryGetValue(variable, out var value))
182181
{
183-
var cacheSlot = ConsumeNextPreComputedCacheSlot(out var cacheKey);
184-
_preComputedCache[cacheSlot] = new PreComputedCacheItem()
182+
var cacheSlot = ConsumeNextPlaceholderCacheSlot(out var cacheKey);
183+
_placeholderCache[cacheSlot] = new PlaceholderCacheItem()
185184
{
186185
ComputedValue = value ?? _options.DefaultNullValue,
187186
IsVariable = true

NTDLS.ExpressionParser/Sanitized.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
internal class Sanitized
44
{
55
public int OperationCount { get; set; }
6-
public int ConsumedPreComputedCacheSlots { get; set; }
6+
public int ConsumedPlaceholderCacheSlots { get; set; }
77
public string Text { get; set; } = string.Empty;
88
internal HashSet<string> DiscoveredVariables { get; private set; } = new();
99
internal HashSet<string> DiscoveredFunctions { get; private set; } = new();

NTDLS.ExpressionParser/Sanitizer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public static Sanitized Process(string expressionText, ExpressionOptions options
3333
sanitized.OperationCount++;
3434
}
3535

36-
sanitized.ConsumedPreComputedCacheSlots = sanitized.OperationCount;
36+
sanitized.ConsumedPlaceholderCacheSlots = sanitized.OperationCount;
3737

3838
var expressionSpan = expressionText.AsSpan();
3939

NTDLS.ExpressionParser/SubExpression.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,12 @@ internal string Compute()
203203
return Text;
204204
}
205205

206-
return _parentExpression.State.StorePreComputedCacheItem(_parentExpression.StringToDouble(Text));
206+
return _parentExpression.State.StorePlaceholderCacheItem(_parentExpression.StringToDouble(Text));
207207
}
208208

209209
internal void StorePreComputed(int startIndex, int endIndex, double? value)
210210
{
211-
var cacheKey = _parentExpression.State.StorePreComputedCacheItem(value);
211+
var cacheKey = _parentExpression.State.StorePlaceholderCacheItem(value);
212212
Text = _parentExpression.ReplaceRange(Text, startIndex, endIndex, cacheKey);
213213
}
214214

@@ -258,7 +258,7 @@ private bool GetLeftAndRightValues(string operation,
258258
i--;
259259
outParsedLength = (operationIndex - i) - 1;
260260
var cacheKey = span.Slice(operationIndex - outParsedLength + 1, outParsedLength - 2);
261-
var cachedItem = _parentExpression.State.GetPreComputedCacheItem(cacheKey);
261+
var cachedItem = _parentExpression.State.GetPlaceholderCacheItem(cacheKey);
262262
return cachedItem.ComputedValue;
263263
}
264264
else
@@ -300,7 +300,7 @@ private bool GetLeftAndRightValues(string operation,
300300
}
301301
i++;
302302
outParsedLength = i;
303-
var cachedItem = _parentExpression.State.GetPreComputedCacheItem(span.Slice(1, i - 2));
303+
var cachedItem = _parentExpression.State.GetPlaceholderCacheItem(span.Slice(1, i - 2));
304304
return cachedItem.ComputedValue;
305305
}
306306
else

NTDLS.ExpressionParser/Types.cs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,13 @@
55
/// </summary>
66
public delegate double? ExpressionFunction(double[] parameters);
77

8-
internal struct ParsedResultCacheItem
8+
internal struct PositionStepCacheItem
99
{
10-
public double? ParsedValue;
1110
public int BeginPosition;
1211
public int EndPosition;
1312
}
1413

15-
//internal struct PreParsedCacheItem
16-
//{
17-
// public int BeginPosition;
18-
// public int EndPosition;
19-
//}
20-
21-
internal struct PreComputedCacheItem
14+
internal struct PlaceholderCacheItem
2215
{
2316
public double? ComputedValue;
2417
public bool IsVariable;

0 commit comments

Comments
 (0)