Ejemplo n.º 1
0
        public static IMergeAlgorithm GetMergeAlgo(MergeAlgo ma, Type type)
        {
            IMergeAlgorithm a;

            m_MergeAlgorithms.TryGetValue(new MergeAlgoKey(ma, type), out a);
            return(a);
        }
Ejemplo n.º 2
0
 public MergeAlgoKey(MergeAlgo algo, Type ColumnDataType)
 {
     this.algo = algo;
     this.type = ColumnDataType;
 }
Ejemplo n.º 3
0
        public override SpanQueryResult MergeResults(IList <SpanQueryResult> partialResults)
        {
            SpanQueryResult finalResult = default(SpanQueryResult);

            if (partialResults == null || partialResults.Count == 0)
            {
                return(finalResult);
            }

            // We have partialResults to process
            ByteArrayEqualityComparer byteArrayEqualityComparer = new ByteArrayEqualityComparer();
            Dictionary <byte[] /*IndexId*/, IndexHeader /*IndexHeader*/> completeIndexIdIndexHeaderMapping =
                new Dictionary <byte[], IndexHeader>(byteArrayEqualityComparer);

            if (partialResults.Count == 1)
            {
                #region  Just one cluster was targeted, so no need to merge anything
                finalResult = partialResults[0];
                #endregion
            }
            else
            {
                #region  More than one clusters was targeted

                List <ResultItem> completeResultItemList = new List <ResultItem>();
                BaseComparer      baseComparer;
                int totalCount = 0;
                int additionalAvailableItemCount = 0;

                foreach (SpanQueryResult partialResult in partialResults)
                {
                    if (partialResult != null)
                    {
                        #region Compute TotalCount
                        totalCount += partialResult.TotalCount;
                        #endregion

                        #region Compute PageableItemCount
                        if (GetAdditionalAvailableItemCount)
                        {
                            additionalAvailableItemCount += partialResult.AdditionalAvailableItemCount;
                        }
                        #endregion

                        #region Merge Results
                        if (partialResult.ResultItemList != null && partialResult.ResultItemList.Count > 0)
                        {
                            baseComparer = new BaseComparer(partialResult.IsTagPrimarySort, partialResult.SortFieldName, partialResult.SortOrderList);
                            MergeAlgo.MergeItemLists(ref completeResultItemList, partialResult.ResultItemList, MaxMergeCount, baseComparer);
                        }
                        #endregion

                        #region Update IndexIdIndexHeaderMapping
                        if (GetIndexHeaderType != GetIndexHeaderType.None &&
                            partialResult.IndexIdIndexHeaderMapping != null &&
                            partialResult.IndexIdIndexHeaderMapping.Count > 0)
                        {
                            foreach (KeyValuePair <byte[], IndexHeader> kvp in partialResult.IndexIdIndexHeaderMapping)
                            {
                                if (!completeIndexIdIndexHeaderMapping.ContainsKey(kvp.Key))
                                {
                                    completeIndexIdIndexHeaderMapping.Add(kvp.Key, kvp.Value);
                                }
                            }
                        }
                        #endregion
                    }
                }

                #region Create FinalResult
                finalResult = new SpanQueryResult
                {
                    ResultItemList = completeResultItemList,
                    TotalCount     = totalCount,
                    AdditionalAvailableItemCount = additionalAvailableItemCount,
                };
                if (GetIndexHeaderType != GetIndexHeaderType.None && completeIndexIdIndexHeaderMapping.Count > 0)
                {
                    finalResult.IndexIdIndexHeaderMapping = completeIndexIdIndexHeaderMapping;
                }
                #endregion

                #endregion
            }

            #region Spanning and Update IndexIdIndexHeaderMapping if required
            if (ClientSideSubsetProcessingRequired && Span != 0 && finalResult != null)
            {
                #region Spanning
                List <ResultItem> filteredResultItemList = new List <ResultItem>();
                if (finalResult.ResultItemList.Count >= Offset)
                {
                    for (int i = Offset - 1; i < finalResult.ResultItemList.Count && filteredResultItemList.Count < Span; i++)
                    {
                        filteredResultItemList.Add(finalResult.ResultItemList[i]);
                    }
                }
                finalResult.ResultItemList = filteredResultItemList;
                #endregion

                #region Update IndexIdIndexHeaderMapping to only include metadata relevant after paging
                if (partialResults.Count != 1 && GetIndexHeaderType == GetIndexHeaderType.ResultItemsIndexIds && completeIndexIdIndexHeaderMapping.Count > 0)
                {
                    Dictionary <byte[] /*IndexId*/, IndexHeader /*IndexHeader*/> filteredIndexIdIndexHeaderMapping = new Dictionary <byte[], IndexHeader>(byteArrayEqualityComparer);
                    foreach (ResultItem resultItem in finalResult.ResultItemList)
                    {
                        if (!filteredIndexIdIndexHeaderMapping.ContainsKey(resultItem.IndexId))
                        {
                            filteredIndexIdIndexHeaderMapping.Add(resultItem.IndexId, completeIndexIdIndexHeaderMapping[resultItem.IndexId]);
                        }
                    }
                    finalResult.IndexIdIndexHeaderMapping = filteredIndexIdIndexHeaderMapping.Count > 0 ? filteredIndexIdIndexHeaderMapping : null;
                }
                #endregion
            }
            #endregion
            return(finalResult);
        }
        /// <summary>
        /// Processes the specified query.
        /// </summary>
        /// <param name="query">The query.</param>
        /// <param name="messageContext">The message context.</param>
        /// <param name="storeContext">The store context.</param>
        /// <returns>Query Result</returns>
        internal TQueryResult Process(BaseMultiIndexIdQuery <TQueryResult> query,
                                      MessageContext messageContext,
                                      IndexStoreContext storeContext)
        {
            TQueryResult      result;
            List <ResultItem> resultItemList = new List <ResultItem>();
            Dictionary <byte[], IndexHeader> indexIdIndexHeaderMapping = null;
            bool             isTagPrimarySort             = false;
            string           sortFieldName                = null;
            List <SortOrder> sortOrderList                = null;
            int              totalCount                   = 0;
            int              additionalAvailableItemCount = 0;
            GroupByResult    groupByResult                = null;
            StringBuilder    exceptionInfo                = new StringBuilder();
            int              indexCap         = 0;
            IndexTypeMapping indexTypeMapping =
                storeContext.StorageConfiguration.CacheIndexV3StorageConfig.IndexTypeMappingCollection[messageContext.TypeId];

            try
            {
                if (query.IndexIdList.Count > 0)
                {
                    #region Validate Query

                    ValidateQuery(indexTypeMapping, query, messageContext);

                    #endregion

                    #region Set sort vars

                    Index targetIndexInfo = indexTypeMapping.IndexCollection[query.TargetIndexName];
                    indexCap = targetIndexInfo.MaxIndexSize;

                    if (query.TagSort != null)
                    {
                        isTagPrimarySort = query.TagSort.IsTag;
                        sortFieldName    = query.TagSort.TagName;
                        sortOrderList    = new List <SortOrder>(1)
                        {
                            query.TagSort.SortOrder
                        };
                    }
                    else
                    {
                        isTagPrimarySort = targetIndexInfo.PrimarySortInfo.IsTag;
                        sortFieldName    = targetIndexInfo.PrimarySortInfo.FieldName;
                        sortOrderList    = targetIndexInfo.PrimarySortInfo.SortOrderList;
                    }
                    BaseComparer baseComparer = new BaseComparer(isTagPrimarySort, sortFieldName, sortOrderList);
                    groupByResult = new GroupByResult(baseComparer);
                    #endregion

                    #region Prepare ResultList

                    CacheIndexInternal targetIndex;
                    IndexIdParams      indexIdParam;
                    int    maxExtractCount;
                    byte[] metadata;
                    MetadataPropertyCollection metadataPropertyCollection;
                    Dictionary <KeyValuePair <byte[], string>, CacheIndexInternal> internalIndexDictionary = new Dictionary <KeyValuePair <byte[], string>, CacheIndexInternal>();

                    int maxMergeCount = query.MaxMergeCount;

                    IndexCondition queryIndexCondition = query.IndexCondition;

                    for (int i = 0; i < query.IndexIdList.Count; i++)
                    {
                        #region Extract index and apply criteria

                        indexIdParam    = query.GetParamsForIndexId(query.IndexIdList[i]);
                        maxExtractCount = ComputeMaxExtractCount(indexIdParam.MaxItems,
                                                                 query.GetAdditionalAvailableItemCount,
                                                                 indexIdParam.Filter,
                                                                 query.MaxMergeCount);

                        // Note: This should be changed later and just extracted once if it is also requested in GetIndexHeader
                        metadata = null;
                        metadataPropertyCollection = null;
                        if (indexTypeMapping.MetadataStoredSeperately)
                        {
                            IndexServerUtils.GetMetadataStoredSeperately(indexTypeMapping,
                                                                         messageContext.TypeId,
                                                                         messageContext.PrimaryId,
                                                                         query.IndexIdList[i],
                                                                         storeContext,
                                                                         out metadata,
                                                                         out metadataPropertyCollection);
                        }

                        targetIndex = IndexServerUtils.GetCacheIndexInternal(storeContext,
                                                                             messageContext.TypeId,
                                                                             (query.PrimaryIdList != null && i < query.PrimaryIdList.Count) ?
                                                                             query.PrimaryIdList[i] :
                                                                             IndexCacheUtils.GeneratePrimaryId(query.IndexIdList[i]),
                                                                             query.IndexIdList[i],
                                                                             targetIndexInfo.ExtendedIdSuffix,
                                                                             query.TargetIndexName,
                                                                             maxExtractCount,
                                                                             indexIdParam.Filter,
                                                                             true,
                                                                             queryIndexCondition,
                                                                             false,
                                                                             false,
                                                                             targetIndexInfo.PrimarySortInfo,
                                                                             targetIndexInfo.LocalIdentityTagList,
                                                                             targetIndexInfo.StringHashCodeDictionary,
                                                                             query.CapCondition,
                                                                             targetIndexInfo.IsMetadataPropertyCollection,
                                                                             metadataPropertyCollection,
                                                                             query.DomainSpecificProcessingType,
                                                                             storeContext.DomainSpecificConfig,
                                                                             null,
                                                                             query.GroupBy,
                                                                             false);

                        #endregion

                        if (targetIndex != null)
                        {
                            totalCount += targetIndex.OutDeserializationContext.TotalCount;
                            additionalAvailableItemCount += targetIndex.Count;
                            internalIndexDictionary.Add(new KeyValuePair <byte[], string>(query.IndexIdList[i], query.TargetIndexName),
                                                        targetIndex);

                            SetItemCounter(messageContext.TypeId, targetIndex.OutDeserializationContext);

                            #region Dynamic tag sort

                            if (query.TagSort != null)
                            {
                                targetIndex.Sort(query.TagSort);
                            }

                            #endregion

                            #region Get items from index and merge

                            if (query.GroupBy == null)
                            {
                                MergeAlgo.MergeItemLists(ref resultItemList,
                                                         CacheIndexInternalAdapter.GetResultItemList(targetIndex, 1, int.MaxValue),
                                                         query.MaxMergeCount,
                                                         baseComparer);
                            }
                            else
                            {
                                MergeAlgo.MergeGroupResult(ref groupByResult,
                                                           targetIndex.GroupByResult,
                                                           query.MaxMergeCount,
                                                           baseComparer);
                            }

                            if ((i != query.IndexIdList.Count - 1) && (resultItemList.Count == maxMergeCount))
                            {
                                AdjustIndexCondition(GetConditionBoundaryBytes(resultItemList, groupByResult, query.GroupBy, isTagPrimarySort, sortFieldName),
                                                     ref queryIndexCondition,
                                                     baseComparer);
                            }

                            #endregion
                        }
                    }

                    #endregion

                    #region Subset Processing

                    ProcessSubsets(query, ref resultItemList, ref groupByResult, baseComparer);

                    #endregion

                    #region Get Extra Tags for IndexIds in the list

                    //Note: Getting extra tags from GroupByResult not supported for now

                    if (query.TagsFromIndexes != null && query.TagsFromIndexes.Count != 0)
                    {
                        KeyValuePair <byte[] /*IndexId */, string /*IndexName*/> kvp;
                        CacheIndexInternal additionalCacheIndexInternal;

                        #region Form IndexId - PrimaryId Mapping

                        Dictionary <byte[] /*IndexId */, int /*PrimaryId*/> indexIdPrimaryIdMapping =
                            new Dictionary <byte[] /*IndexId */, int /*PrimaryId*/>(query.IndexIdList.Count, new ByteArrayEqualityComparer());
                        if (query.PrimaryIdList != null && query.PrimaryIdList.Count > 0)
                        {
                            //Form dictionary of IndexIdPrimaryIdMapping
                            for (int i = 0; i < query.IndexIdList.Count && i < query.PrimaryIdList.Count; i++)
                            {
                                indexIdPrimaryIdMapping.Add(query.IndexIdList[i], query.PrimaryIdList[i]);
                            }
                        }

                        #endregion

                        int indexPrimaryId;
                        foreach (ResultItem resultItem in resultItemList)
                        {
                            foreach (string indexName in query.TagsFromIndexes)
                            {
                                Index indexInfo = indexTypeMapping.IndexCollection[indexName];
                                kvp = new KeyValuePair <byte[], string>(resultItem.IndexId, indexName);
                                if (!internalIndexDictionary.ContainsKey(kvp))
                                {
                                    additionalCacheIndexInternal = IndexServerUtils.GetCacheIndexInternal(storeContext,
                                                                                                          messageContext.TypeId,
                                                                                                          indexIdPrimaryIdMapping.TryGetValue(resultItem.IndexId, out indexPrimaryId) ?
                                                                                                          indexPrimaryId :
                                                                                                          IndexCacheUtils.GeneratePrimaryId(resultItem.IndexId),
                                                                                                          resultItem.IndexId,
                                                                                                          indexInfo.ExtendedIdSuffix,
                                                                                                          indexName,
                                                                                                          0,
                                                                                                          null,
                                                                                                          true,
                                                                                                          null,
                                                                                                          false,
                                                                                                          false,
                                                                                                          indexInfo.PrimarySortInfo,
                                                                                                          indexInfo.LocalIdentityTagList,
                                                                                                          indexInfo.StringHashCodeDictionary,
                                                                                                          null,
                                                                                                          indexInfo.IsMetadataPropertyCollection,
                                                                                                          null,
                                                                                                          query.DomainSpecificProcessingType,
                                                                                                          storeContext.DomainSpecificConfig,
                                                                                                          null,
                                                                                                          null,
                                                                                                          false);

                                    if (additionalCacheIndexInternal != null)
                                    {
                                        SetItemCounter(messageContext.TypeId, additionalCacheIndexInternal.OutDeserializationContext);

                                        internalIndexDictionary.Add(kvp, additionalCacheIndexInternal);
                                        try
                                        {
                                            IndexServerUtils.GetTags(additionalCacheIndexInternal, resultItem, resultItem);
                                        }
                                        catch (Exception ex)
                                        {
                                            LoggingUtil.Log.Error(ex.ToString());
                                            exceptionInfo.Append(" | " + ex.Message);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    #endregion

                    #region Get IndexHeader

                    if (query.GetIndexHeaderType == GetIndexHeaderType.AllIndexIds)
                    {
                        //Get IndexHeader for all IndexIds
                        indexIdIndexHeaderMapping = new Dictionary <byte[], IndexHeader>(new ByteArrayEqualityComparer());

                        for (int i = 0; i < query.IndexIdList.Count; i++)
                        {
                            byte[]             indexId = query.IndexIdList[i];
                            CacheIndexInternal targetIndexCacheIndexInternal;

                            if (!indexIdIndexHeaderMapping.ContainsKey(indexId) &&
                                internalIndexDictionary.TryGetValue(new KeyValuePair <byte[], string>(indexId, query.TargetIndexName), out targetIndexCacheIndexInternal))
                            {
                                indexIdIndexHeaderMapping.Add(indexId, GetIndexHeader(internalIndexDictionary,
                                                                                      targetIndexCacheIndexInternal,
                                                                                      indexId,
                                                                                      query,
                                                                                      indexTypeMapping,
                                                                                      messageContext.TypeId,
                                                                                      storeContext,
                                                                                      i));
                            }
                        }
                    }
                    else if (query.GetIndexHeaderType == GetIndexHeaderType.ResultItemsIndexIds)
                    {
                        //Get IndexHeader just for IndexIds present in the result
                        indexIdIndexHeaderMapping = new Dictionary <byte[], IndexHeader>(new ByteArrayEqualityComparer());

                        if (query.GroupBy == null)
                        {
                            for (int i = 0; i < resultItemList.Count; i++)
                            {
                                ResultItem resultItem = resultItemList[i];
                                if (!indexIdIndexHeaderMapping.ContainsKey(resultItem.IndexId))
                                {
                                    CacheIndexInternal targetIndexCacheIndexInternal;
                                    internalIndexDictionary.TryGetValue(new KeyValuePair <byte[], string>(resultItem.IndexId, query.TargetIndexName),
                                                                        out targetIndexCacheIndexInternal);
                                    indexIdIndexHeaderMapping.Add(resultItem.IndexId,
                                                                  GetIndexHeader(internalIndexDictionary,
                                                                                 targetIndexCacheIndexInternal,
                                                                                 resultItem.IndexId,
                                                                                 query,
                                                                                 indexTypeMapping,
                                                                                 messageContext.TypeId,
                                                                                 storeContext,
                                                                                 i));
                                }
                            }
                        }
                        else
                        {
                            foreach (ResultItemBag resultItemBag in groupByResult)
                            {
                                for (int i = 0; i < resultItemBag.Count; i++)
                                {
                                    ResultItem resultItem = resultItemBag[i];
                                    if (!indexIdIndexHeaderMapping.ContainsKey(resultItem.IndexId))
                                    {
                                        CacheIndexInternal targetIndexCacheIndexInternal;
                                        internalIndexDictionary.TryGetValue(new KeyValuePair <byte[], string>(resultItem.IndexId, query.TargetIndexName),
                                                                            out targetIndexCacheIndexInternal);
                                        indexIdIndexHeaderMapping.Add(resultItem.IndexId,
                                                                      GetIndexHeader(internalIndexDictionary,
                                                                                     targetIndexCacheIndexInternal,
                                                                                     resultItem.IndexId,
                                                                                     query,
                                                                                     indexTypeMapping,
                                                                                     messageContext.TypeId,
                                                                                     storeContext,
                                                                                     i));
                                    }
                                }
                            }
                        }
                    }

                    #endregion

                    #region Get data

                    if (!query.ExcludeData)
                    {
                        DataTierUtil.GetData(resultItemList,
                                             groupByResult,
                                             storeContext, messageContext,
                                             indexTypeMapping.FullDataIdFieldList,
                                             query.FullDataIdInfo);
                    }

                    #endregion
                }

                result = new TQueryResult
                {
                    ResultItemList            = resultItemList,
                    IndexIdIndexHeaderMapping = indexIdIndexHeaderMapping,
                    TotalCount = totalCount,
                    AdditionalAvailableItemCount = additionalAvailableItemCount,
                    IsTagPrimarySort             = isTagPrimarySort,
                    SortFieldName = sortFieldName,
                    SortOrderList = sortOrderList,
                    IndexCap      = indexCap,
                    GroupByResult = groupByResult,
                    ExceptionInfo = exceptionInfo.ToString()
                };

                #region Log Potentially Bad Queries

                if (indexTypeMapping.QueryOverrideSettings != null &&
                    indexTypeMapping.QueryOverrideSettings.MaxResultItemsThresholdLog > 0 &&
                    resultItemList != null &&
                    resultItemList.Count > indexTypeMapping.QueryOverrideSettings.MaxResultItemsThresholdLog)
                {
                    LoggingUtil.Log.ErrorFormat("Encountered potentially Bad Paged Query with Large Result Set of {0}.  AddressHistory: {1}.  Query Info: {2}",
                                                resultItemList.Count,
                                                IndexServerUtils.FormatAddressHistory(messageContext.AddressHistory),
                                                FormatQueryInfo(query));
                }

                LoggingUtil.Log.DebugFormat("QueryInfo: {0}, AddressHistory: {1}", FormatQueryInfo(query), IndexServerUtils.FormatAddressHistory(messageContext.AddressHistory));

                #endregion

                SetIndexIdListCounter(messageContext.TypeId, query);
            }
            catch (Exception ex)
            {
                exceptionInfo.Append(" | " + ex.Message);
                result = new TQueryResult
                {
                    ExceptionInfo = exceptionInfo.ToString()
                };
                LoggingUtil.Log.ErrorFormat("TypeId {0} -- Error processing PagedIndexQuery : {1}", messageContext.TypeId, ex);
            }
            return(result);
        }
Ejemplo n.º 5
0
        public override PagedIndexQueryResult MergeResults(IList <PagedIndexQueryResult> partialResults)
        {
            PagedIndexQueryResult finalResult = default(PagedIndexQueryResult);

            if (partialResults == null || partialResults.Count == 0)
            {
                return(finalResult);
            }

            // We have partialResults to process
            BaseComparer baseComparer = null;
            ByteArrayEqualityComparer byteArrayEqualityComparer = new ByteArrayEqualityComparer();
            Dictionary <byte[] /*IndexId*/, IndexHeader /*IndexHeader*/> completeIndexIdIndexHeaderMapping =
                new Dictionary <byte[], IndexHeader>(byteArrayEqualityComparer);

            // resultVer required to determine if server is correctly performing paging logic
            int resultVer = 0;

            if (partialResults.Count == 1)
            {
                #region  Just one cluster was targeted, so no need to merge anything

                finalResult = partialResults[0];
                if (finalResult != null)
                {
                    resultVer = finalResult.CurrentVersion;
                }

                #endregion
            }
            else
            {
                #region  More than one clusters was targeted

                List <ResultItem> completeResultItemList = new List <ResultItem>();
                GroupByResult     completeGroupByResult  = new GroupByResult(null);
                int           totalCount             = 0;
                int           pageableItemCount      = 0;
                StringBuilder exceptionStringBuilder = new StringBuilder();
                bool          indexCapSet            = false;
                int           indexCap = 0;

                foreach (PagedIndexQueryResult partialResult in partialResults)
                {
                    if (partialResult != null)
                    {
                        #region Update resultVer

                        if (resultVer == 0)
                        {
                            resultVer = partialResult.CurrentVersion;
                        }

                        #endregion

                        #region Assign IndexCap

                        if (!indexCapSet)
                        {
                            indexCap    = partialResult.IndexCap;
                            indexCapSet = true;
                        }

                        #endregion

                        #region Compute TotalCount

                        totalCount += partialResult.TotalCount;

                        #endregion

                        #region Compute PageableItemCount

                        if (GetPageableItemCount)
                        {
                            pageableItemCount += partialResult.AdditionalAvailableItemCount;
                        }

                        #endregion

                        #region Merge Results

                        if ((partialResult.ResultItemList != null && partialResult.ResultItemList.Count > 0) ||
                            (partialResult.GroupByResult != null && partialResult.GroupByResult.Count > 0))
                        {
                            if (baseComparer == null)
                            {
                                baseComparer = new BaseComparer(partialResult.IsTagPrimarySort,
                                                                partialResult.SortFieldName,
                                                                partialResult.SortOrderList);
                                completeGroupByResult = new GroupByResult(baseComparer);
                            }

                            if (GroupBy == null)
                            {
                                MergeAlgo.MergeItemLists(ref completeResultItemList,
                                                         partialResult.ResultItemList,
                                                         MaxMergeCount,
                                                         baseComparer);
                            }
                            else
                            {
                                MergeAlgo.MergeGroupResult(ref completeGroupByResult,
                                                           partialResult.GroupByResult,
                                                           MaxMergeCount,
                                                           baseComparer);
                            }
                        }
                        #endregion

                        #region Update IndexIdIndexHeaderMapping

                        if (GetIndexHeaderType != GetIndexHeaderType.None &&
                            partialResult.IndexIdIndexHeaderMapping != null &&
                            partialResult.IndexIdIndexHeaderMapping.Count > 0)
                        {
                            foreach (KeyValuePair <byte[], IndexHeader> kvp in partialResult.IndexIdIndexHeaderMapping)
                            {
                                if (!completeIndexIdIndexHeaderMapping.ContainsKey(kvp.Key))
                                {
                                    completeIndexIdIndexHeaderMapping.Add(kvp.Key, kvp.Value);
                                }
                            }
                        }

                        #endregion

                        #region Update exceptionInfo

                        if (!String.IsNullOrEmpty(partialResult.ExceptionInfo))
                        {
                            exceptionStringBuilder.Append(partialResult.ExceptionInfo);
                            exceptionStringBuilder.Append(" ");
                        }

                        #endregion
                    }
                }

                #region Create FinalResult

                finalResult = new PagedIndexQueryResult
                {
                    ResultItemList = completeResultItemList,
                    GroupByResult  = completeGroupByResult,
                    TotalCount     = totalCount,
                    AdditionalAvailableItemCount = pageableItemCount,
                    IndexCap = indexCap,
                };

                //Assign sort fields for use in GroupBy remote queries
                if (baseComparer != null)
                {
                    finalResult.IsTagPrimarySort = baseComparer.IsTagPrimarySort;
                    finalResult.SortFieldName    = baseComparer.SortFieldName;
                    finalResult.SortOrderList    = baseComparer.SortOrderList;
                }

                if (GetIndexHeaderType != GetIndexHeaderType.None && completeIndexIdIndexHeaderMapping.Count > 0)
                {
                    finalResult.IndexIdIndexHeaderMapping = completeIndexIdIndexHeaderMapping;
                }

                if (exceptionStringBuilder.Length > 0)
                {
                    finalResult.ExceptionInfo = exceptionStringBuilder.ToString();
                }

                #endregion

                #endregion
            }

            #region Determine whether client side paging is required

            bool performClientSidePaging;
            if (resultVer < PagedIndexQueryResult.CORRECT_SERVERSIDE_PAGING_LOGIC_VERSION)
            {
                // this.ClientSidePaging cannot be trusted
                performClientSidePaging = numClustersInGroup > 1 && PageNum != 0;
            }
            else
            {
                // this.ClientSidePaging can be trusted
                performClientSidePaging = ClientSidePaging && PageNum != 0;
            }

            #endregion

            #region Perform Paging and Update IndexIdIndexHeaderMapping if required

            if (performClientSidePaging && finalResult != null)
            {
                #region Paging Logic

                int start = (PageNum - 1) * PageSize;
                if (GroupBy == null)
                {
                    int end = (PageNum * PageSize) < finalResult.ResultItemList.Count ? (PageNum * PageSize) : finalResult.ResultItemList.Count;
                    List <ResultItem> filteredResultItemList = new List <ResultItem>();
                    for (int i = start; i < end; i++)
                    {
                        filteredResultItemList.Add(finalResult.ResultItemList[i]);
                    }
                    finalResult.ResultItemList = filteredResultItemList;
                }
                else if (finalResult.GroupByResult != null && finalResult.GroupByResult.Count > 0)
                {
                    int           end = (PageNum * PageSize) < finalResult.GroupByResult.Count ? (PageNum * PageSize) : finalResult.GroupByResult.Count;
                    GroupByResult filteredGroupByResult = new GroupByResult(baseComparer);
                    for (int i = start; i < end; i++)
                    {
                        filteredGroupByResult.Add(finalResult.GroupByResult[i].CompositeKey, finalResult.GroupByResult[i]);
                    }
                    finalResult.GroupByResult = filteredGroupByResult;
                }

                #endregion

                #region Update IndexIdIndexHeaderMapping to only include metadata relevant after paging

                if (partialResults.Count != 1 && GetIndexHeaderType == GetIndexHeaderType.ResultItemsIndexIds && completeIndexIdIndexHeaderMapping.Count > 0)
                {
                    Dictionary <byte[] /*IndexId*/, IndexHeader /*IndexHeader*/> filteredIndexIdIndexHeaderMapping =
                        new Dictionary <byte[], IndexHeader>(byteArrayEqualityComparer);
                    if (GroupBy == null)
                    {
                        foreach (ResultItem resultItem in finalResult.ResultItemList)
                        {
                            if (!filteredIndexIdIndexHeaderMapping.ContainsKey(resultItem.IndexId))
                            {
                                filteredIndexIdIndexHeaderMapping.Add(resultItem.IndexId, completeIndexIdIndexHeaderMapping[resultItem.IndexId]);
                            }
                        }
                    }
                    else if (finalResult.GroupByResult != null && finalResult.GroupByResult.Count > 0)
                    {
                        foreach (ResultItemBag resultItemBag in finalResult.GroupByResult)
                        {
                            for (int i = 0; i < resultItemBag.Count; i++)
                            {
                                ResultItem resultItem = resultItemBag[i];
                                if (!filteredIndexIdIndexHeaderMapping.ContainsKey(resultItem.IndexId))
                                {
                                    filteredIndexIdIndexHeaderMapping.Add(resultItem.IndexId, completeIndexIdIndexHeaderMapping[resultItem.IndexId]);
                                }
                            }
                        }
                    }
                    finalResult.IndexIdIndexHeaderMapping = filteredIndexIdIndexHeaderMapping.Count > 0 ? filteredIndexIdIndexHeaderMapping : null;
                }

                #endregion
            }

            #endregion

            return(finalResult);
        }
Ejemplo n.º 6
0
        public override SpanQueryResult MergeResults(IList <SpanQueryResult> partialResults)
        {
            SpanQueryResult finalResult = default(SpanQueryResult);

            if (partialResults == null || partialResults.Count == 0)
            {
                return(finalResult);
            }

            // We have partialResults to process
            ByteArrayEqualityComparer byteArrayEqualityComparer = new ByteArrayEqualityComparer();
            BaseComparer baseComparer = null;
            Dictionary <byte[] /*IndexId*/, IndexHeader /*IndexHeader*/> completeIndexIdIndexHeaderMapping =
                new Dictionary <byte[], IndexHeader>(byteArrayEqualityComparer);

            if (partialResults.Count == 1)
            {
                #region  Just one cluster was targeted, so no need to merge anything

                finalResult = partialResults[0];

                #endregion
            }
            else
            {
                #region  More than one clusters was targeted

                List <ResultItem> completeResultItemList = new List <ResultItem>();
                GroupByResult     completeGroupByResult  = new GroupByResult(null);
                int           totalCount = 0;
                int           additionalAvailableItemCount = 0;
                StringBuilder exceptionStringBuilder       = new StringBuilder();
                bool          indexCapSet = false;
                int           indexCap    = 0;

                foreach (SpanQueryResult partialResult in partialResults)
                {
                    if (partialResult != null)
                    {
                        #region Compute TotalCount

                        totalCount += partialResult.TotalCount;

                        #endregion

                        #region Assign IndexCap

                        if (!indexCapSet)
                        {
                            indexCap    = partialResult.IndexCap;
                            indexCapSet = true;
                        }

                        #endregion

                        #region Compute PageableItemCount

                        if (GetAdditionalAvailableItemCount)
                        {
                            additionalAvailableItemCount += partialResult.AdditionalAvailableItemCount;
                        }

                        #endregion

                        #region Merge Results

                        if ((partialResult.ResultItemList != null && partialResult.ResultItemList.Count > 0) ||
                            (partialResult.GroupByResult != null && partialResult.GroupByResult.Count > 0))
                        {
                            if (baseComparer == null)
                            {
                                baseComparer = new BaseComparer(partialResult.IsTagPrimarySort,
                                                                partialResult.SortFieldName,
                                                                partialResult.SortOrderList);
                                completeGroupByResult = new GroupByResult(baseComparer);
                            }

                            if (GroupBy == null)
                            {
                                MergeAlgo.MergeItemLists(ref completeResultItemList,
                                                         partialResult.ResultItemList,
                                                         MaxMergeCount,
                                                         baseComparer);
                            }
                            else
                            {
                                MergeAlgo.MergeGroupResult(ref completeGroupByResult,
                                                           partialResult.GroupByResult,
                                                           MaxMergeCount,
                                                           baseComparer);
                            }
                        }

                        #endregion

                        #region Update IndexIdIndexHeaderMapping

                        if (GetIndexHeaderType != GetIndexHeaderType.None &&
                            partialResult.IndexIdIndexHeaderMapping != null &&
                            partialResult.IndexIdIndexHeaderMapping.Count > 0)
                        {
                            foreach (KeyValuePair <byte[], IndexHeader> kvp in partialResult.IndexIdIndexHeaderMapping)
                            {
                                if (!completeIndexIdIndexHeaderMapping.ContainsKey(kvp.Key))
                                {
                                    completeIndexIdIndexHeaderMapping.Add(kvp.Key, kvp.Value);
                                }
                            }
                        }

                        #endregion

                        #region Update exceptionInfo

                        if (!String.IsNullOrEmpty(partialResult.ExceptionInfo))
                        {
                            exceptionStringBuilder.Append(partialResult.ExceptionInfo);
                            exceptionStringBuilder.Append(" ");
                        }

                        #endregion
                    }
                }

                #region Create FinalResult

                finalResult = new SpanQueryResult
                {
                    ResultItemList = completeResultItemList,
                    GroupByResult  = completeGroupByResult,
                    TotalCount     = totalCount,
                    AdditionalAvailableItemCount = additionalAvailableItemCount,
                    IndexCap = indexCap
                };

                //Assign sort fields for use in GroupBy remote queries
                if (baseComparer != null)
                {
                    finalResult.IsTagPrimarySort = baseComparer.IsTagPrimarySort;
                    finalResult.SortFieldName    = baseComparer.SortFieldName;
                    finalResult.SortOrderList    = baseComparer.SortOrderList;
                }

                if (GetIndexHeaderType != GetIndexHeaderType.None && completeIndexIdIndexHeaderMapping.Count > 0)
                {
                    finalResult.IndexIdIndexHeaderMapping = completeIndexIdIndexHeaderMapping;
                }

                if (exceptionStringBuilder.Length > 0)
                {
                    finalResult.ExceptionInfo = exceptionStringBuilder.ToString();
                }

                #endregion

                #endregion
            }

            #region Spanning and Update IndexIdIndexHeaderMapping if required

            if (ClientSideSubsetProcessingRequired && Span != 0 && finalResult != null)
            {
                #region Spanning

                if (GroupBy == null)
                {
                    List <ResultItem> filteredResultItemList = new List <ResultItem>();
                    if (finalResult.ResultItemList.Count >= Offset)
                    {
                        for (int i = Offset - 1; i < finalResult.ResultItemList.Count && filteredResultItemList.Count < Span; i++)
                        {
                            filteredResultItemList.Add(finalResult.ResultItemList[i]);
                        }
                    }
                    finalResult.ResultItemList = filteredResultItemList;
                }
                else if (finalResult.GroupByResult != null && finalResult.GroupByResult.Count > 0)
                {
                    GroupByResult filteredGroupByResult = new GroupByResult(baseComparer);
                    if (finalResult.GroupByResult.Count >= Offset)
                    {
                        for (int i = Offset - 1; i < finalResult.GroupByResult.Count && filteredGroupByResult.Count < Span; i++)
                        {
                            filteredGroupByResult.Add(finalResult.GroupByResult[i].CompositeKey, finalResult.GroupByResult[i]);
                        }
                    }
                    finalResult.GroupByResult = filteredGroupByResult;
                }

                #endregion

                #region Update IndexIdIndexHeaderMapping to only include metadata relevant after paging

                if (partialResults.Count != 1 && GetIndexHeaderType == GetIndexHeaderType.ResultItemsIndexIds && completeIndexIdIndexHeaderMapping.Count > 0)
                {
                    Dictionary <byte[] /*IndexId*/, IndexHeader /*IndexHeader*/> filteredIndexIdIndexHeaderMapping = new Dictionary <byte[], IndexHeader>(byteArrayEqualityComparer);
                    if (GroupBy == null)
                    {
                        foreach (ResultItem resultItem in finalResult.ResultItemList)
                        {
                            if (!filteredIndexIdIndexHeaderMapping.ContainsKey(resultItem.IndexId))
                            {
                                filteredIndexIdIndexHeaderMapping.Add(resultItem.IndexId, completeIndexIdIndexHeaderMapping[resultItem.IndexId]);
                            }
                        }
                    }
                    else if (finalResult.GroupByResult != null && finalResult.GroupByResult.Count > 0)
                    {
                        foreach (ResultItemBag resultItemBag in finalResult.GroupByResult)
                        {
                            for (int i = 0; i < resultItemBag.Count; i++)
                            {
                                ResultItem resultItem = resultItemBag[i];
                                if (!filteredIndexIdIndexHeaderMapping.ContainsKey(resultItem.IndexId))
                                {
                                    filteredIndexIdIndexHeaderMapping.Add(resultItem.IndexId, completeIndexIdIndexHeaderMapping[resultItem.IndexId]);
                                }
                            }
                        }
                    }
                    finalResult.IndexIdIndexHeaderMapping = filteredIndexIdIndexHeaderMapping.Count > 0 ? filteredIndexIdIndexHeaderMapping : null;
                }

                #endregion
            }

            #endregion
            return(finalResult);
        }
Ejemplo n.º 7
0
        public override PagedIndexQueryResult MergeResults(IList <PagedIndexQueryResult> partialResults)
        {
            PagedIndexQueryResult finalResult = default(PagedIndexQueryResult);

            if (partialResults == null || partialResults.Count == 0)
            {
                return(finalResult);
            }

            // We have partialResults to process
            ByteArrayEqualityComparer byteArrayEqualityComparer = new ByteArrayEqualityComparer();
            Dictionary <byte[] /*IndexId*/, IndexHeader /*IndexHeader*/> completeIndexIdIndexHeaderMapping =
                new Dictionary <byte[], IndexHeader>(byteArrayEqualityComparer);

            // resultVer required to determine if server is correctly performing paging logic
            int resultVer = 0;

            if (partialResults.Count == 1)
            {
                #region  Just one cluster was targeted, so no need to merge anything
                finalResult = partialResults[0];
                if (finalResult != null)
                {
                    resultVer = finalResult.CurrentVersion;
                }
                #endregion
            }
            else
            {
                #region  More than one clusters was targeted

                List <ResultItem> completeResultItemList = new List <ResultItem>();
                BaseComparer      baseComparer;
                int totalCount        = 0;
                int pageableItemCount = 0;

                foreach (PagedIndexQueryResult partialResult in partialResults)
                {
                    if (partialResult != null)
                    {
                        #region Update resultVer
                        if (resultVer == 0)
                        {
                            resultVer = partialResult.CurrentVersion;
                        }
                        #endregion

                        #region Compute TotalCount
                        totalCount += partialResult.TotalCount;
                        #endregion

                        #region Compute PageableItemCount
                        if (GetPageableItemCount)
                        {
                            pageableItemCount += partialResult.AdditionalAvailableItemCount;
                        }
                        #endregion

                        #region Merge Results
                        if (partialResult.ResultItemList != null && partialResult.ResultItemList.Count > 0)
                        {
                            baseComparer = new BaseComparer(partialResult.IsTagPrimarySort, partialResult.SortFieldName, partialResult.SortOrderList);
                            MergeAlgo.MergeItemLists(ref completeResultItemList, partialResult.ResultItemList, MaxMergeCount, baseComparer);
                        }
                        #endregion

                        #region Update IndexIdIndexHeaderMapping
                        if (GetIndexHeaderType != GetIndexHeaderType.None &&
                            partialResult.IndexIdIndexHeaderMapping != null &&
                            partialResult.IndexIdIndexHeaderMapping.Count > 0)
                        {
                            foreach (KeyValuePair <byte[], IndexHeader> kvp in partialResult.IndexIdIndexHeaderMapping)
                            {
                                if (!completeIndexIdIndexHeaderMapping.ContainsKey(kvp.Key))
                                {
                                    completeIndexIdIndexHeaderMapping.Add(kvp.Key, kvp.Value);
                                }
                            }
                        }
                        #endregion
                    }
                }

                #region Create FinalResult
                finalResult = new PagedIndexQueryResult
                {
                    ResultItemList = completeResultItemList,
                    TotalCount     = totalCount,
                    AdditionalAvailableItemCount = pageableItemCount,
                };
                if (GetIndexHeaderType != GetIndexHeaderType.None && completeIndexIdIndexHeaderMapping.Count > 0)
                {
                    finalResult.IndexIdIndexHeaderMapping = completeIndexIdIndexHeaderMapping;
                }
                #endregion

                #endregion
            }

            #region Determine whether client side paging is required
            bool performClientSidePaging;
            if (resultVer < PagedIndexQueryResult.CORRECT_SERVERSIDE_PAGING_LOGIC_VERSION)
            {
                // this.ClientSidePaging cannot be trusted
                performClientSidePaging = numClustersInGroup > 1 && PageNum != 0;
            }
            else
            {
                // this.ClientSidePaging can be trusted
                performClientSidePaging = ClientSidePaging && PageNum != 0;
            }
            #endregion

            #region Perform Paging and Update IndexIdIndexHeaderMapping if required
            if (performClientSidePaging && finalResult != null)
            {
                #region Paging Logic
                int start = (PageNum - 1) * PageSize;
                int end   = (PageNum * PageSize) < finalResult.ResultItemList.Count ? (PageNum * PageSize) : finalResult.ResultItemList.Count;
                List <ResultItem> filteredResultItemList = new List <ResultItem>();
                for (int i = start; i < end; i++)
                {
                    filteredResultItemList.Add(finalResult.ResultItemList[i]);
                }
                finalResult.ResultItemList = filteredResultItemList;
                #endregion

                #region Update IndexIdIndexHeaderMapping to only include metadata relevant after paging
                if (partialResults.Count != 1 && GetIndexHeaderType == GetIndexHeaderType.ResultItemsIndexIds && completeIndexIdIndexHeaderMapping.Count > 0)
                {
                    Dictionary <byte[] /*IndexId*/, IndexHeader /*IndexHeader*/> filteredIndexIdIndexHeaderMapping =
                        new Dictionary <byte[], IndexHeader>(byteArrayEqualityComparer);
                    foreach (ResultItem resultItem in finalResult.ResultItemList)
                    {
                        if (!filteredIndexIdIndexHeaderMapping.ContainsKey(resultItem.IndexId))
                        {
                            filteredIndexIdIndexHeaderMapping.Add(resultItem.IndexId, completeIndexIdIndexHeaderMapping[resultItem.IndexId]);
                        }
                    }
                    finalResult.IndexIdIndexHeaderMapping = filteredIndexIdIndexHeaderMapping.Count > 0 ? filteredIndexIdIndexHeaderMapping : null;
                }
                #endregion
            }
            #endregion

            return(finalResult);
        }