private static void RunMatchRangesToContinuationTokens(
            IReadOnlyDictionary <PartitionKeyRange, IPartitionedToken> expectedMapping,
            IEnumerable <PartitionKeyRange> partitionKeyRanges,
            IEnumerable <IPartitionedToken> partitionedTokens)
        {
            IReadOnlyDictionary <PartitionKeyRange, IPartitionedToken> actualMapping = CosmosCrossPartitionQueryExecutionContext.MatchRangesToContinuationTokens(
                partitionKeyRanges.OrderBy(x => Guid.NewGuid()).ToArray(),
                partitionedTokens.OrderBy(x => Guid.NewGuid()).ToList());

            ContinuationResumeLogicTests.AssertPartitionMappingAreEqual(
                expectedMapping,
                actualMapping);
        }
        private static void RunTryGetInitializationInfo(
            IReadOnlyDictionary <PartitionKeyRange, IPartitionedToken> expectedMappingLeftPartitions,
            IReadOnlyDictionary <PartitionKeyRange, IPartitionedToken> expectedMappingTargetPartition,
            IReadOnlyDictionary <PartitionKeyRange, IPartitionedToken> expectedMappingRightPartitions,
            IEnumerable <PartitionKeyRange> partitionKeyRanges,
            IEnumerable <IPartitionedToken> partitionedTokens)
        {
            TryCatch <PartitionMapping <IPartitionedToken> > tryGetInitializationInfo = CosmosCrossPartitionQueryExecutionContext.TryGetInitializationInfo(
                partitionKeyRanges.OrderBy(x => Guid.NewGuid()).ToArray(),
                partitionedTokens.OrderBy(x => Guid.NewGuid()).ToList());

            Assert.IsTrue(tryGetInitializationInfo.Succeeded);
            PartitionMapping <IPartitionedToken> partitionMapping = tryGetInitializationInfo.Result;

            AssertPartitionMappingAreEqual(expectedMappingLeftPartitions, partitionMapping.PartitionsLeftOfTarget);
            AssertPartitionMappingAreEqual(expectedMappingTargetPartition, partitionMapping.TargetPartition);
            AssertPartitionMappingAreEqual(expectedMappingRightPartitions, partitionMapping.PartitionsRightOfTarget);
        }
        /// <summary>
        /// Gets the filters for every partition.
        /// </summary>
        private static TryCatch <OrderByInitInfo> TryGetOrderByPartitionKeyRangesInitializationInfo(
            OrderByContinuationToken[] suppliedContinuationTokens,
            List <PartitionKeyRange> partitionKeyRanges,
            SortOrder[] sortOrders,
            string[] orderByExpressions)
        {
            TryCatch <InitInfo <OrderByContinuationToken> > tryFindRangeAndContinuationTokensMonad = CosmosCrossPartitionQueryExecutionContext.TryFindTargetRangeAndExtractContinuationTokens(
                partitionKeyRanges,
                suppliedContinuationTokens
                .Select(token => Tuple.Create(token, token.CompositeContinuationToken.Range)));

            return(tryFindRangeAndContinuationTokensMonad.Try <OrderByInitInfo>((indexAndContinuationTokens) =>
            {
                int minIndex = indexAndContinuationTokens.TargetIndex;
                IReadOnlyDictionary <string, OrderByContinuationToken> partitionKeyRangeToContinuationToken = indexAndContinuationTokens.ContinuationTokens;

                FormattedFilterInfo formattedFilterInfo = CosmosOrderByItemQueryExecutionContext.GetFormattedFilters(
                    orderByExpressions,
                    suppliedContinuationTokens,
                    sortOrders);

                RangeFilterInitializationInfo[] filters = new RangeFilterInitializationInfo[]
                {
                    new RangeFilterInitializationInfo(
                        filter: formattedFilterInfo.FilterForRangesLeftOfTargetRanges,
                        startIndex: 0,
                        endIndex: minIndex - 1),
                    new RangeFilterInitializationInfo(
                        filter: formattedFilterInfo.FiltersForTargetRange,
                        startIndex: minIndex,
                        endIndex: minIndex),
                    new RangeFilterInitializationInfo(
                        filter: formattedFilterInfo.FilterForRangesRightOfTargetRanges,
                        startIndex: minIndex + 1,
                        endIndex: partitionKeyRanges.Count - 1),
                };

                return new OrderByInitInfo(
                    filters,
                    partitionKeyRangeToContinuationToken);
            }));
        }