/// <summary> /// Gets the printable CacheIndexInternalList. /// </summary> /// <param name="internalIndexList">The internal index list.</param> /// <returns></returns> internal static string GetPrintableCacheIndexInternalList(List <CacheIndexInternal> internalIndexList, TagHashCollection tagHashCollection, short typeId) { StringBuilder logStr = new StringBuilder(); logStr.Append("CacheIndexInternalList Info").Append(Environment.NewLine); int itemCount; foreach (CacheIndexInternal cii in internalIndexList) { if (cii.InDeserializationContext != null && cii.InDeserializationContext.IndexId != null) { //CacheIndexInternal Name logStr.Append("IndexName : ").Append(cii.InDeserializationContext.IndexName); logStr.Append(", IndexId : ").Append(IndexCacheUtils.GetReadableByteArray(cii.InDeserializationContext.IndexId)).Append(Environment.NewLine); } if (cii.InternalItemList != null) { logStr.Append("CacheIndexInternal.InternalItemList.Count : ").Append(cii.InternalItemList.Count.ToString()).Append(Environment.NewLine); itemCount = 0; foreach (InternalItem internalItem in cii.InternalItemList) { LogItem(logStr, internalItem, itemCount++, tagHashCollection, typeId); } } else { logStr.Append("CacheIndexInternal.ItemIdList = null").Append(Environment.NewLine); } } return(logStr.ToString()); }
/// <summary> /// Gets the data into resultItemList items. /// </summary> /// <param name="resultItemList">The result item list.</param> /// <param name="storeContext">The store context.</param> /// <param name="messageContext">The message context.</param> /// <param name="fullDataIdFieldList">The full data id field list.</param> /// <param name="fullDataIdInfo">The full data id info.</param> internal static void GetData(List <ResultItem> resultItemList, IndexStoreContext storeContext, MessageContext messageContext, FullDataIdFieldList fullDataIdFieldList, FullDataIdInfo fullDataIdInfo) { byte[] extendedId; List <RelayMessage> dataStoreMessages = new List <RelayMessage>(); short relatedTypeId; if (fullDataIdInfo != null && fullDataIdInfo.RelatedTypeName != null) { if (!storeContext.TryGetTypeId(fullDataIdInfo.RelatedTypeName, out relatedTypeId)) { LoggingUtil.Log.ErrorFormat("Invalid RelatedCacheTypeName - {0}", fullDataIdInfo.RelatedTypeName); throw new Exception("Invalid RelatedTypeId for TypeId - " + 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); } if (resultItemList != null && resultItemList.Count > 0) { foreach (ResultItem resultItem in resultItemList) { extendedId = GetFullDataId(resultItem.IndexId, resultItem, fullDataIdInfo != null && fullDataIdInfo.RelatedTypeName != null ? fullDataIdInfo.FullDataIdFieldList : fullDataIdFieldList); dataStoreMessages.Add(new RelayMessage(relatedTypeId, IndexCacheUtils.GeneratePrimaryId(extendedId), extendedId, MessageType.Get)); } storeContext.ForwarderComponent.HandleMessages(dataStoreMessages); int i = 0; foreach (ResultItem resultItem in resultItemList) { if (dataStoreMessages[i].Payload != null) { resultItem.Data = dataStoreMessages[i].Payload.ByteArray; } else { LoggingUtil.Log.DebugFormat("Fetched Null Data for TypeId: {0}, IndexId: {1}, ItemId: {2}, FullDataId: {3}, PrimaryId: {4}", relatedTypeId, IndexCacheUtils.GetReadableByteArray(resultItem.IndexId), IndexCacheUtils.GetReadableByteArray(resultItem.ItemId), IndexCacheUtils.GetReadableByteArray(dataStoreMessages[i].ExtendedId), IndexCacheUtils.GeneratePrimaryId(dataStoreMessages[i].ExtendedId) ); } i++; } } }
/// <summary> /// Gets printable CacheIndex. /// </summary> /// <param name="clientIndex">client index.</param> /// <param name="tagHashCollection">tag Hash Collection.</param> /// <param name="typeId">type id.</param> /// <returns></returns> internal static string GetPrintableCacheIndex(CacheIndex clientIndex, TagHashCollection tagHashCollection, short typeId) { StringBuilder logStr = new StringBuilder(); logStr.Append(Environment.NewLine).Append("Client Index Info").Append(Environment.NewLine); int itemCount; logStr.Append("IndexId : ").Append(IndexCacheUtils.GetReadableByteArray(clientIndex.IndexId)).Append(Environment.NewLine); logStr.Append("Metadata : ").Append(clientIndex.Metadata == null ? "Null" : IndexCacheUtils.GetReadableByteArray(clientIndex.Metadata)).Append(Environment.NewLine); logStr.Append("TargetIndexName : ").Append(clientIndex.TargetIndexName).Append(Environment.NewLine); logStr.Append("IndexTagmapping : ").Append(clientIndex.IndexTagMapping == null ? "Null" : clientIndex.IndexTagMapping.Count.ToString()).Append(Environment.NewLine); if (clientIndex.IndexTagMapping != null && clientIndex.IndexTagMapping.Count > 0) { logStr.Append("IndexTagmapping Items : "); foreach (var indexTag in clientIndex.IndexTagMapping) { logStr.Append("IndexName : ").Append(indexTag.Key).Append(" Tags : "); foreach (var tag in indexTag.Value) { logStr.Append(tag).Append(" , "); } } logStr.Append(Environment.NewLine); } //AddList)) if (clientIndex.AddList != null) { logStr.Append("ClientIndex.AddList.Count : ").Append(clientIndex.AddList.Count).Append(Environment.NewLine); itemCount = 0; foreach (IndexDataItem indexDataItem in clientIndex.AddList) { LogItem(logStr, indexDataItem, itemCount, tagHashCollection, typeId); } } else { logStr.Append("ClientIndex.AddList = null").Append(Environment.NewLine); } //DeleteList if (clientIndex.DeleteList != null) { logStr.Append("ClientIndex.DeleteList.Count : ").Append(clientIndex.DeleteList.Count).Append(Environment.NewLine); itemCount = 0; foreach (IndexItem indexItem in clientIndex.DeleteList) { LogItem(logStr, indexItem, itemCount, tagHashCollection, typeId); } } else { logStr.Append("ClientIndex.DeleteList = null").Append(Environment.NewLine); } return(logStr.ToString()); }
private static void LogItem(StringBuilder logStr, IItem iItem, int itemCount, TagHashCollection tagHashCollection, short typeId) { if (iItem.ItemId == null) { logStr.Append("ItemList[").Append(itemCount.ToString()).Append("].ItemId = null").Append(Environment.NewLine); } else if (iItem.ItemId.Length == 0) { logStr.Append("ItemList[").Append(itemCount.ToString()).Append("].ItemId.Length = 0").Append(Environment.NewLine); } else { logStr.Append("ItemList[").Append(itemCount.ToString()).Append("].ItemId = ").Append(IndexCacheUtils.GetReadableByteArray(iItem.ItemId)).Append(Environment.NewLine); } logStr.Append("Tags.Count : "); if (iItem is IndexItem) { var indexItem = (IndexItem)iItem; if (indexItem.Tags != null && indexItem.Tags.Count > 0) { logStr.Append(indexItem.Tags.Count).Append(" - "); foreach (var tag in indexItem.Tags) { logStr.Append(tag.Key).Append("=").Append(IndexCacheUtils.GetReadableByteArray(tag.Value)). Append(", "); } } else { logStr.Append("0"); } } else if (iItem is InternalItem) { var internalItem = (InternalItem)iItem; if (internalItem.TagList != null && internalItem.TagList.Count > 0) { logStr.Append(internalItem.TagList.Count).Append(" - "); foreach (var tag in internalItem.TagList) { logStr.Append(tagHashCollection.GetTagName(typeId, tag.Key)). Append("=").Append(IndexCacheUtils.GetReadableByteArray(tag.Value)). Append(", "); } } else { logStr.Append("0"); } } logStr.Append(Environment.NewLine); }
/// <summary> /// Gets printable CacheIndex. /// </summary> /// <param name="clientIndex">client index.</param> /// <param name="tagHashCollection">tag Hash Collection.</param> /// <returns></returns> internal static string GetPrintableCacheIndex(CacheIndex clientIndex, TagHashCollection tagHashCollection, short typeId) { StringBuilder logStr = new StringBuilder(); logStr.Append(Environment.NewLine).Append("Client Index Info").Append(Environment.NewLine); int itemCount; logStr.Append("IndexId : ").Append(IndexCacheUtils.GetReadableByteArray(clientIndex.IndexId)). Append(Environment.NewLine); //AddList if (clientIndex.AddList != null) { logStr.Append("ClientIndex.AddList.Count : ").Append(clientIndex.AddList.Count).Append(Environment.NewLine); itemCount = 0; foreach (IndexDataItem indexDataItem in clientIndex.AddList) { LogItem(logStr, indexDataItem, itemCount, tagHashCollection, typeId); } } else { logStr.Append("ClientIndex.AddList = null").Append(Environment.NewLine); } //DeleteList if (clientIndex.DeleteList != null) { logStr.Append("ClientIndex.DeleteList.Count : ").Append(clientIndex.DeleteList.Count).Append(Environment.NewLine); itemCount = 0; foreach (IndexItem indexItem in clientIndex.DeleteList) { LogItem(logStr, indexItem, itemCount, tagHashCollection, typeId); } } else { logStr.Append("ClientIndex.DeleteList = null").Append(Environment.NewLine); } return(logStr.ToString()); }
/// <summary> /// Formats the index ids. /// </summary> /// <param name="indexIds">The index ids.</param> /// <returns>formatted index ids</returns> internal static string FormatIndexIds(ICollection <byte[]> indexIds) { var stb = new StringBuilder(); if (indexIds == null) { stb.Append("null"); } else { stb.Append("Count: ").Append(indexIds.Count).Append(" IndexIds: "); foreach (var indexId in indexIds) { stb.Append(IndexCacheUtils.GetReadableByteArray(indexId)).Append(", "); } } return(stb.ToString()); }
/// <summary> /// Deserialize the class data from a stream. /// </summary> /// <param name="reader">The <see cref="IPrimitiveReader"/> that extracts used to extra data from a stream.</param> /// <param name="version">The value of <see cref="CurrentVersion"/> that was written to the stream when it was originally serialized to a stream; /// the version of the <paramref name="reader"/> data.</param> public void Deserialize(IPrimitiveReader reader, int version) { //Metadata ushort len = reader.ReadUInt16(); if (len > 0) { Metadata = reader.ReadBytes(len); } //VirtualCount if (version >= 2) { virtualCount = reader.ReadInt32(); } //Count outDeserializationContext = new OutDeserializationContext { TotalCount = reader.ReadInt32() }; if (InDeserializationContext.DeserializeHeaderOnly) { //Note: If InDeserializationContext.DeserializeHeaderOnly property is set then InDeserializationContext.PartialByteArray shall hold all CacheIndexInternal //payload except metadata and header (just virtual count for now). This code path will only be used if just //header info like virtual count needs to be updated keeping rest of the index untouched. //InDeserializationContext.PartialByteArray shall be used in Serialize code outDeserializationContext.UnserializedCacheIndexInternal = new byte[(int)reader.BaseStream.Length - (int)reader.BaseStream.Position + 1]; reader.BaseStream.Read(outDeserializationContext.UnserializedCacheIndexInternal, 0, outDeserializationContext.UnserializedCacheIndexInternal.Length); } else { int actualItemCount = outDeserializationContext.TotalCount; //this.InDeserializationContext.MaxItemsPerIndex = 0 indicates need to extract all items //this.InDeserializationContext.MaxItemsPerIndex > 0 indicates need to extract only number of items indicated by InDeserializationContext.MaxItemsPerIndex if (InDeserializationContext.MaxItemsPerIndex > 0) { if (InDeserializationContext.MaxItemsPerIndex < outDeserializationContext.TotalCount) { actualItemCount = InDeserializationContext.MaxItemsPerIndex; } } #region Populate InternalItemList byte[] itemId; InternalItem internalItem; bool enterConditionPassed = false; InternalItemList = new InternalItemList(); // Note: ---- Termination condition of the loop // For full index extraction loop shall terminate because of condition : internalItemList.Count < actualItemCount // For partial index extraction loop shall terminate because of following conditions // a) i < InDeserializationContext.TotalCount (when no sufficient items are found) OR // b) internalItemList.Count < actualItemCount (Item extraction cap is reached) int i = 0; while (InternalItemList.Count < actualItemCount && i < outDeserializationContext.TotalCount) { i++; #region Deserialize ItemId len = reader.ReadUInt16(); if (len > 0) { itemId = reader.ReadBytes(len); } else { throw new Exception("Invalid ItemId - is null or length is zero for IndexId : " + IndexCacheUtils.GetReadableByteArray(InDeserializationContext.IndexId)); } #endregion #region Process IndexCondition if (InDeserializationContext.EnterCondition != null || InDeserializationContext.ExitCondition != null) { #region Have Enter/Exit Condition if (InDeserializationContext.PrimarySortInfo.IsTag == false) { #region Sort by ItemId if (InDeserializationContext.EnterCondition != null && enterConditionPassed == false) { #region enter condition processing if (InDeserializationContext.EnterCondition.Process(itemId)) { enterConditionPassed = true; internalItem = DeserializeInternalItem(itemId, InDeserializationContext, reader); ApplyFilterAndAddItem(internalItem); } else { SkipDeserializeInternalItem(reader); // no filter processing required } #endregion } else if (InDeserializationContext.ExitCondition != null) { #region exit condition processing if (InDeserializationContext.ExitCondition.Process(itemId)) { // since item passed exit filter, we keep it. internalItem = DeserializeInternalItem(itemId, InDeserializationContext, reader); ApplyFilterAndAddItem(internalItem); } else { // no need to search beyond this point break; } #endregion } else if (InDeserializationContext.EnterCondition != null && enterConditionPassed && InDeserializationContext.ExitCondition == null) { #region enter condition processing when no exit condition exists internalItem = DeserializeInternalItem(itemId, InDeserializationContext, reader); ApplyFilterAndAddItem(internalItem); #endregion } #endregion } else { byte[] tagValue; #region Deserialize InternalItem and fetch PrimarySortTag value internalItem = DeserializeInternalItem(itemId, InDeserializationContext, reader); if (!internalItem.TryGetTagValue(InDeserializationContext.PrimarySortInfo.FieldName, out tagValue)) { throw new Exception("PrimarySortTag Not found: " + InDeserializationContext.PrimarySortInfo.FieldName); } #endregion #region Sort by Tag if (InDeserializationContext.EnterCondition != null && enterConditionPassed == false) { #region enter condition processing if (InDeserializationContext.EnterCondition.Process(tagValue)) { enterConditionPassed = true; ApplyFilterAndAddItem(internalItem); } #endregion } else if (InDeserializationContext.ExitCondition != null) { #region exit condition processing if (InDeserializationContext.ExitCondition.Process(tagValue)) { // since item passed exit filter, we keep it. ApplyFilterAndAddItem(internalItem); } else { // no need to search beyond this point break; } #endregion } else if (InDeserializationContext.EnterCondition != null && enterConditionPassed && InDeserializationContext.ExitCondition == null) { #region enter condition processing when no exit condition exists ApplyFilterAndAddItem(internalItem); #endregion } #endregion } #endregion } else { #region No Enter/Exit Condition internalItem = DeserializeInternalItem(itemId, InDeserializationContext, reader); ApplyFilterAndAddItem(internalItem); #endregion } #endregion } //Set ReadItemCount on OutDeserializationContext outDeserializationContext.ReadItemCount = i; #endregion } }
/// <summary> /// Serialize the class data to a stream. /// </summary> /// <param name="writer">The <see cref="IPrimitiveWriter"/> that writes to the stream.</param> public void Serialize(IPrimitiveWriter writer) { //Metadata if (Metadata == null || Metadata.Length == 0) { writer.Write((ushort)0); } else { writer.Write((ushort)Metadata.Length); writer.Write(Metadata); } if (!LegacySerializationUtil.Instance.IsSupported(InDeserializationContext.TypeId)) { //VirtualCount writer.Write(virtualCount); } // Note: If InDeserializationContext.DeserializeHeaderOnly property is set then InDeserializationContext.UnserializedCacheIndexInternal shall hold all CacheIndexInternal // payload except metadata and virtual count. This code path will only be used if just header info like // virtual count needs to be updated keeping rest of the index untouched if (InDeserializationContext.DeserializeHeaderOnly && outDeserializationContext.UnserializedCacheIndexInternal != null && outDeserializationContext.UnserializedCacheIndexInternal.Length != 0) { //Count writer.Write(outDeserializationContext.TotalCount); // UnserializedCacheIndexInternal writer.BaseStream.Write(outDeserializationContext.UnserializedCacheIndexInternal, 0, outDeserializationContext.UnserializedCacheIndexInternal.Length); } else { //Count if (InternalItemList == null || InternalItemList.Count == 0) { writer.Write(0); } else { writer.Write(InternalItemList.Count); for (int i = 0; i < InternalItemList.Count; i++) { //Id if (InternalItemList[i].ItemId == null || InternalItemList[i].ItemId.Length == 0) { throw new Exception("Invalid ItemId - is null or length is zero for IndexId : " + IndexCacheUtils.GetReadableByteArray(InDeserializationContext.IndexId)); } writer.Write((ushort)InternalItemList[i].ItemId.Length); writer.Write(InternalItemList[i].ItemId); //(byte)KvpListCount if (InternalItemList[i].TagList == null || InternalItemList[i].TagList.Count == 0) { writer.Write((byte)0); } else { writer.Write((byte)InternalItemList[i].TagList.Count); //KvpList byte[] stringHashValue; foreach (KeyValuePair <int /*TagHashCode*/, byte[] /*TagValue*/> kvp in InternalItemList[i].TagList) { writer.Write(kvp.Key); if (kvp.Value == null || kvp.Value.Length == 0) { writer.Write((ushort)0); } else { if (InDeserializationContext.StringHashCodeDictionary != null && InDeserializationContext.StringHashCodeDictionary.Count > 0 && InDeserializationContext.StringHashCodeDictionary.ContainsKey(kvp.Key)) { InDeserializationContext.StringHashCollection.AddStringArray(InDeserializationContext.TypeId, kvp.Value); stringHashValue = StringHashCollection.GetHashCodeByteArray(kvp.Value); writer.Write((ushort)stringHashValue.Length); writer.Write(stringHashValue); } else { writer.Write((ushort)kvp.Value.Length); writer.Write(kvp.Value); } } } } } } } }
/// <summary> /// Processes the get message. /// </summary> /// <param name="message">The message.</param> /// <param name="messageContext">The message context.</param> private void ProcessGetMessage(RelayMessage message, MessageContext messageContext) { byte[] payloadByteArray = GetProcessor.Process(messageContext, storeContext); if (payloadByteArray != null) { bool compress = storeContext.GetCompressOption(message.TypeId); message.Payload = new RelayPayload(message.TypeId, message.Id, payloadByteArray, compress); } else { LoggingUtil.Log.InfoFormat("Miss in CacheIndexStorage for Id : {0}, ExtendedId : ", message.Id, IndexCacheUtils.GetReadableByteArray(message.ExtendedId)); } }
/// <summary> /// Processes the specified cache index. /// </summary> /// <param name="cacheIndex">Index of the cache.</param> /// <param name="messageContext">The message context.</param> /// <param name="storeContext">The store context.</param> internal static void Process(CacheIndex cacheIndex, MessageContext messageContext, IndexStoreContext storeContext) { lock (LockingUtil.Instance.GetLock(messageContext.PrimaryId)) { try { IndexTypeMapping indexTypeMapping = storeContext.StorageConfiguration.CacheIndexV3StorageConfig.IndexTypeMappingCollection[messageContext.TypeId]; #region Extract CacheIndex and Validate from incoming message ValidateSave(cacheIndex); #endregion #region Log CacheIndex before processing StringBuilder dbgIndexInfo = null; if (LoggingUtil.Log.IsDebugEnabled) { dbgIndexInfo = new StringBuilder(); dbgIndexInfo.Append("TypeId=").Append(messageContext.TypeId).Append(Environment.NewLine); dbgIndexInfo.Append(IndexServerUtils.GetPrintableCacheIndex(cacheIndex, storeContext.TagHashCollection, messageContext.TypeId)); } #endregion #region Init vars List <RelayMessage> indexStorageMessageList = new List <RelayMessage>(); List <RelayMessage> dataStorageMessageList = new List <RelayMessage>(); List <CacheIndexInternal> internalIndexList = new List <CacheIndexInternal>(); List <IndexItem> cappedDeleteItemList = new List <IndexItem>(); CacheIndexInternal internalIndex; #endregion if (cacheIndex.IndexVirtualCountMapping == null) { #region Save Items #region Extract CacheIndexInternal from index storage if (cacheIndex.TargetIndexName == null) //Save to multiple indexes { #region Get CacheIndexInternal for multiple indexes foreach (KeyValuePair <string /*IndexName*/, List <string> /*TagNameList*/> kvp in cacheIndex.IndexTagMapping) { Index indexInfo = indexTypeMapping.IndexCollection[kvp.Key]; internalIndex = IndexServerUtils.GetCacheIndexInternal(storeContext, messageContext.TypeId, cacheIndex.PrimaryId, cacheIndex.IndexId, indexInfo.ExtendedIdSuffix, kvp.Key, 0, null, true, null, false, false, indexInfo.PrimarySortInfo, indexInfo.LocalIdentityTagList, indexInfo.StringHashCodeDictionary, null); if (internalIndex != null) { // update performance counter PerformanceCounters.Instance.SetCounterValue( PerformanceCounterEnum.NumberOfItemsInIndexPerSave, messageContext.TypeId, internalIndex.OutDeserializationContext.TotalCount); } if (internalIndex == null || cacheIndex.ReplaceFullIndex) //CacheIndexInternal does not exists or is to be discarded { internalIndex = new CacheIndexInternal { InDeserializationContext = new InDeserializationContext { TypeId = messageContext.TypeId, TagHashCollection = storeContext.TagHashCollection, IndexId = cacheIndex.IndexId, IndexName = kvp.Key, InclusiveFilter = true, PrimarySortInfo = indexInfo.PrimarySortInfo, LocalIdentityTagNames = indexInfo.LocalIdentityTagList, StringHashCollection = storeContext.StringHashCollection, StringHashCodeDictionary = indexInfo.StringHashCodeDictionary } }; } internalIndexList.Add(internalIndex); } #endregion } else //Save to single index { #region Get CacheIndexInternal for TargetIndexName Index indexInfo = indexTypeMapping.IndexCollection[cacheIndex.TargetIndexName]; internalIndex = IndexServerUtils.GetCacheIndexInternal(storeContext, messageContext.TypeId, cacheIndex.PrimaryId, cacheIndex.IndexId, indexInfo.ExtendedIdSuffix, cacheIndex.TargetIndexName, 0, null, true, null, false, false, indexInfo.PrimarySortInfo, indexInfo.LocalIdentityTagList, indexInfo.StringHashCodeDictionary, null); if (internalIndex != null) { // update performance counter PerformanceCounters.Instance.SetCounterValue( PerformanceCounterEnum.NumberOfItemsInIndexPerSave, messageContext.TypeId, internalIndex.OutDeserializationContext.TotalCount); } if (internalIndex == null || cacheIndex.ReplaceFullIndex) //CacheIndexInternal does not exists or is to be discarded { internalIndex = new CacheIndexInternal { InDeserializationContext = new InDeserializationContext { TypeId = messageContext.TypeId, TagHashCollection = storeContext.TagHashCollection, IndexId = cacheIndex.IndexId, IndexName = cacheIndex.TargetIndexName, InclusiveFilter = true, PrimarySortInfo = indexInfo.PrimarySortInfo, LocalIdentityTagNames = indexInfo.LocalIdentityTagList, StringHashCollection = storeContext.StringHashCollection, StringHashCodeDictionary = indexInfo.StringHashCodeDictionary } }; } internalIndexList.Add(internalIndex); #endregion } #endregion #region Log CacheIndexInternals before save if (LoggingUtil.Log.IsDebugEnabled && dbgIndexInfo != null) { dbgIndexInfo.Append(Environment.NewLine).Append(string.Format("BEFORE SAVE {0}", IndexServerUtils.GetPrintableCacheIndexInternalList( internalIndexList, storeContext.TagHashCollection, messageContext.TypeId))); } #endregion #region Process Delete and Add List try { #region Process Delete List if (cacheIndex.DeleteList.Count > 0 && !cacheIndex.ReplaceFullIndex) { ProcessDeleteList(internalIndexList, cacheIndex.DeleteList, messageContext.TypeId); } #endregion #region Process Add List if (cacheIndex.AddList.Count > 0 || cacheIndex.UpdateMetadata) { ProcessAddList(internalIndexList, cappedDeleteItemList, cacheIndex, storeContext, indexTypeMapping); } #endregion } catch { LoggingUtil.Log.Debug(IndexServerUtils.GetPrintableCacheIndexInternalList(internalIndexList, storeContext.TagHashCollection, messageContext.TypeId)); throw; } #endregion #region Log CacheIndexInternals after save if (LoggingUtil.Log.IsDebugEnabled && dbgIndexInfo != null) { dbgIndexInfo.Append(Environment.NewLine).Append(string.Format("AFTER SAVE {0}", IndexServerUtils.GetPrintableCacheIndexInternalList(internalIndexList, storeContext.TagHashCollection, messageContext.TypeId))); } #endregion #region Data store relay messages for deletes and saves if (DataTierUtil.ShouldForwardToDataTier(messageContext.RelayTTL, messageContext.SourceZone, storeContext.MyZone, indexTypeMapping.IndexServerMode) && !cacheIndex.PreserveData) { byte[] fullDataId; short relatedTypeId; 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); } #region Delete Messages foreach (IndexItem indexItem in cacheIndex.DeleteList) { fullDataId = DataTierUtil.GetFullDataId(cacheIndex.IndexId, indexItem, indexTypeMapping.FullDataIdFieldList); if (fullDataId != null) { dataStorageMessageList.Add(new RelayMessage(relatedTypeId, IndexCacheUtils.GeneratePrimaryId(fullDataId), fullDataId, MessageType.Delete)); } } #endregion #region Save Messages foreach (IndexDataItem indexDataItem in cacheIndex.AddList) { fullDataId = DataTierUtil.GetFullDataId(cacheIndex.IndexId, indexDataItem, indexTypeMapping.FullDataIdFieldList); if (fullDataId != null) { dataStorageMessageList.Add(new RelayMessage(relatedTypeId, IndexCacheUtils.GeneratePrimaryId(fullDataId), fullDataId, DateTime.Now, indexDataItem.Data ?? new byte[0], storeContext.GetCompressOption(messageContext.TypeId), MessageType.Save)); if (indexDataItem.Data == null || indexDataItem.Data.Length == 0) { LoggingUtil.Log.WarnFormat("Saving null data for TypeId: {0}, IndexId: {1}, ItemId: {2}, FullDataId: {3}, PrimaryId: {4}", relatedTypeId, IndexCacheUtils.GetReadableByteArray(cacheIndex.IndexId), IndexCacheUtils.GetReadableByteArray(indexDataItem.ItemId), IndexCacheUtils.GetReadableByteArray(fullDataId), IndexCacheUtils.GeneratePrimaryId(fullDataId)); } } } #endregion #region Capped Item Delete Messages foreach (IndexItem indexItem in cappedDeleteItemList) { fullDataId = DataTierUtil.GetFullDataId(cacheIndex.IndexId, indexItem, indexTypeMapping.FullDataIdFieldList); if (fullDataId != null) { dataStorageMessageList.Add(new RelayMessage(relatedTypeId, IndexCacheUtils.GeneratePrimaryId(fullDataId), fullDataId, MessageType.Delete)); } } #endregion #region Send relay mesaages to data store if (dataStorageMessageList.Count > 0) { storeContext.ForwarderComponent.HandleMessages(dataStorageMessageList); } #endregion } #endregion #endregion if (dbgIndexInfo != null) { LoggingUtil.Log.Debug(dbgIndexInfo.ToString()); } } else { #region Update Virtual Count foreach (KeyValuePair <string /*IndexName*/, int /*VirtualCount*/> kvp in cacheIndex.IndexVirtualCountMapping) { Index indexInfo = indexTypeMapping.IndexCollection[kvp.Key]; internalIndex = IndexServerUtils.GetCacheIndexInternal(storeContext, messageContext.TypeId, cacheIndex.PrimaryId, cacheIndex.IndexId, indexInfo.ExtendedIdSuffix, kvp.Key, 0, null, true, null, true, false, indexInfo.PrimarySortInfo, indexInfo.LocalIdentityTagList, indexInfo.StringHashCodeDictionary, null); if (internalIndex == null) { internalIndex = new CacheIndexInternal { InDeserializationContext = new InDeserializationContext { TypeId = messageContext.TypeId, TagHashCollection = storeContext.TagHashCollection, IndexId = cacheIndex.IndexId, IndexName = kvp.Key, InclusiveFilter = true, DeserializeHeaderOnly = true, PrimarySortInfo = indexInfo.PrimarySortInfo, LocalIdentityTagNames = indexInfo.LocalIdentityTagList, StringHashCollection = storeContext.StringHashCollection, StringHashCodeDictionary = indexInfo.StringHashCodeDictionary } }; } else { // update performance counter PerformanceCounters.Instance.SetCounterValue( PerformanceCounterEnum.NumberOfItemsInIndexPerSave, messageContext.TypeId, internalIndex.OutDeserializationContext.TotalCount); } internalIndex.VirtualCount = kvp.Value; internalIndexList.Add(internalIndex); } #endregion } #region Index storage relay messages for each CacheIndexInternal #region Metadata if (indexTypeMapping.MetadataStoredSeperately && cacheIndex.UpdateMetadata) { indexStorageMessageList.Add(new RelayMessage(messageContext.TypeId, cacheIndex.PrimaryId, cacheIndex.IndexId, DateTime.Now, cacheIndex.Metadata ?? new byte[0], storeContext.GetCompressOption(messageContext.TypeId), MessageType.Save)); } #endregion #region Index(es) byte[] payload; CompactBinaryWriter writer; RelayMessage indexStorageMessage; byte[] extendedId; foreach (CacheIndexInternal cacheIndexInternal in internalIndexList) { extendedId = IndexServerUtils.FormExtendedId( cacheIndex.IndexId, indexTypeMapping.IndexCollection[cacheIndexInternal.InDeserializationContext.IndexName].ExtendedIdSuffix); // This mess is required until Moods 2.0 migrated to have IVersionSerializable version of CacheIndexInternal // ** TBD - Should be removed later if (LegacySerializationUtil.Instance.IsSupported(messageContext.TypeId)) { writer = new CompactBinaryWriter(new BinaryWriter(new MemoryStream())); cacheIndexInternal.Serialize(writer); payload = new byte[writer.BaseStream.Length]; writer.BaseStream.Position = 0; writer.BaseStream.Read(payload, 0, payload.Length); indexStorageMessage = new RelayMessage(messageContext.TypeId, cacheIndex.PrimaryId, extendedId, DateTime.Now, payload, storeContext.GetCompressOption(messageContext.TypeId), MessageType.Save); } else { indexStorageMessage = RelayMessage.GetSaveMessageForObject(messageContext.TypeId, cacheIndex.PrimaryId, extendedId, DateTime.Now, cacheIndexInternal, storeContext.GetCompressOption(messageContext.TypeId)); } indexStorageMessageList.Add(indexStorageMessage); } #endregion #region Send relay mesaages to index storage storeContext.IndexStorageComponent.HandleMessages(indexStorageMessageList); #endregion #endregion } catch (Exception ex) { LoggingUtil.Log.DebugFormat("CacheIndex: {0}", IndexServerUtils.GetPrintableCacheIndex(cacheIndex, storeContext.TagHashCollection, messageContext.TypeId)); throw new Exception("TypeId " + messageContext.TypeId + " -- Error processing save message.", ex); } } }
/// <summary> /// Processes the specified MetadataPropertyQuery. /// </summary> /// <param name="metadataPropertyQuery">The MetadataPropertyQuery.</param> /// <param name="messageContext">The message context.</param> /// <param name="storeContext">The store context.</param> /// <returns></returns> internal static MetadataPropertyQueryResult Process(MetadataPropertyQuery metadataPropertyQuery, MessageContext messageContext, IndexStoreContext storeContext) { MetadataPropertyQueryResult metadataPropertyQueryResult; MetadataPropertyCollection metadataPropertyCollection = null; try { IndexTypeMapping indexTypeMapping = storeContext.StorageConfiguration.CacheIndexV3StorageConfig.IndexTypeMappingCollection[messageContext.TypeId]; if (indexTypeMapping.IsMetadataPropertyCollection || indexTypeMapping.IndexCollection[metadataPropertyQuery.TargetIndexName].IsMetadataPropertyCollection) { #region Fetch MetadataPropertyCollection if (indexTypeMapping.MetadataStoredSeperately) { byte[] metadata; IndexServerUtils.GetMetadataStoredSeperately(indexTypeMapping, messageContext.TypeId, metadataPropertyQuery.PrimaryId, metadataPropertyQuery.IndexId, storeContext, out metadata, out metadataPropertyCollection); } else { // Get CacheIndexInternal Index indexInfo = indexTypeMapping.IndexCollection[metadataPropertyQuery.TargetIndexName]; CacheIndexInternal cacheIndexInternal = IndexServerUtils.GetCacheIndexInternal(storeContext, messageContext. TypeId, metadataPropertyQuery .PrimaryId, metadataPropertyQuery .IndexId, indexInfo. ExtendedIdSuffix, metadataPropertyQuery . TargetIndexName, 0, null, false, null, true, false, null, null, null, null, true, null, DomainSpecificProcessingType .None, null, null, null, true); if (cacheIndexInternal != null) { metadataPropertyCollection = cacheIndexInternal.MetadataPropertyCollection; } } #endregion } metadataPropertyQueryResult = new MetadataPropertyQueryResult { MetadataPropertyCollection = metadataPropertyCollection }; } catch (Exception ex) { metadataPropertyQueryResult = new MetadataPropertyQueryResult { MetadataPropertyCollection = metadataPropertyCollection, ExceptionInfo = ex.Message }; LoggingUtil.Log.ErrorFormat("TypeId {0} -- Error processing MetadataPropertyQuery : {1} for IndexId : {2} and TargetIndexname : {3}", messageContext.TypeId, ex, metadataPropertyQuery.IndexId != null ? IndexCacheUtils.GetReadableByteArray(metadataPropertyQuery.IndexId) : "Null", metadataPropertyQuery.TargetIndexName ?? "Null"); } return(metadataPropertyQueryResult); }