private static void ProcessAddList(List <CacheIndexInternal> internalIndexList, List <IndexItem> cappedDeleteItemList, CacheIndex clientIndex, IndexStoreContext storeContext, IndexTypeMapping indexTypeMapping) { #region Add new items to each internalIndex Index indexInfo; InternalItemComparer comparer; int searchIndex; PerformanceCounters.Instance.SetCounterValue( PerformanceCounterEnum.AddList, indexTypeMapping.TypeId, clientIndex.AddList.Count); foreach (CacheIndexInternal cacheIndexInternal in internalIndexList) { indexInfo = indexTypeMapping.IndexCollection[cacheIndexInternal.InDeserializationContext.IndexName]; comparer = new InternalItemComparer(indexInfo.PrimarySortInfo.IsTag, indexInfo.PrimarySortInfo.FieldName, indexInfo.PrimarySortInfo.SortOrderList); if (clientIndex.AddList.Count > 0) { foreach (IndexDataItem addItem in clientIndex.AddList) { searchIndex = cacheIndexInternal.Search(addItem); if (searchIndex > -1) { UpdateExistingIndexItem(clientIndex, cacheIndexInternal, indexInfo, addItem, searchIndex, storeContext, comparer); } else { AddNewItem(clientIndex, cacheIndexInternal, indexInfo, addItem, storeContext, comparer); #region IndexSize Capping if (indexInfo.MaxIndexSize > 0 && cacheIndexInternal.Count > indexInfo.MaxIndexSize) { int deleteIndex = indexInfo.TrimFromTail ? cacheIndexInternal.Count - 1 : 0; //Add item to a list to delete it from the Data Store cappedDeleteItemList.Add(InternalItemAdapter.ConvertToIndexItem(cacheIndexInternal.GetItem(deleteIndex), cacheIndexInternal.InDeserializationContext)); //Delete from Index Store cacheIndexInternal.DeleteItem(deleteIndex, false); } #endregion } } } //Update metadata if (clientIndex.UpdateMetadata && indexTypeMapping.IndexCollection[cacheIndexInternal.InDeserializationContext.IndexName].MetadataPresent) { cacheIndexInternal.Metadata = clientIndex.Metadata; } } #endregion }
/// <summary> /// Sorts the InternalItemList based on the specified tag sort. /// </summary> /// <param name="tagSort">The tag sort.</param> internal void Sort(TagSort tagSort) { InternalItemComparer internalItemComparer = new InternalItemComparer(tagSort.IsTag, tagSort.TagName, new List <SortOrder>(1) { tagSort.SortOrder }); itemList.Sort(internalItemComparer); }
/// <summary> /// Binary searches an item. /// </summary> /// <param name="searchItem">The search item.</param> /// <param name="isTagPrimarySort">if set to <c>true</c> [is tag primary sort].</param> /// <param name="sortFieldName">Name of the sort field.</param> /// <param name="sortOrderList">The sort order list.</param> /// <param name="localIdentityTagNames">The local identity tag names.</param> /// <returns></returns> public override int BinarySearchItem(InternalItem searchItem, bool isTagPrimarySort, string sortFieldName, List <SortOrder> sortOrderList, List <string> localIdentityTagNames) { try { int searchIndex = -1; if (Count > 0) { InternalItemComparer comparer = new InternalItemComparer(isTagPrimarySort, sortFieldName, sortOrderList); searchIndex = itemList.BinarySearch(searchItem, comparer); //Look for localIdentity at searchIndex if (searchIndex > -1 && localIdentityTagNames.Count > 0) { if (EqualsLocalId(this[searchIndex], searchItem, localIdentityTagNames)) { return(searchIndex); } //Search to left of the searchIndex int newIndex = searchIndex - 1; while (newIndex > -1 && comparer.Compare(this[newIndex], searchItem) == 0) { if (EqualsLocalId(this[newIndex], searchItem, localIdentityTagNames)) { return(newIndex); } newIndex--; } //Search to right of index newIndex = searchIndex + 1; while (newIndex < Count && comparer.Compare(this[newIndex], searchItem) == 0) { if (EqualsLocalId(this[newIndex], searchItem, localIdentityTagNames)) { return(newIndex); } newIndex++; } return(-1); } } return(searchIndex); } catch (Exception ex) { throw new Exception("Error in Binary Search", ex); } }
/// <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> /// Gets the insert position. /// </summary> /// <param name="searchItem">The search item.</param> /// <param name="sortBy">The sort by.</param> /// <param name="comparer">The comparer.</param> /// <returns>InsertPosition</returns> internal int GetInsertPosition(IndexItem searchItem, SortBy sortBy, InternalItemComparer comparer) { return(InternalItemList.GetInsertPosition(InternalItemAdapter.ConvertToInternalItem(searchItem), comparer, sortBy)); }
/// <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); }
private static void ProcessAddList(List<CacheIndexInternal> internalIndexList, List<IndexItem> cappedDeleteItemList, CacheIndex clientIndex, IndexStoreContext storeContext, IndexTypeMapping indexTypeMapping) { #region Add new items to each internalIndex Index indexInfo; InternalItemComparer comparer; int searchIndex; PerformanceCounters.Instance.SetCounterValue( PerformanceCounterEnum.AddList, indexTypeMapping.TypeId, clientIndex.AddList.Count); foreach (CacheIndexInternal cacheIndexInternal in internalIndexList) { indexInfo = indexTypeMapping.IndexCollection[cacheIndexInternal.InDeserializationContext.IndexName]; comparer = new InternalItemComparer(indexInfo.PrimarySortInfo.IsTag, indexInfo.PrimarySortInfo.FieldName, indexInfo.PrimarySortInfo.SortOrderList); if (clientIndex.AddList.Count > 0) { foreach (IndexDataItem addItem in clientIndex.AddList) { searchIndex = cacheIndexInternal.Search(addItem); if (searchIndex > -1) { UpdateExistingIndexItem(clientIndex, cacheIndexInternal, indexInfo, addItem, searchIndex, storeContext, comparer); } else { AddNewItem(clientIndex, cacheIndexInternal, indexInfo, addItem, storeContext, comparer); #region IndexSize Capping if (indexInfo.MaxIndexSize > 0 && cacheIndexInternal.Count > indexInfo.MaxIndexSize) { int deleteIndex = indexInfo.TrimFromTail ? cacheIndexInternal.Count - 1 : 0; //Add item to a list to delete it from the Data Store cappedDeleteItemList.Add(InternalItemAdapter.ConvertToIndexItem(cacheIndexInternal.GetItem(deleteIndex), cacheIndexInternal.InDeserializationContext)); //Delete from Index Store cacheIndexInternal.DeleteItem(deleteIndex, false); } #endregion } } } //Update metadata if (clientIndex.UpdateMetadata && indexTypeMapping.IndexCollection[cacheIndexInternal.InDeserializationContext.IndexName].MetadataPresent) { cacheIndexInternal.Metadata = clientIndex.Metadata; } } #endregion }
/// <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> /// Gets the insert position. /// </summary> /// <param name="searchItem">The search item.</param> /// <param name="sortBy">The sort by.</param> /// <param name="comparer">The comparer.</param> /// <returns>InsertPosition</returns> internal int GetInsertPosition(IndexItem searchItem, SortBy sortBy, InternalItemComparer comparer) { return InternalItemList.GetInsertPosition(InternalItemAdapter.ConvertToInternalItem(searchItem), comparer, sortBy); }