From d810aacdcd3af286faa6cb92606f9f16798a9374 Mon Sep 17 00:00:00 2001 From: obligaron Date: Sat, 19 Oct 2024 08:30:44 +0200 Subject: [PATCH 1/3] CSHARP-5348: Add PopContext to Bson*Context where missing --- src/MongoDB.Bson/IO/BsonBinaryWriter.cs | 6 +++--- src/MongoDB.Bson/IO/BsonBinaryWriterContext.cs | 5 +++++ src/MongoDB.Bson/IO/BsonDocumentWriter.cs | 8 ++++---- src/MongoDB.Bson/IO/BsonDocumentWriterContext.cs | 5 +++++ src/MongoDB.Bson/IO/JsonWriter.cs | 6 +++--- src/MongoDB.Bson/IO/JsonWriterContext.cs | 5 +++++ 6 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/MongoDB.Bson/IO/BsonBinaryWriter.cs b/src/MongoDB.Bson/IO/BsonBinaryWriter.cs index 42430ef4eb4..7b9565592ba 100644 --- a/src/MongoDB.Bson/IO/BsonBinaryWriter.cs +++ b/src/MongoDB.Bson/IO/BsonBinaryWriter.cs @@ -290,7 +290,7 @@ public override void WriteEndArray() _bsonStream.WriteByte(0); BackpatchSize(); // size of document - _context = _context.ParentContext; + _context = _context.PopContext(); State = GetNextState(); } @@ -313,7 +313,7 @@ public override void WriteEndDocument() _bsonStream.WriteByte(0); BackpatchSize(); // size of document - _context = _context.ParentContext; + _context = _context.PopContext(); if (_context == null) { State = BsonWriterState.Done; @@ -323,7 +323,7 @@ public override void WriteEndDocument() if (_context.ContextType == ContextType.JavaScriptWithScope) { BackpatchSize(); // size of the JavaScript with scope value - _context = _context.ParentContext; + _context = _context.PopContext(); } State = GetNextState(); } diff --git a/src/MongoDB.Bson/IO/BsonBinaryWriterContext.cs b/src/MongoDB.Bson/IO/BsonBinaryWriterContext.cs index fb791ab4fc3..63bc6d79546 100644 --- a/src/MongoDB.Bson/IO/BsonBinaryWriterContext.cs +++ b/src/MongoDB.Bson/IO/BsonBinaryWriterContext.cs @@ -55,5 +55,10 @@ internal int Index get { return _index; } set { _index = value; } } + + internal BsonBinaryWriterContext PopContext() + { + return _parentContext; + } } } diff --git a/src/MongoDB.Bson/IO/BsonDocumentWriter.cs b/src/MongoDB.Bson/IO/BsonDocumentWriter.cs index 3f77160f1c2..d0507a4b392 100644 --- a/src/MongoDB.Bson/IO/BsonDocumentWriter.cs +++ b/src/MongoDB.Bson/IO/BsonDocumentWriter.cs @@ -195,7 +195,7 @@ public override void WriteEndArray() base.WriteEndArray(); var array = _context.Array; - _context = _context.ParentContext; + _context = _context.PopContext(); WriteValue(array); State = GetNextState(); } @@ -219,15 +219,15 @@ public override void WriteEndDocument() if (_context.ContextType == ContextType.ScopeDocument) { var scope = _context.Document; - _context = _context.ParentContext; + _context = _context.PopContext(); var code = _context.Code; - _context = _context.ParentContext; + _context = _context.PopContext(); WriteValue(new BsonJavaScriptWithScope(code, scope)); } else { var document = _context.Document; - _context = _context.ParentContext; + _context = _context.PopContext(); if (_context != null) { WriteValue(document); diff --git a/src/MongoDB.Bson/IO/BsonDocumentWriterContext.cs b/src/MongoDB.Bson/IO/BsonDocumentWriterContext.cs index 4aa1f6ddd82..049ae09e7fd 100644 --- a/src/MongoDB.Bson/IO/BsonDocumentWriterContext.cs +++ b/src/MongoDB.Bson/IO/BsonDocumentWriterContext.cs @@ -87,5 +87,10 @@ internal string Code { get { return _code; } } + + internal BsonDocumentWriterContext PopContext() + { + return _parentContext; + } } } diff --git a/src/MongoDB.Bson/IO/JsonWriter.cs b/src/MongoDB.Bson/IO/JsonWriter.cs index 39b884c8618..e558e42eb12 100644 --- a/src/MongoDB.Bson/IO/JsonWriter.cs +++ b/src/MongoDB.Bson/IO/JsonWriter.cs @@ -312,7 +312,7 @@ public override void WriteEndArray() base.WriteEndArray(); _textWriter.Write("]"); - _context = _context.ParentContext; + _context = _context.PopContext(); State = GetNextState(); } @@ -344,12 +344,12 @@ public override void WriteEndDocument() if (_context.ContextType == ContextType.ScopeDocument) { - _context = _context.ParentContext; + _context = _context.PopContext(); WriteEndDocument(); } else { - _context = _context.ParentContext; + _context = _context.PopContext(); } if (_context == null) diff --git a/src/MongoDB.Bson/IO/JsonWriterContext.cs b/src/MongoDB.Bson/IO/JsonWriterContext.cs index c48dc7cef12..4fd7e5d00c1 100644 --- a/src/MongoDB.Bson/IO/JsonWriterContext.cs +++ b/src/MongoDB.Bson/IO/JsonWriterContext.cs @@ -52,5 +52,10 @@ internal bool HasElements get { return _hasElements; } set { _hasElements = value; } } + + internal JsonWriterContext PopContext() + { + return _parentContext; + } } } From e3923ca52b0581760dcb7ea828931132a22e0e87 Mon Sep 17 00:00:00 2001 From: obligaron Date: Sat, 19 Oct 2024 08:25:34 +0200 Subject: [PATCH 2/3] CSHARP-5348: Introduce Bson*Context.PushContext --- .../MongoDB.Driver.Benchmarks/README.md | 2 +- src/MongoDB.Bson/IO/BsonBinaryReader.cs | 6 +++--- .../IO/BsonBinaryReaderContext.cs | 5 +++++ src/MongoDB.Bson/IO/BsonBinaryWriter.cs | 9 ++++++--- .../IO/BsonBinaryWriterContext.cs | 5 +++++ src/MongoDB.Bson/IO/BsonDocumentReader.cs | 4 ++-- .../IO/BsonDocumentReaderContext.cs | 10 ++++++++++ src/MongoDB.Bson/IO/BsonDocumentWriter.cs | 8 ++++---- .../IO/BsonDocumentWriterContext.cs | 19 +++++++++++++++++-- src/MongoDB.Bson/IO/JsonReader.cs | 6 +++--- src/MongoDB.Bson/IO/JsonReaderContext.cs | 5 +++++ src/MongoDB.Bson/IO/JsonWriter.cs | 4 ++-- src/MongoDB.Bson/IO/JsonWriterContext.cs | 5 +++++ 13 files changed, 68 insertions(+), 20 deletions(-) diff --git a/benchmarks/MongoDB.Driver.Benchmarks/README.md b/benchmarks/MongoDB.Driver.Benchmarks/README.md index fa07012c742..899a9df0ae6 100644 --- a/benchmarks/MongoDB.Driver.Benchmarks/README.md +++ b/benchmarks/MongoDB.Driver.Benchmarks/README.md @@ -13,7 +13,7 @@ This suite implements the benchmarks described in this [spec](https://github.com (e.g `dotnet run -c Release -- --driverBenchmarks --envVars MONGODB_URI:"ConnectionString"`) You can also select the benchmarks to run directly on the command for running the benchmarks as such -`dotnet run -c Release -- --driverBenchmarks --fitler "*BenchmarkClassName*"`. The benchmarks are also grouped into categories namely: BSONBench, WriteBench +`dotnet run -c Release -- --driverBenchmarks --filter "*BenchmarkClassName*"`. The benchmarks are also grouped into categories namely: BSONBench, WriteBench ReadBench, ParallelBench, SingleBench, MultiBench and DriverBench. So if you wanted to only run the WriteBench benchmarks, you can do so as follows: `dotnet run -c Release -- --driverBenchmarks --anyCategories "WriteBench"`. diff --git a/src/MongoDB.Bson/IO/BsonBinaryReader.cs b/src/MongoDB.Bson/IO/BsonBinaryReader.cs index 3bf194cd425..4993bffd764 100644 --- a/src/MongoDB.Bson/IO/BsonBinaryReader.cs +++ b/src/MongoDB.Bson/IO/BsonBinaryReader.cs @@ -432,7 +432,7 @@ public override string ReadJavaScriptWithScope() var startPosition = _bsonStream.Position; // position of size field var size = ReadSize(); - _context = new BsonBinaryReaderContext(_context, ContextType.JavaScriptWithScope, startPosition, size); + _context = _context.PushContext(ContextType.JavaScriptWithScope, startPosition, size); var code = _bsonStream.ReadString(Settings.Encoding); State = BsonReaderState.ScopeDocument; @@ -590,7 +590,7 @@ public override void ReadStartArray() var startPosition = _bsonStream.Position; // position of size field var size = ReadSize(); - _context = new BsonBinaryReaderContext(_context, ContextType.Array, startPosition, size); + _context = _context.PushContext(ContextType.Array, startPosition, size); State = BsonReaderState.Type; } @@ -605,7 +605,7 @@ public override void ReadStartDocument() var contextType = (State == BsonReaderState.ScopeDocument) ? ContextType.ScopeDocument : ContextType.Document; var startPosition = _bsonStream.Position; // position of size field var size = ReadSize(); - _context = new BsonBinaryReaderContext(_context, contextType, startPosition, size); + _context = _context.PushContext(contextType, startPosition, size); State = BsonReaderState.Type; } diff --git a/src/MongoDB.Bson/IO/BsonBinaryReaderContext.cs b/src/MongoDB.Bson/IO/BsonBinaryReaderContext.cs index c4e18381dda..9363d46bd61 100644 --- a/src/MongoDB.Bson/IO/BsonBinaryReaderContext.cs +++ b/src/MongoDB.Bson/IO/BsonBinaryReaderContext.cs @@ -83,5 +83,10 @@ public BsonBinaryReaderContext PopContext(long position) } return _parentContext; } + + internal BsonBinaryReaderContext PushContext(ContextType contextType, long startPosition, long size) + { + return new BsonBinaryReaderContext(this, contextType, startPosition, size); + } } } diff --git a/src/MongoDB.Bson/IO/BsonBinaryWriter.cs b/src/MongoDB.Bson/IO/BsonBinaryWriter.cs index 7b9565592ba..b1535347d79 100644 --- a/src/MongoDB.Bson/IO/BsonBinaryWriter.cs +++ b/src/MongoDB.Bson/IO/BsonBinaryWriter.cs @@ -400,7 +400,7 @@ public override void WriteJavaScriptWithScope(string code) _bsonStream.WriteBsonType(BsonType.JavaScriptWithScope); WriteNameHelper(); - _context = new BsonBinaryWriterContext(_context, ContextType.JavaScriptWithScope, _bsonStream.Position); + _context = _context.PushContext(ContextType.JavaScriptWithScope, _bsonStream.Position); _bsonStream.WriteInt32(0); // reserve space for size of JavaScript with scope value _bsonStream.WriteString(code, Settings.Encoding); @@ -564,7 +564,7 @@ public override void WriteStartArray() base.WriteStartArray(); _bsonStream.WriteBsonType(BsonType.Array); WriteNameHelper(); - _context = new BsonBinaryWriterContext(_context, ContextType.Array, _bsonStream.Position); + _context = _context.PushContext(ContextType.Array, _bsonStream.Position); _bsonStream.WriteInt32(0); // reserve space for size State = BsonWriterState.Value; @@ -588,7 +588,10 @@ public override void WriteStartDocument() WriteNameHelper(); } var contextType = (State == BsonWriterState.ScopeDocument) ? ContextType.ScopeDocument : ContextType.Document; - _context = new BsonBinaryWriterContext(_context, contextType, _bsonStream.Position); + if (_context == null) + _context = new BsonBinaryWriterContext(null, contextType, _bsonStream.Position); + else + _context = _context.PushContext(contextType, _bsonStream.Position); _bsonStream.WriteInt32(0); // reserve space for size State = BsonWriterState.Name; diff --git a/src/MongoDB.Bson/IO/BsonBinaryWriterContext.cs b/src/MongoDB.Bson/IO/BsonBinaryWriterContext.cs index 63bc6d79546..3f42c5faa2d 100644 --- a/src/MongoDB.Bson/IO/BsonBinaryWriterContext.cs +++ b/src/MongoDB.Bson/IO/BsonBinaryWriterContext.cs @@ -60,5 +60,10 @@ internal BsonBinaryWriterContext PopContext() { return _parentContext; } + + internal BsonBinaryWriterContext PushContext(ContextType contextType, long startPosition) + { + return new BsonBinaryWriterContext(this, contextType, startPosition); + } } } diff --git a/src/MongoDB.Bson/IO/BsonDocumentReader.cs b/src/MongoDB.Bson/IO/BsonDocumentReader.cs index aa4a1e93252..2231bee8be0 100644 --- a/src/MongoDB.Bson/IO/BsonDocumentReader.cs +++ b/src/MongoDB.Bson/IO/BsonDocumentReader.cs @@ -413,7 +413,7 @@ public override void ReadStartArray() VerifyBsonType("ReadStartArray", BsonType.Array); var array = _currentValue.AsBsonArray; - _context = new BsonDocumentReaderContext(_context, ContextType.Array, array); + _context = _context.PushContext(ContextType.Array, array); State = BsonReaderState.Type; } @@ -435,7 +435,7 @@ public override void ReadStartDocument() { document = _currentValue.AsBsonDocument; } - _context = new BsonDocumentReaderContext(_context, ContextType.Document, document); + _context = _context.PushContext(ContextType.Document, document); State = BsonReaderState.Type; } diff --git a/src/MongoDB.Bson/IO/BsonDocumentReaderContext.cs b/src/MongoDB.Bson/IO/BsonDocumentReaderContext.cs index 9208be4ae0f..60c2f6b0dd2 100644 --- a/src/MongoDB.Bson/IO/BsonDocumentReaderContext.cs +++ b/src/MongoDB.Bson/IO/BsonDocumentReaderContext.cs @@ -124,5 +124,15 @@ public BsonDocumentReaderContext PopContext() { return _parentContext; } + + internal BsonDocumentReaderContext PushContext(ContextType contextType, BsonArray array) + { + return new BsonDocumentReaderContext(this, contextType, array); + } + + internal BsonDocumentReaderContext PushContext(ContextType contextType, BsonDocument document) + { + return new BsonDocumentReaderContext(this, contextType, document); + } } } diff --git a/src/MongoDB.Bson/IO/BsonDocumentWriter.cs b/src/MongoDB.Bson/IO/BsonDocumentWriter.cs index d0507a4b392..8e5e4ef0b27 100644 --- a/src/MongoDB.Bson/IO/BsonDocumentWriter.cs +++ b/src/MongoDB.Bson/IO/BsonDocumentWriter.cs @@ -304,7 +304,7 @@ public override void WriteJavaScriptWithScope(string code) ThrowInvalidState("WriteJavaScriptWithScope", BsonWriterState.Value); } - _context = new BsonDocumentWriterContext(_context, ContextType.JavaScriptWithScope, code); + _context = _context.PushContext(ContextType.JavaScriptWithScope, code); State = BsonWriterState.ScopeDocument; } @@ -407,7 +407,7 @@ public override void WriteStartArray() } base.WriteStartArray(); - _context = new BsonDocumentWriterContext(_context, ContextType.Array, new BsonArray()); + _context = _context.PushContext(ContextType.Array, new BsonArray()); State = BsonWriterState.Value; } @@ -430,10 +430,10 @@ public override void WriteStartDocument() _context = new BsonDocumentWriterContext(null, ContextType.Document, _document); break; case BsonWriterState.Value: - _context = new BsonDocumentWriterContext(_context, ContextType.Document, new BsonDocument()); + _context = _context.PushContext(ContextType.Document, new BsonDocument()); break; case BsonWriterState.ScopeDocument: - _context = new BsonDocumentWriterContext(_context, ContextType.ScopeDocument, new BsonDocument()); + _context = _context.PushContext(ContextType.ScopeDocument, new BsonDocument()); break; default: throw new BsonInternalException("Unexpected state."); diff --git a/src/MongoDB.Bson/IO/BsonDocumentWriterContext.cs b/src/MongoDB.Bson/IO/BsonDocumentWriterContext.cs index 049ae09e7fd..f82d3152d67 100644 --- a/src/MongoDB.Bson/IO/BsonDocumentWriterContext.cs +++ b/src/MongoDB.Bson/IO/BsonDocumentWriterContext.cs @@ -36,7 +36,7 @@ internal BsonDocumentWriterContext( _document = document; } - internal BsonDocumentWriterContext( + private BsonDocumentWriterContext( BsonDocumentWriterContext parentContext, ContextType contextType, BsonArray array) @@ -46,7 +46,7 @@ internal BsonDocumentWriterContext( _array = array; } - internal BsonDocumentWriterContext( + private BsonDocumentWriterContext( BsonDocumentWriterContext parentContext, ContextType contextType, string code) @@ -92,5 +92,20 @@ internal BsonDocumentWriterContext PopContext() { return _parentContext; } + + internal BsonDocumentWriterContext PushContext(ContextType contextType, BsonDocument document) + { + return new BsonDocumentWriterContext(this, contextType, document); + } + + internal BsonDocumentWriterContext PushContext(ContextType contextType, BsonArray array) + { + return new BsonDocumentWriterContext(this, contextType, array); + } + + internal BsonDocumentWriterContext PushContext(ContextType contextType, string code) + { + return new BsonDocumentWriterContext(this, contextType, code); + } } } diff --git a/src/MongoDB.Bson/IO/JsonReader.cs b/src/MongoDB.Bson/IO/JsonReader.cs index 0d5a483ff60..d26f7846b7c 100644 --- a/src/MongoDB.Bson/IO/JsonReader.cs +++ b/src/MongoDB.Bson/IO/JsonReader.cs @@ -627,7 +627,7 @@ public override string ReadJavaScriptWithScope() { if (Disposed) { ThrowObjectDisposedException(); } VerifyBsonType("ReadJavaScriptWithScope", BsonType.JavaScriptWithScope); - _context = new JsonReaderContext(_context, ContextType.JavaScriptWithScope); + _context = _context.PushContext(ContextType.JavaScriptWithScope); State = BsonReaderState.ScopeDocument; return _currentValue.AsString; } @@ -723,7 +723,7 @@ public override void ReadStartArray() if (Disposed) { ThrowObjectDisposedException(); } VerifyBsonType("ReadStartArray", BsonType.Array); - _context = new JsonReaderContext(_context, ContextType.Array); + _context = _context.PushContext(ContextType.Array); State = BsonReaderState.Type; } @@ -735,7 +735,7 @@ public override void ReadStartDocument() if (Disposed) { ThrowObjectDisposedException(); } VerifyBsonType("ReadStartDocument", BsonType.Document); - _context = new JsonReaderContext(_context, ContextType.Document); + _context = _context.PushContext(ContextType.Document); State = BsonReaderState.Type; } diff --git a/src/MongoDB.Bson/IO/JsonReaderContext.cs b/src/MongoDB.Bson/IO/JsonReaderContext.cs index 94dc554ec39..8f12af683a1 100644 --- a/src/MongoDB.Bson/IO/JsonReaderContext.cs +++ b/src/MongoDB.Bson/IO/JsonReaderContext.cs @@ -53,5 +53,10 @@ public JsonReaderContext PopContext() { return _parentContext; } + + internal JsonReaderContext PushContext(ContextType contextType) + { + return new JsonReaderContext(this, contextType); + } } } diff --git a/src/MongoDB.Bson/IO/JsonWriter.cs b/src/MongoDB.Bson/IO/JsonWriter.cs index e558e42eb12..501cfc4ad01 100644 --- a/src/MongoDB.Bson/IO/JsonWriter.cs +++ b/src/MongoDB.Bson/IO/JsonWriter.cs @@ -641,7 +641,7 @@ public override void WriteStartArray() WriteNameHelper(Name); _textWriter.Write("["); - _context = new JsonWriterContext(_context, ContextType.Array, Settings.IndentChars); + _context = _context.PushContext(ContextType.Array, Settings.IndentChars); State = BsonWriterState.Value; } @@ -664,7 +664,7 @@ public override void WriteStartDocument() _textWriter.Write("{"); var contextType = (State == BsonWriterState.ScopeDocument) ? ContextType.ScopeDocument : ContextType.Document; - _context = new JsonWriterContext(_context, contextType, Settings.IndentChars); + _context = _context.PushContext(contextType, Settings.IndentChars); State = BsonWriterState.Name; } diff --git a/src/MongoDB.Bson/IO/JsonWriterContext.cs b/src/MongoDB.Bson/IO/JsonWriterContext.cs index 4fd7e5d00c1..609121ee129 100644 --- a/src/MongoDB.Bson/IO/JsonWriterContext.cs +++ b/src/MongoDB.Bson/IO/JsonWriterContext.cs @@ -57,5 +57,10 @@ internal JsonWriterContext PopContext() { return _parentContext; } + + internal JsonWriterContext PushContext(ContextType contextType, string indentChars) + { + return new JsonWriterContext(this, contextType, indentChars); + } } } From 4f91e8d0ce2097be27be0b46e4391fcd2d3b9df9 Mon Sep 17 00:00:00 2001 From: obligaron Date: Sat, 19 Oct 2024 13:02:31 +0200 Subject: [PATCH 3/3] CSHARP-5348: Cache Bson*Context.PushContext --- .../MongoDB.Driver.Benchmarks/README.md | 2 +- .../IO/BsonBinaryReaderContext.cs | 19 ++++++++-- .../IO/BsonBinaryWriterContext.cs | 13 ++++++- .../IO/BsonDocumentReaderContext.cs | 25 ++++++++++-- .../IO/BsonDocumentWriterContext.cs | 38 ++++++++++++------- src/MongoDB.Bson/IO/JsonReaderContext.cs | 9 ++++- src/MongoDB.Bson/IO/JsonWriterContext.cs | 12 +++++- 7 files changed, 89 insertions(+), 29 deletions(-) diff --git a/benchmarks/MongoDB.Driver.Benchmarks/README.md b/benchmarks/MongoDB.Driver.Benchmarks/README.md index 899a9df0ae6..005c5bd5be6 100644 --- a/benchmarks/MongoDB.Driver.Benchmarks/README.md +++ b/benchmarks/MongoDB.Driver.Benchmarks/README.md @@ -1,6 +1,6 @@ # C# Driver Benchmark Suite -This suite implements the benchmarks described in this [spec](https://github.com/mongodb/specifications/blob/master/source/benchmarking/benchmarking.rst). +This suite implements the benchmarks described in this [spec](https://github.com/mongodb/specifications/blob/master/source/benchmarking/benchmarking.md). ## Running the Driver Benchmarks diff --git a/src/MongoDB.Bson/IO/BsonBinaryReaderContext.cs b/src/MongoDB.Bson/IO/BsonBinaryReaderContext.cs index 9363d46bd61..589362a24de 100644 --- a/src/MongoDB.Bson/IO/BsonBinaryReaderContext.cs +++ b/src/MongoDB.Bson/IO/BsonBinaryReaderContext.cs @@ -21,9 +21,10 @@ internal class BsonBinaryReaderContext { // private fields private readonly BsonBinaryReaderContext _parentContext; - private readonly ContextType _contextType; - private readonly long _startPosition; - private readonly long _size; + private BsonBinaryReaderContext _cachedPushContext; + private ContextType _contextType; + private long _startPosition; + private long _size; private string _currentElementName; private int _currentArrayIndex = -1; @@ -86,7 +87,17 @@ public BsonBinaryReaderContext PopContext(long position) internal BsonBinaryReaderContext PushContext(ContextType contextType, long startPosition, long size) { - return new BsonBinaryReaderContext(this, contextType, startPosition, size); + if (_cachedPushContext == null) + _cachedPushContext = new BsonBinaryReaderContext(this, contextType, startPosition, size); + else + { + _cachedPushContext._contextType = contextType; + _cachedPushContext._startPosition = startPosition; + _cachedPushContext._size = size; + _cachedPushContext._currentArrayIndex = -1; + _cachedPushContext._currentElementName = null; + } + return _cachedPushContext; } } } diff --git a/src/MongoDB.Bson/IO/BsonBinaryWriterContext.cs b/src/MongoDB.Bson/IO/BsonBinaryWriterContext.cs index 3f42c5faa2d..8512e9d56de 100644 --- a/src/MongoDB.Bson/IO/BsonBinaryWriterContext.cs +++ b/src/MongoDB.Bson/IO/BsonBinaryWriterContext.cs @@ -18,7 +18,8 @@ namespace MongoDB.Bson.IO internal class BsonBinaryWriterContext { // private fields - private BsonBinaryWriterContext _parentContext; + private readonly BsonBinaryWriterContext _parentContext; + private BsonBinaryWriterContext _cachedPushContext; private ContextType _contextType; private long _startPosition; private int _index; // used when contextType is Array @@ -63,7 +64,15 @@ internal BsonBinaryWriterContext PopContext() internal BsonBinaryWriterContext PushContext(ContextType contextType, long startPosition) { - return new BsonBinaryWriterContext(this, contextType, startPosition); + if (_cachedPushContext == null) + _cachedPushContext = new BsonBinaryWriterContext(this, contextType, startPosition); + else + { + _cachedPushContext._contextType = contextType; + _cachedPushContext._startPosition = startPosition; + _cachedPushContext._index = 0; + } + return _cachedPushContext; } } } diff --git a/src/MongoDB.Bson/IO/BsonDocumentReaderContext.cs b/src/MongoDB.Bson/IO/BsonDocumentReaderContext.cs index 60c2f6b0dd2..aa5013eb5ee 100644 --- a/src/MongoDB.Bson/IO/BsonDocumentReaderContext.cs +++ b/src/MongoDB.Bson/IO/BsonDocumentReaderContext.cs @@ -18,20 +18,23 @@ namespace MongoDB.Bson.IO internal class BsonDocumentReaderContext { // private fields - private BsonDocumentReaderContext _parentContext; + private readonly BsonDocumentReaderContext _parentContext; + private BsonDocumentReaderContext _cachedPushContext; private ContextType _contextType; private BsonDocument _document; private BsonArray _array; private int _index; // constructors - internal BsonDocumentReaderContext( + private BsonDocumentReaderContext( BsonDocumentReaderContext parentContext, ContextType contextType, + BsonDocument document, BsonArray array) { _parentContext = parentContext; _contextType = contextType; + _document = document; _array = array; } @@ -127,12 +130,26 @@ public BsonDocumentReaderContext PopContext() internal BsonDocumentReaderContext PushContext(ContextType contextType, BsonArray array) { - return new BsonDocumentReaderContext(this, contextType, array); + return PushContext(contextType, null, array); } internal BsonDocumentReaderContext PushContext(ContextType contextType, BsonDocument document) { - return new BsonDocumentReaderContext(this, contextType, document); + return PushContext(contextType, document, null); + } + + private BsonDocumentReaderContext PushContext(ContextType contextType, BsonDocument document, BsonArray array) + { + if (_cachedPushContext == null) + _cachedPushContext = new BsonDocumentReaderContext(this, contextType, document, array); + else + { + _cachedPushContext._contextType = contextType; + _cachedPushContext._document = document; + _cachedPushContext._array = array; + _cachedPushContext._index = 0; + } + return _cachedPushContext; } } } diff --git a/src/MongoDB.Bson/IO/BsonDocumentWriterContext.cs b/src/MongoDB.Bson/IO/BsonDocumentWriterContext.cs index f82d3152d67..00f25a8e790 100644 --- a/src/MongoDB.Bson/IO/BsonDocumentWriterContext.cs +++ b/src/MongoDB.Bson/IO/BsonDocumentWriterContext.cs @@ -18,7 +18,8 @@ namespace MongoDB.Bson.IO internal class BsonDocumentWriterContext { // private fields - private BsonDocumentWriterContext _parentContext; + private readonly BsonDocumentWriterContext _parentContext; + private BsonDocumentWriterContext _cachedPushContext; private ContextType _contextType; private BsonDocument _document; private BsonArray _array; @@ -39,20 +40,14 @@ internal BsonDocumentWriterContext( private BsonDocumentWriterContext( BsonDocumentWriterContext parentContext, ContextType contextType, - BsonArray array) - { - _parentContext = parentContext; - _contextType = contextType; - _array = array; - } - - private BsonDocumentWriterContext( - BsonDocumentWriterContext parentContext, - ContextType contextType, + BsonDocument document, + BsonArray array, string code) { _parentContext = parentContext; _contextType = contextType; + _document = document; + _array = array; _code = code; } @@ -95,17 +90,32 @@ internal BsonDocumentWriterContext PopContext() internal BsonDocumentWriterContext PushContext(ContextType contextType, BsonDocument document) { - return new BsonDocumentWriterContext(this, contextType, document); + return PushContext(contextType, document, null, null); } internal BsonDocumentWriterContext PushContext(ContextType contextType, BsonArray array) { - return new BsonDocumentWriterContext(this, contextType, array); + return PushContext(contextType, null, array, null); } internal BsonDocumentWriterContext PushContext(ContextType contextType, string code) { - return new BsonDocumentWriterContext(this, contextType, code); + return PushContext(contextType, null, null, code); + } + + private BsonDocumentWriterContext PushContext(ContextType contextType, BsonDocument document, BsonArray array, string code) + { + if (_cachedPushContext == null) + _cachedPushContext = new BsonDocumentWriterContext(this, contextType, document, array, code); + else + { + _cachedPushContext._contextType = contextType; + _cachedPushContext._document = document; + _cachedPushContext._array = array; + _cachedPushContext._code = code; + _cachedPushContext._name = null; + } + return _cachedPushContext; } } } diff --git a/src/MongoDB.Bson/IO/JsonReaderContext.cs b/src/MongoDB.Bson/IO/JsonReaderContext.cs index 8f12af683a1..e93707a4bae 100644 --- a/src/MongoDB.Bson/IO/JsonReaderContext.cs +++ b/src/MongoDB.Bson/IO/JsonReaderContext.cs @@ -18,7 +18,8 @@ namespace MongoDB.Bson.IO internal class JsonReaderContext { // private fields - private JsonReaderContext _parentContext; + private readonly JsonReaderContext _parentContext; + private JsonReaderContext _cachedPushContext; private ContextType _contextType; // constructors @@ -56,7 +57,11 @@ public JsonReaderContext PopContext() internal JsonReaderContext PushContext(ContextType contextType) { - return new JsonReaderContext(this, contextType); + if (_cachedPushContext == null) + _cachedPushContext = new JsonReaderContext(this, contextType); + else + _cachedPushContext._contextType = contextType; + return _cachedPushContext; } } } diff --git a/src/MongoDB.Bson/IO/JsonWriterContext.cs b/src/MongoDB.Bson/IO/JsonWriterContext.cs index 609121ee129..cdc8b6c2cee 100644 --- a/src/MongoDB.Bson/IO/JsonWriterContext.cs +++ b/src/MongoDB.Bson/IO/JsonWriterContext.cs @@ -18,7 +18,8 @@ namespace MongoDB.Bson.IO internal class JsonWriterContext { // private fields - private JsonWriterContext _parentContext; + private readonly JsonWriterContext _parentContext; + private JsonWriterContext _cachedPushContext; private ContextType _contextType; private string _indentation; private bool _hasElements = false; @@ -60,7 +61,14 @@ internal JsonWriterContext PopContext() internal JsonWriterContext PushContext(ContextType contextType, string indentChars) { - return new JsonWriterContext(this, contextType, indentChars); + if (_cachedPushContext == null) + _cachedPushContext = new JsonWriterContext(this, contextType, indentChars); + else + { + _cachedPushContext._contextType = contextType; + _cachedPushContext._hasElements = false; + } + return _cachedPushContext; } } }