From 2692e5355a40ef4893e4ada9c2d5731375a82056 Mon Sep 17 00:00:00 2001 From: Alistair Evans Date: Fri, 25 Oct 2019 14:28:40 +0100 Subject: [PATCH] CSHARP-1525 - Add DiscardBufferedData method to JsonReader, so consumers of the reader can choose to clear the memory use of the reader when reading large JSON documents. --- src/MongoDB.Bson/IO/JsonReader.cs | 13 ++++++-- .../MongoDB.Bson.Tests/IO/JsonReaderTests.cs | 33 +++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/MongoDB.Bson/IO/JsonReader.cs b/src/MongoDB.Bson/IO/JsonReader.cs index f33ec492c3c..a5d64f106b6 100644 --- a/src/MongoDB.Bson/IO/JsonReader.cs +++ b/src/MongoDB.Bson/IO/JsonReader.cs @@ -111,7 +111,7 @@ public JsonReader(TextReader textReader, JsonReaderSettings settings) { } - private JsonReader(JsonBuffer buffer, JsonReaderSettings settings) + internal JsonReader(JsonBuffer buffer, JsonReaderSettings settings) : base(settings) { _buffer = buffer; @@ -119,7 +119,16 @@ private JsonReader(JsonBuffer buffer, JsonReaderSettings settings) _context = new JsonReaderContext(null, ContextType.TopLevel); } - // public methods + // public methods + /// + /// Resets the underlying buffer; use this if you are streaming very large BSON documents and want to reduce memory + /// use. + /// + public void DiscardBufferedData() + { + _buffer.ResetBuffer(); + } + /// /// Closes the reader. /// diff --git a/tests/MongoDB.Bson.Tests/IO/JsonReaderTests.cs b/tests/MongoDB.Bson.Tests/IO/JsonReaderTests.cs index 823ed0dc1d3..a751992cdf8 100644 --- a/tests/MongoDB.Bson.Tests/IO/JsonReaderTests.cs +++ b/tests/MongoDB.Bson.Tests/IO/JsonReaderTests.cs @@ -1600,6 +1600,39 @@ public void IsValidBinaryDataSubTypeString_should_return_true_when_value_is_vali result.Should().BeTrue(); } } + + [Fact] + public void Can_discard_buffered_data() + { + var json = "[ " + string.Join(",", Enumerable.Repeat("{ \"a\" : { \"x\" : 1 } }", 1024)) + "]"; + var textReader = new StreamReader(new MemoryStream(Encoding.UTF8.GetBytes(json))); + + var buffer = new JsonBuffer(textReader); + using (var reader = new JsonReader(buffer, JsonReaderSettings.Defaults)) + { + reader.ReadStartArray(); + + // Deserialize some. + for (int idx = 0; idx < 512; idx++) + { + BsonSerializer.Deserialize(reader); + } + + buffer.Position.Should().BeGreaterThan(512); + + reader.DiscardBufferedData(); + + buffer.Position.Should().Be(0); + + // Make sure we can continue deserializing after the discard. + for (int idx = 0; idx < 512; idx++) + { + BsonSerializer.Deserialize(reader); + } + + reader.ReadEndArray(); + } + } } public static class JsonReaderReflector