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