/// <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); }