Exemple #1
0
        private static List <IndexDataItem> DeserializeIndexDataItemList(IPrimitiveReader reader)
        {
            int listCount = reader.ReadInt32();
            List <IndexDataItem> indexDataItemList = new List <IndexDataItem>(listCount);
            IndexDataItem        indexDataItem;

            for (int i = 0; i < listCount; i++)
            {
                indexDataItem = new IndexDataItem();
                indexDataItem.Deserialize(reader);
                indexDataItemList.Add(indexDataItem);
            }
            return(indexDataItemList);
        }
        /// <summary>
        /// Determines whether repositioning of index item is required or not.
        /// </summary>
        /// <param name="indexInfo">The index info.</param>
        /// <param name="addItem">The add item.</param>
        /// <param name="internalItem">The internal item.</param>
        /// <returns>
        /// 	<c>true</c> if repositioning of index item is required; otherwise, <c>false</c>.
        /// </returns>
        private static bool IsRepositioningOfIndexItemRequired(Index indexInfo, IndexDataItem addItem, InternalItem internalItem)
        {
            byte[] sortTagValueInAddItem;
            if (indexInfo.PrimarySortInfo.IsTag && addItem.Tags.TryGetValue(indexInfo.PrimarySortInfo.FieldName, out sortTagValueInAddItem))
            {
                // Index is sorted by tag and tag might have been updated
                byte[] sortTagValueInIndex;
                internalItem.TryGetTagValue(indexInfo.PrimarySortInfo.FieldName, out sortTagValueInIndex);

                if (!ByteArrayComparerUtil.CompareByteArrays(sortTagValueInAddItem, sortTagValueInIndex))
                {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// Repositions the index item.
        /// </summary>
        /// <param name="cacheIndexInternal">The cache index internal.</param>
        /// <param name="indexInfo">The index info.</param>
        /// <param name="addItem">The add item.</param>
        /// <param name="searchIndex">Index of the search.</param>
        /// <param name="internalItem">The internal item.</param>
        /// <param name="comparer">The comparer.</param>
        private static void RepositionIndexItem(CacheIndexInternal cacheIndexInternal, Index indexInfo, IndexDataItem addItem, int searchIndex, InternalItem internalItem, InternalItemComparer comparer)
        {
            // Remove the Item from current position
            cacheIndexInternal.DeleteItem(searchIndex, false);

            // Determine where to insert the Item
            int newSearchIndex = cacheIndexInternal.GetInsertPosition(addItem, indexInfo.PrimarySortInfo.SortOrderList[0].SortBy, comparer);

            // insert the item at new position
            cacheIndexInternal.InsertItem(internalItem, newSearchIndex, false);
        }
        /// <summary>
        /// Updates the existing index item.
        /// </summary>
        /// <param name="clientIndex">Index from the client.</param>
        /// <param name="cacheIndexInternal">The cache index internal.</param>
        /// <param name="indexInfo">The index info.</param>
        /// <param name="addItem">The add item.</param>
        /// <param name="searchIndex">Index to search.</param>
        /// <param name="storeContext">The store context.</param>
        /// <param name="comparer">The comparer.</param>
        private static void UpdateExistingIndexItem(CacheIndex clientIndex, CacheIndexInternal cacheIndexInternal, Index indexInfo, IndexDataItem addItem, int searchIndex, IndexStoreContext storeContext, InternalItemComparer comparer)
        {
            InternalItem internalItem = cacheIndexInternal.InternalItemList[searchIndex];
            if (clientIndex.TargetIndexName != null) //Save to single index
            {
                if (addItem.Tags != null && addItem.Tags.Count > 0)
                {
                    bool reposition = IsRepositioningOfIndexItemRequired(indexInfo, addItem, internalItem);

                    // Update all tags on the internal item
                    foreach (KeyValuePair<string, byte[]> kvp in addItem.Tags)
                    {
                        storeContext.TagHashCollection.AddTag(cacheIndexInternal.InDeserializationContext.TypeId, kvp.Key);
                        internalItem.UpdateTag(TagHashCollection.GetTagHashCode(kvp.Key), kvp.Value);
                    }

                    // Reposition index item if required
                    if (reposition)
                    {
                        RepositionIndexItem(cacheIndexInternal, indexInfo, addItem, searchIndex, internalItem, comparer);
                    }
                }
            }
            else //Save to multiple indexes
            {
                if (addItem.Tags != null && addItem.Tags.Count > 0)
                {
                    List<string> tagNameList;
                    byte[] tagValue;
                    clientIndex.IndexTagMapping.TryGetValue(cacheIndexInternal.InDeserializationContext.IndexName, out tagNameList);

                    bool reposition = IsRepositioningOfIndexItemRequired(indexInfo, addItem, internalItem);

                    // Update all tags on the internal item
                    foreach (string tagName in tagNameList)
                    {
                        //Add to tagHashCollection
                        storeContext.TagHashCollection.AddTag(cacheIndexInternal.InDeserializationContext.TypeId, tagName);
                        addItem.TryGetTagValue(tagName, out tagValue);
                        internalItem.UpdateTag(TagHashCollection.GetTagHashCode(tagName), tagValue);
                    }

                    // Reposition index item if required
                    if (reposition)
                    {
                        RepositionIndexItem(cacheIndexInternal, indexInfo, addItem, searchIndex, internalItem, comparer);
                    }
                }
            }
        }
        /// <summary>
        /// Adds the new item.
        /// </summary>
        /// <param name="clientIndex">Index from the client.</param>
        /// <param name="cacheIndexInternal">The cache index internal.</param>
        /// <param name="indexInfo">The index info.</param>
        /// <param name="addItem">The add item.</param>
        /// <param name="storeContext">The store context.</param>
        /// <param name="comparer">The comparer.</param>
        private static void AddNewItem(CacheIndex clientIndex,
            CacheIndexInternal cacheIndexInternal,
            Index indexInfo, IndexDataItem addItem,
            IndexStoreContext storeContext,
            InternalItemComparer comparer)
        {
            int searchIndex;
            List<KeyValuePair<int, byte[]>> kvpList;
            searchIndex = cacheIndexInternal.GetInsertPosition(addItem, indexInfo.PrimarySortInfo.SortOrderList[0].SortBy, comparer);

            //Add item to CacheIndexInternal
            kvpList = null;
            if (addItem.Tags != null && addItem.Tags.Count > 0)
            {
                kvpList = new List<KeyValuePair<int, byte[]>>();

                if (clientIndex.TargetIndexName != null) //Save to single index
                {
                    foreach (KeyValuePair<string, byte[]> kvp in addItem.Tags)
                    {
                        //Add to tagHashCollection
                        storeContext.TagHashCollection.AddTag(cacheIndexInternal.InDeserializationContext.TypeId, kvp.Key);
                        kvpList.Add(new KeyValuePair<int, byte[]>(TagHashCollection.GetTagHashCode(kvp.Key), kvp.Value));
                    }
                }
                else //Save to multiple indexes
                {
                    List<string> tagNameList;
                    clientIndex.IndexTagMapping.TryGetValue(cacheIndexInternal.InDeserializationContext.IndexName, out tagNameList);
                    foreach (string tagName in tagNameList)
                    {
                        //Add to tagHashCollection
                        storeContext.TagHashCollection.AddTag(cacheIndexInternal.InDeserializationContext.TypeId, tagName);
                        kvpList.Add(new KeyValuePair<int, byte[]>(TagHashCollection.GetTagHashCode(tagName), addItem.Tags[tagName]));
                    }
                }
            }
            cacheIndexInternal.InsertItem(new InternalItem { ItemId = addItem.ItemId, TagList = kvpList }, searchIndex, true);
        }
        /// <summary>
        /// Processes the specified contains index query.
        /// </summary>
        /// <param name="containsIndexQuery">The contains index query.</param>
        /// <param name="messageContext">The message context.</param>
        /// <param name="storeContext">The store context.</param>
        /// <returns>ContainsIndexQueryResult</returns>
        internal static ContainsIndexQueryResult Process(ContainsIndexQuery containsIndexQuery, MessageContext messageContext, IndexStoreContext storeContext)
        {
            ContainsIndexQueryResult containsIndexQueryResult;
            MultiItemResult multiItemResult = null;
            byte[] metadata = null;
            bool indexExists = false;
            int indexSize = -1;
            int virtualCount = -1;

            try
            {
                IndexTypeMapping indexTypeMapping =
                    storeContext.StorageConfiguration.CacheIndexV3StorageConfig.IndexTypeMappingCollection[messageContext.TypeId];

                #region Check TargetIndexName
                
                if (!indexTypeMapping.IndexCollection.Contains(containsIndexQuery.TargetIndexName))
                {
                    throw new Exception("Invalid TargetIndexName - " + containsIndexQuery.TargetIndexName);
                }
                
                #endregion

                Index targetIndexInfo = indexTypeMapping.IndexCollection[containsIndexQuery.TargetIndexName];
                List<CacheIndexInternal> internalCacheIndexList = new List<CacheIndexInternal>();

                #region Get TargetIndex
                
                CacheIndexInternal cacheIndexInternal = IndexServerUtils.GetCacheIndexInternal(storeContext,
                    messageContext.TypeId,
                    messageContext.PrimaryId,
                    containsIndexQuery.IndexId,
                    targetIndexInfo.ExtendedIdSuffix,
                    containsIndexQuery.TargetIndexName,
                    0,
                    null,
                    true,
                    null,
                    false,
                    false,
                    targetIndexInfo.PrimarySortInfo,
                    targetIndexInfo.LocalIdentityTagList,
                    targetIndexInfo.StringHashCodeDictionary,
                    null);
                
                #endregion

                if (cacheIndexInternal != null)
                {
                    internalCacheIndexList.Add(cacheIndexInternal);
                    indexExists = true;
                    indexSize = cacheIndexInternal.OutDeserializationContext.TotalCount;
                    virtualCount = cacheIndexInternal.VirtualCount;

                    // update the performance counter
                    PerformanceCounters.Instance.SetCounterValue(
                        PerformanceCounterEnum.NumOfItemsInIndexPerContainsIndexQuery,
                        messageContext.TypeId,
                        indexSize);

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

                    int searchIndex;
                    IndexDataItem indexDataItem;

                    foreach (IndexItem queryIndexItem in containsIndexQuery.IndexItemList)
                    {
                        #region Search item in index
                        
                        searchIndex = internalCacheIndexList[0].Search(queryIndexItem);
                        
                        #endregion

                        if (searchIndex > -1)
                        {
                            if (multiItemResult == null)
                            {
                                multiItemResult = new MultiItemResult(containsIndexQuery.IndexId);
                            }
                            indexDataItem = new IndexDataItem(InternalItemAdapter.ConvertToIndexItem(internalCacheIndexList[0].GetItem(searchIndex),
                                internalCacheIndexList[0].InDeserializationContext));

                            #region Get extra tags
                            
                            if (containsIndexQuery.TagsFromIndexes != null && containsIndexQuery.TagsFromIndexes.Count != 0)
                            {
                                foreach (string indexName in containsIndexQuery.TagsFromIndexes)
                                {
                                    Index indexInfo = indexTypeMapping.IndexCollection[indexName];

                                    CacheIndexInternal indexInternal =
                                        IndexServerUtils.GetCacheIndexInternal(storeContext,
                                                                               messageContext.TypeId,
                                                                               messageContext.PrimaryId,
                                                                               containsIndexQuery.IndexId,
                                                                               indexInfo.ExtendedIdSuffix,
                                                                               indexName,
                                                                               0,
                                                                               null,
                                                                               true,
                                                                               null,
                                                                               false,
                                                                               false,
                                                                               indexInfo.PrimarySortInfo,
                                                                               indexInfo.LocalIdentityTagList,
                                                                               indexInfo.StringHashCodeDictionary,
                                                                               null);

                                    if (indexInternal != null)
                                    {
                                        // update the performance counter
                                        PerformanceCounters.Instance.SetCounterValue(
                                            PerformanceCounterEnum.NumOfItemsInIndexPerContainsIndexQuery,
                                            messageContext.TypeId,
                                            indexInternal.OutDeserializationContext.TotalCount);

                                        PerformanceCounters.Instance.SetCounterValue(
                                            PerformanceCounterEnum.NumOfItemsReadPerContainsIndexQuery,
                                            messageContext.TypeId,
                                            indexInternal.OutDeserializationContext.ReadItemCount);

                                        internalCacheIndexList.Add(indexInternal);

                                        IndexServerUtils.GetTags(indexInternal, queryIndexItem, indexDataItem);
                                    }
                                }
                            }
                            
                            #endregion

                            multiItemResult.Add(indexDataItem);
                        }
                    }

                    #region Get data
                    
                    if (!containsIndexQuery.ExcludeData && multiItemResult != null)
                    {
                        byte[] extendedId;
                        List<RelayMessage> dataStoreMessages = new List<RelayMessage>(multiItemResult.Count);
                        short relatedTypeId;
                        if (containsIndexQuery.FullDataIdInfo != null && containsIndexQuery.FullDataIdInfo.RelatedTypeName != null)
                        {
                            if (!storeContext.TryGetTypeId(containsIndexQuery.FullDataIdInfo.RelatedTypeName, out relatedTypeId))
                            {
                                LoggingUtil.Log.ErrorFormat("Invalid RelatedCacheTypeName - {0}", containsIndexQuery.FullDataIdInfo.RelatedTypeName);
                                throw new Exception("Invalid RelatedTypeId for TypeId - " + containsIndexQuery.FullDataIdInfo.RelatedTypeName);
                            }
                        }
                        else if (!storeContext.TryGetRelatedIndexTypeId(messageContext.TypeId, out relatedTypeId))
                        {
                            LoggingUtil.Log.ErrorFormat("Invalid RelatedTypeId for TypeId - {0}", messageContext.TypeId);
                            throw new Exception("Invalid RelatedTypeId for TypeId - " + messageContext.TypeId);
                        }

                        foreach (IndexDataItem resultItem in multiItemResult)
                        {
                            extendedId = DataTierUtil.GetFullDataId(containsIndexQuery.IndexId,
                                resultItem,
                                    containsIndexQuery.FullDataIdInfo != null && containsIndexQuery.FullDataIdInfo.RelatedTypeName != null ?
                                    containsIndexQuery.FullDataIdInfo.FullDataIdFieldList :
                                    indexTypeMapping.FullDataIdFieldList);
                            dataStoreMessages.Add(new RelayMessage(relatedTypeId, IndexCacheUtils.GeneratePrimaryId(extendedId), extendedId, MessageType.Get));
                        }

                        storeContext.ForwarderComponent.HandleMessages(dataStoreMessages);

                        int i = 0;
                        foreach (IndexDataItem resultItem in multiItemResult)
                        {
                            if (dataStoreMessages[i].Payload != null)
                            {
                                resultItem.Data = dataStoreMessages[i].Payload.ByteArray;
                            }
                            i++;
                        }
                    }
                    
                    #endregion

                    #region Get metadata
                    
                    if (containsIndexQuery.GetMetadata)
                    {
                        metadata = IndexServerUtils.GetQueryMetadata(internalCacheIndexList,
                            indexTypeMapping,
                            messageContext.TypeId,
                            messageContext.PrimaryId,
                            containsIndexQuery.IndexId,
                            storeContext);
                    }
                    
                    #endregion
                }
                containsIndexQueryResult = new ContainsIndexQueryResult(multiItemResult, metadata, indexSize, indexExists, virtualCount, null);
            }
            catch (Exception ex)
            {
                containsIndexQueryResult = new ContainsIndexQueryResult(null, null, -1, false, -1, ex.Message);
                LoggingUtil.Log.ErrorFormat("TypeId {0} -- Error processing ContainsIndexQuery : {1}", messageContext.TypeId, ex);
            }
            return containsIndexQueryResult;
        }
		public void Deserialize(IPrimitiveReader reader, int version)
		{
			//IndexId
			ushort len = reader.ReadUInt16();
			if (len > 0)
			{
				indexId = reader.ReadBytes(len);
			}

			//TargetIndexName
			targetIndexName = reader.ReadString();

			//IndexTagMapping
			ushort count = reader.ReadUInt16();
			indexTagMapping = new Dictionary<string, List<string>>(count);
			if (count > 0)
			{
				string indexName;
				ushort tagNameListCount;
				List<string> tagNameList;

				for (ushort i = 0; i < count; i++)
				{
					indexName = reader.ReadString();
					tagNameListCount = reader.ReadUInt16();
					tagNameList = new List<string>();
					for (ushort j = 0; j < tagNameListCount; j++)
					{
						tagNameList.Add(reader.ReadString());
					}
					indexTagMapping.Add(indexName, tagNameList);
				}
			}

			//AddList
			int listCount = reader.ReadInt32();
			addList = new List<IndexDataItem>(listCount);
			IndexDataItem indexDataItem;
			for (int i = 0; i < listCount; i++)
			{
				indexDataItem = new IndexDataItem();
				indexDataItem.Deserialize(reader);
				addList.Add(indexDataItem);
			}

			//DeleteList
			listCount = reader.ReadInt32();
			deleteList = new List<IndexItem>(listCount);
			IndexItem indexItem;
			for (int i = 0; i < listCount; i++)
			{
				indexItem = new IndexItem();
				indexItem.Deserialize(reader);
				deleteList.Add(indexItem);
			}

			//Metadata
			len = reader.ReadUInt16();
			if (len > 0)
			{
				metadata = reader.ReadBytes(len);
			}

			//UpdateMetadata
			updateMetadata = reader.ReadBoolean();

			//ReplaceFullIndex
			replaceFullIndex = reader.ReadBoolean();

            if (version >= 2)
            {
                //PreserveData
                preserveData = reader.ReadBoolean();
            }

            if(version >= 3)
            {
                //IndexVirtualCountMapping
                count = reader.ReadUInt16();
                if (count > 0)
                {
                    indexVirtualCountMapping = new Dictionary<string, int>(count);
                    string indexName;
                    int virtualCount;

                    for (ushort i = 0; i < count; i++)
                    {
                        indexName = reader.ReadString();
                        virtualCount = reader.ReadInt32();
                        indexVirtualCountMapping.Add(indexName, virtualCount);
                    }
                }
            }

            if (version >= 4)
            {
                //PrimaryId
                primaryId = reader.ReadInt32();
            }
		}
Exemple #8
0
        public void Deserialize(IPrimitiveReader reader, int version)
        {
            //IndexId
            ushort len = reader.ReadUInt16();

            if (len > 0)
            {
                indexId = reader.ReadBytes(len);
            }

            //TargetIndexName
            targetIndexName = reader.ReadString();

            //IndexTagMapping
            ushort count = reader.ReadUInt16();

            indexTagMapping = new Dictionary <string, List <string> >(count);
            if (count > 0)
            {
                string        indexName;
                ushort        tagNameListCount;
                List <string> tagNameList;

                for (ushort i = 0; i < count; i++)
                {
                    indexName        = reader.ReadString();
                    tagNameListCount = reader.ReadUInt16();
                    tagNameList      = new List <string>();
                    for (ushort j = 0; j < tagNameListCount; j++)
                    {
                        tagNameList.Add(reader.ReadString());
                    }
                    indexTagMapping.Add(indexName, tagNameList);
                }
            }

            //AddList
            int listCount = reader.ReadInt32();

            addList = new List <IndexDataItem>(listCount);
            IndexDataItem indexDataItem;

            for (int i = 0; i < listCount; i++)
            {
                indexDataItem = new IndexDataItem();
                indexDataItem.Deserialize(reader);
                addList.Add(indexDataItem);
            }

            //DeleteList
            listCount  = reader.ReadInt32();
            deleteList = new List <IndexItem>(listCount);
            IndexItem indexItem;

            for (int i = 0; i < listCount; i++)
            {
                indexItem = new IndexItem();
                indexItem.Deserialize(reader);
                deleteList.Add(indexItem);
            }

            //Metadata
            len = reader.ReadUInt16();
            if (len > 0)
            {
                metadata = reader.ReadBytes(len);
            }

            //UpdateMetadata
            updateMetadata = reader.ReadBoolean();

            //ReplaceFullIndex
            replaceFullIndex = reader.ReadBoolean();

            if (version >= 2)
            {
                //PreserveData
                preserveData = reader.ReadBoolean();
            }

            if (version >= 3)
            {
                //IndexVirtualCountMapping
                count = reader.ReadUInt16();
                if (count > 0)
                {
                    indexVirtualCountMapping = new Dictionary <string, int>(count);
                    string indexName;
                    int    virtualCount;

                    for (ushort i = 0; i < count; i++)
                    {
                        indexName    = reader.ReadString();
                        virtualCount = reader.ReadInt32();
                        indexVirtualCountMapping.Add(indexName, virtualCount);
                    }
                }
            }

            if (version >= 4)
            {
                //PrimaryId
                primaryId = reader.ReadInt32();
            }
        }