예제 #1
0
        /// <summary>
        /// Processes the specified intersection query.
        /// </summary>
        /// <param name="intersectionQuery">The intersection query.</param>
        /// <param name="messageContext">The message context.</param>
        /// <param name="storeContext">The store context.</param>
        /// <returns>IntersectionQueryResult</returns>
        internal static IntersectionQueryResult Process(IntersectionQuery intersectionQuery,
                                                        MessageContext messageContext,
                                                        IndexStoreContext storeContext)
        {
            //Fetch each index (assume all indexes are local) and perform intersection and return the results
            IntersectionQueryResult          intersectionQueryResult;
            List <IndexDataItem>             resultItemList            = null;
            Dictionary <byte[], IndexHeader> indexIdIndexHeaderMapping = new Dictionary <byte[], IndexHeader>(new ByteArrayEqualityComparer());
            List <string>    localIdentityTagNames = null;
            bool             isTagPrimarySort      = false;
            string           sortFieldName         = null;
            List <SortOrder> sortOrderList         = null;
            StringBuilder    exceptionInfo         = new StringBuilder();

            try
            {
                if (intersectionQuery.IndexIdList.Count > 0)
                {
                    IndexTypeMapping indexTypeMapping =
                        storeContext.StorageConfiguration.CacheIndexV3StorageConfig.IndexTypeMappingCollection[messageContext.TypeId];
                    ValidateQuery(indexTypeMapping, intersectionQuery);

                    #region Set sort vars

                    Index targetIndexInfo = indexTypeMapping.IndexCollection[intersectionQuery.TargetIndexName];
                    localIdentityTagNames = indexTypeMapping.IndexCollection[intersectionQuery.TargetIndexName].LocalIdentityTagList;
                    bool    sortFieldPartOfLocalId = IsSortFieldPartOfLocalId(localIdentityTagNames, targetIndexInfo.PrimarySortInfo);
                    TagSort itemIdTagSort          = new TagSort("ItemId", false, new SortOrder(DataType.Int32, SortBy.ASC));

                    if (!sortFieldPartOfLocalId)
                    {
                        //Set sort vars
                        isTagPrimarySort = itemIdTagSort.IsTag;
                        sortFieldName    = itemIdTagSort.TagName;
                        sortOrderList    = new List <SortOrder>(1)
                        {
                            itemIdTagSort.SortOrder
                        };
                    }
                    else
                    {
                        isTagPrimarySort = targetIndexInfo.PrimarySortInfo.IsTag;
                        sortFieldName    = targetIndexInfo.PrimarySortInfo.FieldName;
                        sortOrderList    = targetIndexInfo.PrimarySortInfo.SortOrderList;
                    }

                    #endregion

                    #region Fetch CacheIndexInternal and Intersect

                    CacheIndexInternal      targetIndex;
                    CacheIndexInternal      resultCacheIndexInternal = null;
                    IntersectionQueryParams indexIdParam;
                    byte[] indexId;
                    byte[] metadata;
                    MetadataPropertyCollection metadataPropertyCollection;

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

                        indexId      = intersectionQuery.IndexIdList[i];
                        indexIdParam = intersectionQuery.GetIntersectionQueryParamForIndexId(indexId);
                        // 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,
                                                                         indexId,
                                                                         storeContext,
                                                                         out metadata,
                                                                         out metadataPropertyCollection);
                        }

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

                        #endregion

                        if (targetIndex != null)
                        {
                            if (targetIndex.Count <= 0)
                            {
                                // No items in one of the indexes. Stop Interestion !!
                                resultCacheIndexInternal = null;
                                break;
                            }

                            PerformanceCounters.Instance.SetCounterValue(
                                PerformanceCounterEnum.NumOfItemsInIndexPerIntersectionQuery,
                                messageContext.TypeId,
                                targetIndex.OutDeserializationContext.TotalCount);

                            PerformanceCounters.Instance.SetCounterValue(
                                PerformanceCounterEnum.NumOfItemsReadPerIntersectionQuery,
                                messageContext.TypeId,
                                targetIndex.OutDeserializationContext.ReadItemCount);

                            if (!sortFieldPartOfLocalId)
                            {
                                //Need to sort indexes by item id
                                targetIndex.Sort(itemIdTagSort);
                            }

                            #region Intersection

                            if (resultCacheIndexInternal == null)
                            {
                                // No need to perform intersection for first index
                                resultCacheIndexInternal = targetIndex;
                            }
                            else
                            {
                                IntersectionAlgo.Intersect(isTagPrimarySort,
                                                           sortFieldName,
                                                           localIdentityTagNames,
                                                           sortOrderList,
                                                           resultCacheIndexInternal.InternalItemList,
                                                           targetIndex.InternalItemList,
                                                           intersectionQuery.MaxResultItems,
                                                           i == intersectionQuery.IndexIdList.Count - 1 ? intersectionQuery.IsSingleClusterQuery : false);

                                if (resultCacheIndexInternal == null || resultCacheIndexInternal.Count < 1)
                                {
                                    // Unable to fetch one of the indexes. Stop Interestion !!
                                    resultCacheIndexInternal  = null;
                                    indexIdIndexHeaderMapping = null;
                                    break;
                                }
                            }

                            #endregion
                        }
                        else
                        {
                            // Unable to fetch one of the indexes. Stop Interestion !!
                            resultCacheIndexInternal  = null;
                            indexIdIndexHeaderMapping = null;
                            break;
                        }

                        #region Get MetaData

                        if (intersectionQuery.GetIndexHeader)
                        {
                            if (!indexIdIndexHeaderMapping.ContainsKey(indexId))
                            {
                                indexIdIndexHeaderMapping.Add(indexId,
                                                              IndexServerUtils.GetIndexHeader(targetIndex, indexTypeMapping, messageContext.TypeId, IndexCacheUtils.GeneratePrimaryId(indexId), storeContext));
                            }
                        }

                        #endregion
                    }
                    if (resultCacheIndexInternal != null && resultCacheIndexInternal.Count > 0)
                    {
                        resultItemList = CacheIndexInternalAdapter.GetIndexDataItemList(resultCacheIndexInternal, 1, int.MaxValue);
                    }

                    #endregion

                    #region Get data

                    if (!intersectionQuery.ExcludeData && resultItemList != null && resultItemList.Count > 0)
                    {
                        DataTierUtil.GetData(resultItemList,
                                             storeContext,
                                             messageContext,
                                             indexTypeMapping.FullDataIdFieldList,
                                             intersectionQuery.FullDataIdInfo);
                    }

                    #endregion
                }

                intersectionQueryResult = new IntersectionQueryResult(resultItemList,
                                                                      indexIdIndexHeaderMapping,
                                                                      localIdentityTagNames,
                                                                      isTagPrimarySort,
                                                                      sortFieldName,
                                                                      sortOrderList,
                                                                      exceptionInfo.ToString());

                // update performance counter
                PerformanceCounters.Instance.SetCounterValue(
                    PerformanceCounterEnum.IndexLookupAvgPerIntersectionQuery,
                    messageContext.TypeId,
                    intersectionQuery.IndexIdList.Count);
            }
            catch (Exception ex)
            {
                exceptionInfo.Append(" | " + ex.Message);
                intersectionQueryResult = new IntersectionQueryResult(null, null, null, false, null, null, exceptionInfo.ToString());
                LoggingUtil.Log.ErrorFormat("TypeId {0} -- Error processing IntersectionQuery : {1}", messageContext.TypeId, ex);
            }
            return(intersectionQueryResult);
        }
        internal static MultiIndexContainsQueryResult Process(MultiIndexContainsQuery multiIndexContainsQuery,
                                                              MessageContext messageContext,
                                                              IndexStoreContext storeContext)
        {
            MultiIndexContainsQueryResult multiIndexContainsQueryResult;
            List <Pair <MultiIndexContainsQueryResultItem, IndexHeader> > multiIndexContainsQueryResultItemIndexHeaderList =
                new List <Pair <MultiIndexContainsQueryResultItem, IndexHeader> >(multiIndexContainsQuery.IndexIdList.Count);
            int           indexSize     = -1;
            int           indexCap      = 0;
            StringBuilder exceptionInfo = new StringBuilder();

            try
            {
                if (multiIndexContainsQuery.IndexIdList.Count > 0)
                {
                    IndexTypeMapping indexTypeMapping = storeContext.StorageConfiguration.CacheIndexV3StorageConfig.IndexTypeMappingCollection[messageContext.TypeId];

                    short relatedTypeId;
                    ValidateQuery(multiIndexContainsQuery, indexTypeMapping, storeContext, messageContext.TypeId, out relatedTypeId);

                    Index targetIndexInfo = indexTypeMapping.IndexCollection[multiIndexContainsQuery.TargetIndexName];
                    indexCap = targetIndexInfo.MaxIndexSize;
                    MultiIndexContainsQueryParams multiIndexContainsQueryParam;
                    int           searchIndex;
                    IndexDataItem indexDataItem;
                    MultiIndexContainsQueryResultItem multiIndexContainsQueryResultItem;
                    IndexHeader         indexHeader;
                    List <RelayMessage> dataStoreMessages = new List <RelayMessage>();
                    byte[] extendedId;
                    byte[] metadata;
                    MetadataPropertyCollection metadataPropertyCollection;

                    foreach (byte[] indexId in multiIndexContainsQuery.IndexIdList)
                    {
                        #region Get TargetIndex

                        // 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,
                                                                         IndexCacheUtils.GeneratePrimaryId(indexId),
                                                                         indexId,
                                                                         storeContext,
                                                                         out metadata,
                                                                         out metadataPropertyCollection);
                        }

                        multiIndexContainsQueryParam =
                            multiIndexContainsQuery.GetMultiIndexContainsQueryParamForIndexId(indexId);
                        CacheIndexInternal cacheIndexInternal = IndexServerUtils.GetCacheIndexInternal(storeContext,
                                                                                                       messageContext.TypeId,
                                                                                                       IndexCacheUtils.GeneratePrimaryId(indexId),
                                                                                                       indexId,
                                                                                                       targetIndexInfo.ExtendedIdSuffix,
                                                                                                       multiIndexContainsQuery.TargetIndexName,
                                                                                                       multiIndexContainsQueryParam.Count,
                                                                                                       multiIndexContainsQueryParam.Filter,
                                                                                                       true,
                                                                                                       multiIndexContainsQueryParam.IndexCondition,
                                                                                                       false,
                                                                                                       false,
                                                                                                       targetIndexInfo.PrimarySortInfo,
                                                                                                       targetIndexInfo.LocalIdentityTagList,
                                                                                                       targetIndexInfo.StringHashCodeDictionary,
                                                                                                       null,
                                                                                                       targetIndexInfo.IsMetadataPropertyCollection,
                                                                                                       metadataPropertyCollection,
                                                                                                       multiIndexContainsQuery.DomainSpecificProcessingType,
                                                                                                       storeContext.DomainSpecificConfig,
                                                                                                       null,
                                                                                                       null,
                                                                                                       false);

                        #endregion

                        if (cacheIndexInternal != null)
                        {
                            indexSize = cacheIndexInternal.OutDeserializationContext.TotalCount;
                            multiIndexContainsQueryResultItem = null;
                            indexHeader = null;

                            // update the performance counter
                            PerformanceCounters.Instance.SetCounterValue(PerformanceCounterEnum.NumOfItemsInIndexPerMultiIndexContainsQuery,
                                                                         messageContext.TypeId,
                                                                         cacheIndexInternal.OutDeserializationContext.TotalCount);

                            PerformanceCounters.Instance.SetCounterValue(PerformanceCounterEnum.NumOfItemsReadPerMultiIndexContainsQuery,
                                                                         messageContext.TypeId,
                                                                         cacheIndexInternal.OutDeserializationContext.ReadItemCount);

                            #region MultiIndexContainsQueryResultItem

                            foreach (IndexItem queryIndexItem in multiIndexContainsQuery.IndexItemList)
                            {
                                #region Search item in index

                                searchIndex = cacheIndexInternal.Search(queryIndexItem);

                                #endregion

                                if (searchIndex > -1)
                                {
                                    if (multiIndexContainsQueryResultItem == null)
                                    {
                                        multiIndexContainsQueryResultItem = new MultiIndexContainsQueryResultItem
                                        {
                                            IndexId     = indexId,
                                            IndexCap    = indexCap,
                                            IndexExists = true,
                                            IndexSize   = indexSize
                                        };
                                    }
                                    indexDataItem =
                                        new IndexDataItem(
                                            InternalItemAdapter.ConvertToIndexItem(cacheIndexInternal.GetItem(searchIndex),
                                                                                   cacheIndexInternal.InDeserializationContext));

                                    multiIndexContainsQueryResultItem.Add(indexDataItem);

                                    // Data
                                    if (!multiIndexContainsQuery.ExcludeData)
                                    {
                                        extendedId = DataTierUtil.GetFullDataId(indexId,
                                                                                indexDataItem,
                                                                                multiIndexContainsQuery.FullDataIdInfo != null &&
                                                                                multiIndexContainsQuery.FullDataIdInfo.RelatedTypeName != null ?
                                                                                multiIndexContainsQuery.FullDataIdInfo.FullDataIdFieldList :
                                                                                indexTypeMapping.FullDataIdFieldList);

                                        dataStoreMessages.Add(new RelayMessage(relatedTypeId, IndexCacheUtils.GeneratePrimaryId(extendedId), extendedId, MessageType.Get));
                                    }
                                }
                            }

                            #endregion

                            #region Add indexHeader to Result
                            if (multiIndexContainsQueryResultItem != null && multiIndexContainsQueryResultItem.Count > 0)
                            {
                                if (multiIndexContainsQuery.GetIndexHeader)
                                {
                                    indexHeader = IndexServerUtils.GetIndexHeader(cacheIndexInternal, indexTypeMapping,
                                                                                  messageContext.TypeId,
                                                                                  IndexCacheUtils.GeneratePrimaryId(indexId),
                                                                                  storeContext);
                                }


                                multiIndexContainsQueryResultItemIndexHeaderList.Add(new Pair <MultiIndexContainsQueryResultItem, IndexHeader>
                                {
                                    First  = multiIndexContainsQueryResultItem,
                                    Second = indexHeader
                                });
                            }

                            #endregion
                        }
                    }

                    #region Get data

                    if (!multiIndexContainsQuery.ExcludeData)
                    {
                        storeContext.ForwarderComponent.HandleMessages(dataStoreMessages);

                        int i = 0;
                        foreach (
                            Pair <MultiIndexContainsQueryResultItem, IndexHeader> pair in
                            multiIndexContainsQueryResultItemIndexHeaderList)
                        {
                            foreach (IndexDataItem resultItem in pair.First)
                            {
                                if (dataStoreMessages[i].Payload != null)
                                {
                                    resultItem.Data = dataStoreMessages[i].Payload.ByteArray;
                                }
                                i++;
                            }
                        }
                    }

                    #endregion
                }
                multiIndexContainsQueryResult = new MultiIndexContainsQueryResult(multiIndexContainsQueryResultItemIndexHeaderList, exceptionInfo.ToString());

                // update performance counter
                PerformanceCounters.Instance.SetCounterValue(PerformanceCounterEnum.IndexLookupAvgPerMultiIndexContainsQuery,
                                                             messageContext.TypeId,
                                                             multiIndexContainsQuery.IndexIdList.Count);
            }
            catch (Exception ex)
            {
                multiIndexContainsQueryResult = new MultiIndexContainsQueryResult(null, ex.Message);
                LoggingUtil.Log.ErrorFormat("TypeId {0} -- Error processing MultiIndexContainsQuery : {1}", messageContext.TypeId, ex);
            }
            return(multiIndexContainsQueryResult);
        }