private void WriteType1Section(BsonBinaryWriter writer, Type1CommandMessageSection section, long messageStartPosition) { var stream = writer.BsonStream; var serializer = section.DocumentSerializer; var context = BsonSerializationContext.CreateRoot(writer); var maxMessageSize = MaxMessageSize; var payloadStartPosition = stream.Position; stream.WriteInt32(0); // size stream.WriteCString(section.Identifier); var batch = section.Documents; var processedCount = batch.Count; for (var i = 0; i < batch.Count; i++) { var documentStartPosition = stream.Position; var document = batch.Items[batch.Offset + i]; serializer.Serialize(context, document); var messageSize = stream.Position - messageStartPosition; if (messageSize > maxMessageSize) { stream.Position = documentStartPosition; stream.SetLength(documentStartPosition); processedCount = i; break; } } batch.SetProcessedCount(processedCount); stream.BackpatchSize(payloadStartPosition); }
private BsonDocument CreateType1SectionDocument(Type1CommandMessageSection <BsonDocument> section) { return(new BsonDocument { { "payloadType", 1 }, { "identifier", section.Identifier }, { "documents", new BsonArray(section.Documents.GetBatchItems()) } }); }
private void WriteType1Section(BsonBinaryWriter writer, Type1CommandMessageSection section, long messageStartPosition) { var stream = writer.BsonStream; var serializer = section.DocumentSerializer; var context = BsonSerializationContext.CreateRoot(writer); int?maxMessageSize; if (IsEncryptionConfigured) { var maxBatchSize = 2 * 1024 * 1024; // 2 MiB var maxMessageEndPosition = stream.Position + maxBatchSize; maxMessageSize = (int)(maxMessageEndPosition - messageStartPosition); } else { maxMessageSize = MaxMessageSize; } var payloadStartPosition = stream.Position; stream.WriteInt32(0); // size stream.WriteCString(section.Identifier); var batch = section.Documents; var maxDocumentSize = section.MaxDocumentSize ?? writer.Settings.MaxDocumentSize; writer.PushSettings(s => ((BsonBinaryWriterSettings)s).MaxDocumentSize = maxDocumentSize); writer.PushElementNameValidator(section.ElementNameValidator); try { var maxBatchCount = Math.Min(batch.Count, section.MaxBatchCount ?? int.MaxValue); var processedCount = maxBatchCount; for (var i = 0; i < maxBatchCount; i++) { var documentStartPosition = stream.Position; var document = batch.Items[batch.Offset + i]; serializer.Serialize(context, document); var messageSize = stream.Position - messageStartPosition; if (messageSize > maxMessageSize && batch.CanBeSplit && i > 0) { stream.Position = documentStartPosition; stream.SetLength(documentStartPosition); processedCount = i; break; } } batch.SetProcessedCount(processedCount); } finally { writer.PopElementNameValidator(); writer.PopSettings(); } stream.BackpatchSize(payloadStartPosition); }
private IBsonSerializer CreateFixedCountPayloadSerializer(Type1CommandMessageSection payload) { var documentType = payload.DocumentType; var serializerType = typeof(FixedCountBatchableSourceSerializer <>).MakeGenericType(documentType); var itemSerializerType = typeof(IBsonSerializer <>).MakeGenericType(documentType); var constructorParameterTypes = new[] { itemSerializerType, typeof(IElementNameValidator), typeof(int) }; var constructorInfo = serializerType.GetTypeInfo().GetConstructor(constructorParameterTypes); var itemSerializer = payload.DocumentSerializer; var itemElementNameValidator = payload.ElementNameValidator; var count = payload.Documents.Count; return((IBsonSerializer)constructorInfo.Invoke(new object[] { itemSerializer, itemElementNameValidator, count })); }
private IBsonSerializer CreateSizeLimitingPayloadSerializer(Type1CommandMessageSection payload, ConnectionDescription connectionDescription) { var documentType = payload.DocumentType; var serializerType = typeof(SizeLimitingBatchableSourceSerializer <>).MakeGenericType(documentType); var itemSerializerType = typeof(IBsonSerializer <>).MakeGenericType(documentType); var constructorParameterTypes = new[] { itemSerializerType, typeof(IElementNameValidator), typeof(int), typeof(int), typeof(int) }; var constructorInfo = serializerType.GetTypeInfo().GetConstructor(constructorParameterTypes); var itemSerializer = payload.DocumentSerializer; var itemElementNameValidator = payload.ElementNameValidator; var maxBatchCount = Math.Min(payload.MaxBatchCount ?? int.MaxValue, connectionDescription.MaxBatchCount); var maxItemSize = payload.MaxDocumentSize ?? connectionDescription.MaxDocumentSize; var maxBatchSize = connectionDescription.MaxDocumentSize; return((IBsonSerializer)constructorInfo.Invoke(new object[] { itemSerializer, itemElementNameValidator, maxBatchCount, maxItemSize, maxBatchSize })); }
private void WriteType1Section(IBsonWriter writer, Type1CommandMessageSection section) { writer.WriteString("identifier", section.Identifier); writer.WriteName("documents"); writer.WriteStartArray(); var batch = section.Documents; var serializer = section.DocumentSerializer; var context = BsonSerializationContext.CreateRoot(writer); for (var i = 0; i < batch.Count; i++) { var document = batch.Items[batch.Offset + i]; serializer.Serialize(context, document); } writer.WriteEndArray(); }
/// <inheritdoc /> protected override IEnumerable <Type1CommandMessageSection> CreateCommandPayloads(IChannelHandle channel, int attempt) { BatchableSource <DeleteRequest> deletes; if (attempt == 1) { deletes = _deletes; } else { deletes = new BatchableSource <DeleteRequest>(_deletes.Items, _deletes.Offset, _deletes.ProcessedCount, canBeSplit: false); } var maxBatchCount = Math.Min(MaxBatchCount ?? int.MaxValue, channel.ConnectionDescription.MaxBatchCount); var maxDocumentSize = channel.ConnectionDescription.MaxWireDocumentSize; var payload = new Type1CommandMessageSection <DeleteRequest>("deletes", deletes, DeleteRequestSerializer.Instance, NoOpElementNameValidator.Instance, maxBatchCount, maxDocumentSize); return(new Type1CommandMessageSection[] { payload }); }
private BsonArray CreatePayloadArray(Type1CommandMessageSection payload, ConnectionDescription connectionDescription) { IBsonSerializer payloadSerializer; if (payload.Documents.CanBeSplit) { payloadSerializer = CreateSizeLimitingPayloadSerializer(payload, connectionDescription); } else { payloadSerializer = CreateFixedCountPayloadSerializer(payload); } var documents = new BsonDocumentWrapper(payload.Documents, payloadSerializer); return(new BsonArray { documents }); }
/// <inheritdoc /> protected override IEnumerable <Type1CommandMessageSection> CreateCommandPayloads(IChannelHandle channel, int attempt) { BatchableSource <TDocument> documents; if (attempt == 1) { documents = _documents; } else { documents = new BatchableSource <TDocument>(_documents.Items, _documents.Offset, _documents.ProcessedCount, canBeSplit: false); } var isSystemIndexesCollection = _collectionNamespace.Equals(CollectionNamespace.DatabaseNamespace.SystemIndexesCollection); var elementNameValidator = isSystemIndexesCollection ? (IElementNameValidator)NoOpElementNameValidator.Instance : CollectionElementNameValidator.Instance; var maxBatchCount = Math.Min(MaxBatchCount ?? int.MaxValue, channel.ConnectionDescription.MaxBatchCount); var maxDocumentSize = channel.ConnectionDescription.MaxDocumentSize; var payload = new Type1CommandMessageSection <TDocument>("documents", documents, _documentSerializer, elementNameValidator, maxBatchCount, maxDocumentSize); return(new Type1CommandMessageSection[] { payload }); }
private byte[] CreateType1SectionBytes(Type1CommandMessageSection <BsonDocument> section) { using (var memoryStream = new MemoryStream()) using (var stream = new BsonStreamAdapter(memoryStream)) using (var writer = new BsonBinaryWriter(stream)) { stream.WriteByte(1); var payloadStartPosition = stream.Position; stream.WriteInt32(0); // size stream.WriteCString(section.Identifier); var context = BsonSerializationContext.CreateRoot(writer); var batch = section.Documents; for (var i = 0; i < batch.Count; i++) { var document = batch.Items[batch.Offset + i]; BsonDocumentSerializer.Instance.Serialize(context, document); } stream.BackpatchSize(payloadStartPosition); return(memoryStream.ToArray()); } }