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();
        }
Beispiel #7
0
        /// <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());
             }
 }