Skip to content

Commit 0167524

Browse files
DateTimeFormatter to use local byte[] array, as opposed to renting from pool. (#4503) (#4523)
The minimum buffer size that can be rented from the shared memory pool is 65535 bytes. This amount of memory for the purposes of deserialising the day component of a string timespan is excessive. This commit changes the procedure to use a local byte array. Co-authored-by: Stuart Cam <stuart.cam@elastic.co>
1 parent 41360bb commit 0167524

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

src/Elasticsearch.Net/Utf8Json/Formatters/DateTimeFormatter.cs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -929,20 +929,14 @@ public TimeSpan Deserialize(ref JsonReader reader, IJsonFormatterResolver format
929929
var day = 0;
930930
if (hasDay)
931931
{
932-
var poolArray = JsonSerializer.MemoryPool.Rent();
933-
try
932+
const int maxDayLength = 8 + 1; // {Day}.
933+
var dayCharacters = new byte[maxDayLength];
934+
for (; array[i] != '.'; i++)
934935
{
935-
for (; array[i] != '.'; i++)
936-
{
937-
poolArray[day++] = array[i];
938-
}
939-
day = new JsonReader(poolArray).ReadInt32();
940-
i++; // skip '.'
941-
}
942-
finally
943-
{
944-
JsonSerializer.MemoryPool.Return(poolArray);
936+
dayCharacters[day++] = array[i];
945937
}
938+
day = new JsonReader(dayCharacters).ReadInt32();
939+
i++; // skip '.'
946940
}
947941

948942
var hour = (array[i++] - (byte)'0') * 10 + (array[i++] - (byte)'0');

tests/Tests.Reproduce/TimeSpanSerialization.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,27 @@ namespace Tests.Reproduce
99
{
1010
public class TimeSpanSerialization
1111
{
12+
[U]
13+
public void SerializeMaxTimeSpansAsTicksAndStrings()
14+
{
15+
var timeSpans = new TimeSpans(TimeSpan.MaxValue);
16+
var client = new ElasticClient();
17+
18+
var json = client.RequestResponseSerializer.SerializeToString(timeSpans);
19+
20+
json.Should()
21+
.Be("{\"default\":9223372036854775807,\"defaultNullable\":9223372036854775807,\"string\":\"10675199.02:48:05.4775807\",\"stringNullable\":\"10675199.02:48:05.4775807\"}");
22+
23+
TimeSpans deserialized;
24+
using (var stream = client.ConnectionSettings.MemoryStreamFactory.Create(Encoding.UTF8.GetBytes(json)))
25+
deserialized = client.RequestResponseSerializer.Deserialize<TimeSpans>(stream);
26+
27+
timeSpans.Default.Should().Be(deserialized.Default);
28+
timeSpans.DefaultNullable.Should().Be(deserialized.DefaultNullable);
29+
timeSpans.String.Should().Be(deserialized.String);
30+
timeSpans.StringNullable.Should().Be(deserialized.StringNullable);
31+
}
32+
1233
[U]
1334
public void SerializeTimeSpansAsTicksAndStrings()
1435
{

0 commit comments

Comments
 (0)