Skip to content

Commit cd7b921

Browse files
committed
TransformerImpl: Cache a list of defer-Transformers and reuse them if possible
1 parent 75e3ed1 commit cd7b921

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

src/Core/Transformation/Transformer.cs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public bool TryConvert(TStaticSource source, ITransformer _, ITransformer __, [N
3939
private static readonly MethodInfo GetConverterMethodInfo = typeof(TransformerImpl).GetMethod(nameof(GetUnifiedConverter), BindingFlags.Instance | BindingFlags.NonPublic)!;
4040

4141
private readonly TransformerImpl _recurse;
42+
private TransformerImpl?[]? _deferTransformers;
4243
private readonly FastImmutableList<IConverterFactory> _converterFactories;
4344
private readonly ConcurrentDictionary<(IGremlinQueryEnvironment, Type, Type, Type), object> _unifiedConverters = new();
4445

@@ -98,7 +99,41 @@ private IConverter<TStaticSource, TTarget> GetUnifiedConverter<TStaticSource, TA
9899
for (var i = _converterFactories.Count - 1; i >= 0; i--)
99100
{
100101
if (_converterFactories[i].TryCreate<TActualSource, TTarget>(environment) is { } converter)
101-
list.Add((converter, new TransformerImpl(_converterFactories[..i], this)));
102+
{
103+
TransformerImpl? deferTransformer = null;
104+
var deferTransformers = _deferTransformers;
105+
106+
while (true)
107+
{
108+
if (deferTransformers is { } existingDeferTransformers)
109+
{
110+
if (existingDeferTransformers[i] is { } existingDeferTransformer)
111+
{
112+
deferTransformer = existingDeferTransformer;
113+
114+
break;
115+
}
116+
else
117+
{
118+
deferTransformer = new TransformerImpl(_converterFactories[..i], this);
119+
120+
if (Interlocked.CompareExchange(ref deferTransformers[i], deferTransformer, null) is { } otherDeferTransformer)
121+
deferTransformer = otherDeferTransformer;
122+
123+
break;
124+
}
125+
}
126+
else
127+
{
128+
deferTransformers = new TransformerImpl[_converterFactories.Count];
129+
130+
if (Interlocked.CompareExchange(ref _deferTransformers, deferTransformers, null) is { } otherDeferTransformers)
131+
deferTransformers = otherDeferTransformers;
132+
}
133+
}
134+
135+
list.Add((converter, deferTransformer));
136+
}
102137
}
103138

104139
return new UnifiedConverter<TStaticSource, TActualSource, TTarget>([.. list], _recurse);

0 commit comments

Comments
 (0)