/// <summary>
        /// Creates a CosmosPipelinedItemQueryExecutionContext.
        /// </summary>
        /// <param name="queryContext">The parameters for constructing the base class.</param>
        /// <param name="initParams">The initial parameters</param>
        /// <param name="requestContinuationToken">The request continuation.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A task to await on, which in turn returns a CosmosPipelinedItemQueryExecutionContext.</returns>
        public static async Task <CosmosQueryExecutionContext> CreateAsync(
            CosmosQueryContext queryContext,
            CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams initParams,
            string requestContinuationToken,
            CancellationToken cancellationToken)
        {
            DefaultTrace.TraceInformation(
                string.Format(
                    CultureInfo.InvariantCulture,
                    "{0}, CorrelatedActivityId: {1} | Pipelined~Context.CreateAsync",
                    DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture),
                    queryContext.CorrelatedActivityId));

            QueryInfo queryInfo = initParams.PartitionedQueryExecutionInfo.QueryInfo;

            int actualPageSize  = initParams.InitialPageSize;
            int initialPageSize = initParams.InitialPageSize;

            CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams parameters = initParams;
            if (queryInfo.HasGroupBy)
            {
                initialPageSize = int.MaxValue;
                initParams      = new CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams(
                    sqlQuerySpec: initParams.SqlQuerySpec,
                    collectionRid: initParams.CollectionRid,
                    partitionedQueryExecutionInfo: initParams.PartitionedQueryExecutionInfo,
                    partitionKeyRanges: initParams.PartitionKeyRanges,
                    initialPageSize: initialPageSize,
                    maxConcurrency: initParams.MaxConcurrency,
                    maxItemCount: int.MaxValue,
                    maxBufferedItemCount: initParams.MaxBufferedItemCount);
            }

            Func <string, Task <IDocumentQueryExecutionComponent> > createOrderByComponentFunc = async(continuationToken) =>
            {
                return(await CosmosOrderByItemQueryExecutionContext.CreateAsync(
                           queryContext,
                           initParams,
                           continuationToken,
                           cancellationToken));
            };

            Func <string, Task <IDocumentQueryExecutionComponent> > createParallelComponentFunc = async(continuationToken) =>
            {
                return(await CosmosParallelItemQueryExecutionContext.CreateAsync(
                           queryContext,
                           initParams,
                           continuationToken,
                           cancellationToken));
            };

            return((CosmosQueryExecutionContext)await PipelinedDocumentQueryExecutionContext.CreateHelperAsync(
                       queryContext.QueryClient,
                       initParams.PartitionedQueryExecutionInfo.QueryInfo,
                       initialPageSize,
                       requestContinuationToken,
                       createOrderByComponentFunc,
                       createParallelComponentFunc));
        }
        /// <summary>
        /// Creates a PipelinedDocumentQueryExecutionContext.
        /// </summary>
        /// <param name="constructorParams">The parameters for constructing the base class.</param>
        /// <param name="collectionRid">The collection rid.</param>
        /// <param name="partitionedQueryExecutionInfo">The partitioned query execution info.</param>
        /// <param name="partitionKeyRanges">The partition key ranges.</param>
        /// <param name="initialPageSize">The initial page size.</param>
        /// <param name="requestContinuation">The request continuation.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A task to await on, which in turn returns a PipelinedDocumentQueryExecutionContext.</returns>
        public static async Task <IDocumentQueryExecutionContext> CreateDocumentQueryExecutionContextAsync(
            DocumentQueryExecutionContextBase.InitParams constructorParams,
            string collectionRid,
            PartitionedQueryExecutionInfo partitionedQueryExecutionInfo,
            List <PartitionKeyRange> partitionKeyRanges,
            int initialPageSize,
            string requestContinuation,
            CancellationToken cancellationToken)
        {
            DefaultTrace.TraceInformation(
                string.Format(
                    CultureInfo.InvariantCulture,
                    "{0}, CorrelatedActivityId: {1} | Pipelined~Context.CreateAsync",
                    DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture),
                    constructorParams.CorrelatedActivityId));

            QueryInfo queryInfo = partitionedQueryExecutionInfo.QueryInfo;

            Func <string, Task <IDocumentQueryExecutionComponent> > createOrderByComponentFunc = async(continuationToken) =>
            {
                CrossPartitionQueryExecutionContext.CrossPartitionInitParams initParams = new CrossPartitionQueryExecutionContext.CrossPartitionInitParams(
                    collectionRid,
                    partitionedQueryExecutionInfo,
                    partitionKeyRanges,
                    initialPageSize,
                    continuationToken);

                return(await OrderByDocumentQueryExecutionContext.CreateAsync(
                           constructorParams,
                           initParams,
                           cancellationToken));
            };

            Func <string, Task <IDocumentQueryExecutionComponent> > createParallelComponentFunc = async(continuationToken) =>
            {
                CrossPartitionQueryExecutionContext.CrossPartitionInitParams initParams = new CrossPartitionQueryExecutionContext.CrossPartitionInitParams(
                    collectionRid,
                    partitionedQueryExecutionInfo,
                    partitionKeyRanges,
                    initialPageSize,
                    continuationToken);

                return(await ParallelDocumentQueryExecutionContext.CreateAsync(
                           constructorParams,
                           initParams,
                           cancellationToken));
            };

            return((IDocumentQueryExecutionContext)(await PipelinedDocumentQueryExecutionContext.CreateHelperAsync(
                                                        partitionedQueryExecutionInfo.QueryInfo,
                                                        initialPageSize,
                                                        requestContinuation,
                                                        createOrderByComponentFunc,
                                                        createParallelComponentFunc)));
        }
        /// <summary>
        /// Creates a CosmosPipelinedItemQueryExecutionContext.
        /// </summary>
        /// <param name="executionEnvironment">The environment to execute on.</param>
        /// <param name="queryContext">The parameters for constructing the base class.</param>
        /// <param name="initParams">The initial parameters</param>
        /// <param name="requestContinuationToken">The request continuation.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A task to await on, which in turn returns a CosmosPipelinedItemQueryExecutionContext.</returns>
        public static async Task <CosmosQueryExecutionContext> CreateAsync(
            ExecutionEnvironment executionEnvironment,
            CosmosQueryContext queryContext,
            CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams initParams,
            string requestContinuationToken,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            QueryInfo queryInfo = initParams.PartitionedQueryExecutionInfo.QueryInfo;

            int initialPageSize = initParams.InitialPageSize;

            CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams parameters = initParams;
            if (queryInfo.HasGroupBy)
            {
                // The query will block until all groupings are gathered so we might as well speed up the process.
                initParams = new CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams(
                    sqlQuerySpec: initParams.SqlQuerySpec,
                    collectionRid: initParams.CollectionRid,
                    partitionedQueryExecutionInfo: initParams.PartitionedQueryExecutionInfo,
                    partitionKeyRanges: initParams.PartitionKeyRanges,
                    initialPageSize: int.MaxValue,
                    maxConcurrency: initParams.MaxConcurrency,
                    maxItemCount: int.MaxValue,
                    maxBufferedItemCount: initParams.MaxBufferedItemCount);
            }

            Func <string, Task <IDocumentQueryExecutionComponent> > createOrderByComponentFunc = async(continuationToken) =>
            {
                return(await CosmosOrderByItemQueryExecutionContext.CreateAsync(
                           queryContext,
                           initParams,
                           continuationToken,
                           cancellationToken));
            };

            Func <string, Task <IDocumentQueryExecutionComponent> > createParallelComponentFunc = async(continuationToken) =>
            {
                return(await CosmosParallelItemQueryExecutionContext.CreateAsync(
                           queryContext,
                           initParams,
                           continuationToken,
                           cancellationToken));
            };

            return((CosmosQueryExecutionContext)await PipelinedDocumentQueryExecutionContext.CreateHelperAsync(
                       executionEnvironment,
                       queryContext.QueryClient,
                       initParams.PartitionedQueryExecutionInfo.QueryInfo,
                       initialPageSize,
                       requestContinuationToken,
                       createOrderByComponentFunc,
                       createParallelComponentFunc));
        }
        public static async Task <CosmosQueryExecutionContext> CreateSpecializedDocumentQueryExecutionContextAsync(
            CosmosQueryContext cosmosQueryContext,
            PartitionedQueryExecutionInfo partitionedQueryExecutionInfo,
            List <PartitionKeyRange> targetRanges,
            string collectionRid,
            CancellationToken cancellationToken)
        {
            if (!string.IsNullOrEmpty(partitionedQueryExecutionInfo.QueryInfo?.RewrittenQuery))
            {
                cosmosQueryContext.SqlQuerySpec = new SqlQuerySpec(
                    partitionedQueryExecutionInfo.QueryInfo.RewrittenQuery,
                    cosmosQueryContext.SqlQuerySpec.Parameters);
            }

            // Figure out the optimal page size.
            long initialPageSize = cosmosQueryContext.QueryRequestOptions.MaxItemCount.GetValueOrDefault(ParallelQueryConfig.GetConfig().ClientInternalPageSize);

            if (initialPageSize < -1 || initialPageSize == 0)
            {
                throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, "Invalid MaxItemCount {0}", initialPageSize));
            }

            QueryInfo queryInfo = partitionedQueryExecutionInfo.QueryInfo;

            bool getLazyFeedResponse = queryInfo.HasTop;

            // We need to compute the optimal initial page size for order-by queries
            if (queryInfo.HasOrderBy)
            {
                int top;
                if (queryInfo.HasTop && (top = partitionedQueryExecutionInfo.QueryInfo.Top.Value) > 0)
                {
                    // All partitions should initially fetch about 1/nth of the top value.
                    long pageSizeWithTop = (long)Math.Min(
                        Math.Ceiling(top / (double)targetRanges.Count) * PageSizeFactorForTop,
                        top);

                    if (initialPageSize > 0)
                    {
                        initialPageSize = Math.Min(pageSizeWithTop, initialPageSize);
                    }
                    else
                    {
                        initialPageSize = pageSizeWithTop;
                    }
                }
                else if (cosmosQueryContext.IsContinuationExpected)
                {
                    if (initialPageSize < 0)
                    {
                        if (cosmosQueryContext.QueryRequestOptions.MaxBufferedItemCount.HasValue)
                        {
                            // Max of what the user is willing to buffer and the default (note this is broken if MaxBufferedItemCount = -1)
                            initialPageSize = Math.Max(cosmosQueryContext.QueryRequestOptions.MaxBufferedItemCount.Value, ParallelQueryConfig.GetConfig().DefaultMaximumBufferSize);
                        }
                        else
                        {
                            initialPageSize = ParallelQueryConfig.GetConfig().DefaultMaximumBufferSize;
                        }
                    }

                    initialPageSize = (long)Math.Min(
                        Math.Ceiling(initialPageSize / (double)targetRanges.Count) * PageSizeFactorForTop,
                        initialPageSize);
                }
            }

            Debug.Assert(initialPageSize > 0 && initialPageSize <= int.MaxValue,
                         string.Format(CultureInfo.InvariantCulture, "Invalid MaxItemCount {0}", initialPageSize));

            return(await PipelinedDocumentQueryExecutionContext.CreateAsync(
                       cosmosQueryContext,
                       collectionRid,
                       partitionedQueryExecutionInfo,
                       targetRanges,
                       (int)initialPageSize,
                       cosmosQueryContext.QueryRequestOptions.RequestContinuation,
                       cancellationToken));
        }
コード例 #5
0
        /// <summary>
        /// Creates a CosmosPipelinedItemQueryExecutionContext.
        /// </summary>
        /// <param name="constructorParams">The parameters for constructing the base class.</param>
        /// <param name="collectionRid">The collection rid.</param>
        /// <param name="partitionedQueryExecutionInfo">The partitioned query execution info.</param>
        /// <param name="partitionKeyRanges">The partition key ranges.</param>
        /// <param name="initialPageSize">The initial page size.</param>
        /// <param name="requestContinuation">The request continuation.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A task to await on, which in turn returns a CosmosPipelinedItemQueryExecutionContext.</returns>
        public static async Task <CosmosQueryExecutionContext> CreateAsync(
            CosmosQueryContext constructorParams,
            string collectionRid,
            PartitionedQueryExecutionInfo partitionedQueryExecutionInfo,
            List <PartitionKeyRange> partitionKeyRanges,
            int initialPageSize,
            string requestContinuation,
            CancellationToken cancellationToken)
        {
            DefaultTrace.TraceInformation(
                string.Format(
                    CultureInfo.InvariantCulture,
                    "{0}, CorrelatedActivityId: {1} | Pipelined~Context.CreateAsync",
                    DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture),
                    constructorParams.CorrelatedActivityId));

            QueryInfo queryInfo = partitionedQueryExecutionInfo.QueryInfo;

            int actualPageSize = initialPageSize;

            if (queryInfo.HasGroupBy)
            {
                initialPageSize = int.MaxValue;
                constructorParams.QueryRequestOptions.MaxItemCount = int.MaxValue;
            }

            Func <string, Task <IDocumentQueryExecutionComponent> > createOrderByComponentFunc = async(continuationToken) =>
            {
                CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams initParams = new CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams(
                    collectionRid,
                    partitionedQueryExecutionInfo,
                    partitionKeyRanges,
                    initialPageSize,
                    continuationToken);

                return(await CosmosOrderByItemQueryExecutionContext.CreateAsync(
                           constructorParams,
                           initParams,
                           cancellationToken));
            };

            Func <string, Task <IDocumentQueryExecutionComponent> > createParallelComponentFunc = async(continuationToken) =>
            {
                CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams initParams = new CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams(
                    collectionRid,
                    partitionedQueryExecutionInfo,
                    partitionKeyRanges,
                    initialPageSize,
                    continuationToken);

                return(await CosmosParallelItemQueryExecutionContext.CreateAsync(
                           constructorParams,
                           initParams,
                           cancellationToken));
            };

            return((CosmosQueryExecutionContext)(await PipelinedDocumentQueryExecutionContext.CreateHelperAsync(
                                                     partitionedQueryExecutionInfo.QueryInfo,
                                                     initialPageSize,
                                                     requestContinuation,
                                                     constructorParams.QueryRequestOptions.EnableGroupBy,
                                                     createOrderByComponentFunc,
                                                     createParallelComponentFunc)));
        }
コード例 #6
0
        /// <summary>
        /// Creates a CosmosPipelinedItemQueryExecutionContext.
        /// </summary>
        /// <param name="executionEnvironment">The environment to execute on.</param>
        /// <param name="queryContext">The parameters for constructing the base class.</param>
        /// <param name="initParams">The initial parameters</param>
        /// <param name="requestContinuationToken">The request continuation.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A task to await on, which in turn returns a CosmosPipelinedItemQueryExecutionContext.</returns>
        public static async Task <CosmosQueryExecutionContext> CreateAsync(
            ExecutionEnvironment executionEnvironment,
            CosmosQueryContext queryContext,
            CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams initParams,
            string requestContinuationToken,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (requestContinuationToken != null)
            {
                if (!PipelineContinuationToken.TryParse(
                        requestContinuationToken,
                        out PipelineContinuationToken pipelineContinuationToken))
                {
                    throw queryContext.QueryClient.CreateBadRequestException(
                              $"Malformed {nameof(PipelineContinuationToken)}: {requestContinuationToken}.");
                }

                if (PipelineContinuationToken.IsTokenFromTheFuture(pipelineContinuationToken))
                {
                    throw queryContext.QueryClient.CreateBadRequestException(
                              $"{nameof(PipelineContinuationToken)} Continuation token is from a newer version of the SDK. Upgrade the SDK to avoid this issue.\n {requestContinuationToken}.");
                }

                if (!PipelineContinuationToken.TryConvertToLatest(
                        pipelineContinuationToken,
                        out PipelineContinuationTokenV1_1 latestVersionPipelineContinuationToken))
                {
                    throw queryContext.QueryClient.CreateBadRequestException(
                              $"{nameof(PipelineContinuationToken)}: '{requestContinuationToken}' is no longer supported.");
                }

                requestContinuationToken = latestVersionPipelineContinuationToken.SourceContinuationToken;
            }

            QueryInfo queryInfo = initParams.PartitionedQueryExecutionInfo.QueryInfo;

            int initialPageSize = initParams.InitialPageSize;

            CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams parameters = initParams;
            if (queryInfo.HasGroupBy)
            {
                // The query will block until all groupings are gathered so we might as well speed up the process.
                initParams = new CosmosCrossPartitionQueryExecutionContext.CrossPartitionInitParams(
                    sqlQuerySpec: initParams.SqlQuerySpec,
                    collectionRid: initParams.CollectionRid,
                    partitionedQueryExecutionInfo: initParams.PartitionedQueryExecutionInfo,
                    partitionKeyRanges: initParams.PartitionKeyRanges,
                    initialPageSize: int.MaxValue,
                    maxConcurrency: initParams.MaxConcurrency,
                    maxItemCount: int.MaxValue,
                    maxBufferedItemCount: initParams.MaxBufferedItemCount);
            }

            Func <string, Task <IDocumentQueryExecutionComponent> > createOrderByComponentFunc = async(continuationToken) =>
            {
                return(await CosmosOrderByItemQueryExecutionContext.CreateAsync(
                           queryContext,
                           initParams,
                           continuationToken,
                           cancellationToken));
            };

            Func <string, Task <IDocumentQueryExecutionComponent> > createParallelComponentFunc = async(continuationToken) =>
            {
                return(await CosmosParallelItemQueryExecutionContext.CreateAsync(
                           queryContext,
                           initParams,
                           continuationToken,
                           cancellationToken));
            };

            return((CosmosQueryExecutionContext)await PipelinedDocumentQueryExecutionContext.CreateHelperAsync(
                       executionEnvironment,
                       queryContext.QueryClient,
                       initParams.PartitionedQueryExecutionInfo.QueryInfo,
                       initialPageSize,
                       requestContinuationToken,
                       createOrderByComponentFunc,
                       createParallelComponentFunc));
        }
コード例 #7
0
        public static async Task <IDocumentQueryExecutionContext> CreateSpecializedDocumentQueryExecutionContext(
            IDocumentQueryClient client,
            ResourceType resourceTypeEnum,
            Type resourceType,
            Expression expression,
            FeedOptions feedOptions,
            string resourceLink,
            bool isContinuationExpected,
            PartitionedQueryExecutionInfo partitionedQueryExecutionInfo,
            List <PartitionKeyRange> targetRanges,
            string collectionRid,
            CancellationToken token,
            Guid correlatedActivityId)
        {
            long initialPageSize = feedOptions.MaxItemCount.GetValueOrDefault(ParallelQueryConfig.GetConfig().ClientInternalPageSize);

            if (initialPageSize < -1 || initialPageSize == 0)
            {
                throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, "Invalid MaxItemCount {0}", initialPageSize));
            }

            QueryInfo queryInfo = partitionedQueryExecutionInfo.QueryInfo;

            bool getLazyFeedResponse = queryInfo.HasTop;

            // We need to compute the optimal initial page size for order-by queries
            if (queryInfo.HasOrderBy)
            {
                int top;
                if (queryInfo.HasTop && (top = partitionedQueryExecutionInfo.QueryInfo.Top.Value) > 0)
                {
                    // All partitions should initially fetch about 1/nth of the top value.
                    long pageSizeWithTop = (long)Math.Min(
                        Math.Ceiling(top / (double)targetRanges.Count) * PageSizeFactorForTop,
                        top);

                    if (initialPageSize > 0)
                    {
                        initialPageSize = Math.Min(pageSizeWithTop, initialPageSize);
                    }
                    else
                    {
                        initialPageSize = pageSizeWithTop;
                    }
                }
                else if (isContinuationExpected)
                {
                    if (initialPageSize < 0)
                    {
                        // Max of what the user is willing to buffer and the default (note this is broken if MaxBufferedItemCount = -1)
                        initialPageSize = (long)Math.Max(feedOptions.MaxBufferedItemCount, ParallelQueryConfig.GetConfig().DefaultMaximumBufferSize);
                    }

                    initialPageSize = (long)Math.Min(
                        Math.Ceiling(initialPageSize / (double)targetRanges.Count) * PageSizeFactorForTop,
                        initialPageSize);
                }
            }

            Debug.Assert(initialPageSize > 0 && initialPageSize <= int.MaxValue,
                         string.Format(CultureInfo.InvariantCulture, "Invalid MaxItemCount {0}", initialPageSize));

            return(await PipelinedDocumentQueryExecutionContext.CreateAsync(
                       client,
                       resourceTypeEnum,
                       resourceType,
                       expression,
                       feedOptions,
                       resourceLink,
                       collectionRid,
                       partitionedQueryExecutionInfo,
                       targetRanges,
                       (int)initialPageSize,
                       isContinuationExpected,
                       getLazyFeedResponse,
                       token,
                       correlatedActivityId));
        }