Skip to content

Commit a42648b

Browse files
Avoid multiple enumeration of IEnumerable PostData (#4428) (#4431)
This commit updates PostData to use the enumerator to enumerate IEnumerable<string> or IEnumerable<object>, avoiding enumerating twice, once when checking .Any() and again when calling foreach. Closes #4388 Co-authored-by: Russ Cam <russ.cam@elastic.co>
1 parent 0fa6b3b commit a42648b

File tree

1 file changed

+44
-18
lines changed

1 file changed

+44
-18
lines changed

src/Elasticsearch.Net/Transport/PostData.cs

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -187,28 +187,41 @@ public override void Write(Stream writableStream, IConnectionConfigurationValues
187187
break;
188188

189189
case PostType.EnumerableOfString:
190-
if (!_enumerableOfStrings.HasAny()) return;
190+
{
191+
if (_enumerableOfStrings == null)
192+
return;
193+
194+
using var enumerator = _enumerableOfStrings.GetEnumerator();
195+
if (!enumerator.MoveNext())
196+
return;
191197

192198
BufferIfNeeded(settings, ref buffer, ref stream);
193-
foreach (var s in _enumerableOfStrings)
199+
do
194200
{
195-
var bytes = s.Utf8Bytes();
201+
var bytes = enumerator.Current.Utf8Bytes();
196202
stream.Write(bytes, 0, bytes.Length);
197203
stream.Write(NewLineByteArray, 0, 1);
198-
}
204+
} while (enumerator.MoveNext());
199205
break;
200-
206+
}
201207
case PostType.EnumerableOfObject:
202-
if (!_enumerableOfObject.HasAny()) return;
208+
{
209+
if (_enumerableOfObject == null)
210+
return;
211+
212+
using var enumerator = _enumerableOfObject.GetEnumerator();
213+
if (!enumerator.MoveNext())
214+
return;
203215

204216
BufferIfNeeded(settings, ref buffer, ref stream);
205-
foreach (var o in _enumerableOfObject)
217+
do
206218
{
219+
var o = enumerator.Current;
207220
settings.RequestResponseSerializer.Serialize(o, stream, SerializationFormatting.None);
208221
stream.Write(NewLineByteArray, 0, 1);
209-
}
222+
} while (enumerator.MoveNext());
210223
break;
211-
224+
}
212225
case PostType.StreamHandler:
213226
var streamHandlerException = $"{nameof(PostData)} cannot handle {nameof(PostType.StreamHandler)} data. "
214227
+ $"Use {typeof(StreamableData<>).FullName} through {nameof(PostData)}.{nameof(StreamHandler)}<T>() for streamable data";
@@ -267,29 +280,42 @@ public override async Task WriteAsync(Stream writableStream, IConnectionConfigur
267280
break;
268281

269282
case PostType.EnumerableOfString:
270-
if (!_enumerableOfStrings.HasAny()) return;
283+
{
284+
if (_enumerableOfStrings == null)
285+
return;
286+
287+
using var enumerator = _enumerableOfStrings.GetEnumerator();
288+
if (!enumerator.MoveNext())
289+
return;
271290

272291
BufferIfNeeded(settings, ref buffer, ref stream);
273-
foreach (var s in _enumerableOfStrings)
292+
do
274293
{
275-
var bytes = s.Utf8Bytes();
294+
var bytes = enumerator.Current.Utf8Bytes();
276295
await stream.WriteAsync(bytes, 0, bytes.Length, cancellationToken).ConfigureAwait(false);
277296
await stream.WriteAsync(NewLineByteArray, 0, 1, cancellationToken).ConfigureAwait(false);
278-
}
297+
} while (enumerator.MoveNext());
279298
break;
280-
299+
}
281300
case PostType.EnumerableOfObject:
282-
if (!_enumerableOfObject.HasAny()) return;
301+
{
302+
if (_enumerableOfObject == null)
303+
return;
304+
305+
using var enumerator = _enumerableOfObject.GetEnumerator();
306+
if (!enumerator.MoveNext())
307+
return;
283308

284309
BufferIfNeeded(settings, ref buffer, ref stream);
285-
foreach (var o in _enumerableOfObject)
310+
do
286311
{
312+
var o = enumerator.Current;
287313
await settings.RequestResponseSerializer.SerializeAsync(o, stream, SerializationFormatting.None, cancellationToken)
288314
.ConfigureAwait(false);
289315
await stream.WriteAsync(NewLineByteArray, 0, 1, cancellationToken).ConfigureAwait(false);
290-
}
316+
} while (enumerator.MoveNext());
291317
break;
292-
318+
}
293319
case PostType.StreamHandler:
294320
throw new Exception("PostData is not expected/capable to handle streamable data, use StreamableData instead");
295321

0 commit comments

Comments
 (0)