/// <summary> /// Gets whether or not we should increment the skip count based on the rid of the document. /// </summary> /// <param name="currentItemProducer">The current document producer.</param> /// <returns>Whether or not we should increment the skip count.</returns> private bool ShouldIncrementSkipCount(ItemProducer currentItemProducer) { // If we are not at the beginning of the page and we saw the same rid again. return(!currentItemProducer.IsAtBeginningOfPage && string.Equals( this.previousRid, new OrderByQueryResult(currentItemProducer.Current).Rid, StringComparison.Ordinal)); }
/// <summary> /// Initializes a new instance of the ItemProducerTree class. /// </summary> /// <param name="queryContext">query context.</param> /// <param name="querySpecForInit">query spec init.</param> /// <param name="partitionKeyRange">The partition key range.</param> /// <param name="createRetryPolicyFunc">Callback to create a retry policy.</param> /// <param name="produceAsyncCompleteCallback">Callback to invoke once a fetch finishes.</param> /// <param name="itemProducerTreeComparer">Comparer to determine, which tree to produce from.</param> /// <param name="equalityComparer">Comparer to see if we need to return the continuation token for a partition.</param> /// <param name="deferFirstPage">Whether or not to defer fetching the first page.</param> /// <param name="collectionRid">The collection to drain from.</param> /// <param name="initialPageSize">The initial page size.</param> /// <param name="initialContinuationToken">The initial continuation token.</param> public ItemProducerTree( CosmosQueryContext queryContext, SqlQuerySpec querySpecForInit, PartitionKeyRange partitionKeyRange, Func <IDocumentClientRetryPolicy> createRetryPolicyFunc, Action <ItemProducerTree, int, double, QueryMetrics, long, CancellationToken> produceAsyncCompleteCallback, IComparer <ItemProducerTree> itemProducerTreeComparer, IEqualityComparer <CosmosElement> equalityComparer, bool deferFirstPage, string collectionRid, long initialPageSize = 50, string initialContinuationToken = null) { if (queryContext == null) { throw new ArgumentNullException($"{nameof(queryContext)}"); } if (itemProducerTreeComparer == null) { throw new ArgumentNullException($"{nameof(itemProducerTreeComparer)}"); } if (createRetryPolicyFunc == null) { throw new ArgumentNullException($"{nameof(createRetryPolicyFunc)}"); } if (produceAsyncCompleteCallback == null) { throw new ArgumentNullException($"{nameof(produceAsyncCompleteCallback)}"); } if (itemProducerTreeComparer == null) { throw new ArgumentNullException($"{nameof(itemProducerTreeComparer)}"); } if (equalityComparer == null) { throw new ArgumentNullException($"{nameof(equalityComparer)}"); } if (string.IsNullOrEmpty(collectionRid)) { throw new ArgumentException($"{nameof(collectionRid)} can not be null or empty."); } this.root = new ItemProducer( queryContext, querySpecForInit, partitionKeyRange, createRetryPolicyFunc, (itemProducer, itemsBuffered, resourceUnitUsage, queryMetrics, requestLength, token) => produceAsyncCompleteCallback(this, itemsBuffered, resourceUnitUsage, queryMetrics, requestLength, token), equalityComparer, initialPageSize, initialContinuationToken); this.queryClient = queryContext.QueryClient; this.children = new PriorityQueue <ItemProducerTree>(itemProducerTreeComparer, true); this.deferFirstPage = deferFirstPage; this.collectionRid = collectionRid; this.createItemProducerTreeCallback = ItemProducerTree.CreateItemProducerTreeCallback( queryContext, querySpecForInit, createRetryPolicyFunc, produceAsyncCompleteCallback, itemProducerTreeComparer, equalityComparer, deferFirstPage, collectionRid, initialPageSize); this.executeWithSplitProofingSemaphore = new SemaphoreSlim(1, 1); }