Example #1
0
        protected override bool IsIgnorableItem(MessageRec msg)
        {
            if (base.IsIgnorableItem(msg))
            {
                return(true);
            }
            if (msg.CreationTimestamp > ((MergeJob)base.MRSJob).MailboxSnapshotTimestamp)
            {
                return(true);
            }
            if (msg.IsFAI && base.MRSJob.CachedRequestJob.AssociatedMessagesCopyOption != FAICopyOption.Copy)
            {
                MrsTracer.Service.Debug("Ignoring FAI item because FAICopyOption!=Copy", new object[0]);
                return(true);
            }
            string text;

            if (FolderContentsMapper.ShouldItemBeIgnored(msg, (base.SyncState == null) ? null : base.SyncState.BadItems, base.MRSJob.CachedRequestJob.AssociatedMessagesCopyOption ?? FAICopyOption.DoNotCopy, out text))
            {
                return(true);
            }
            this.EnsureDumpsterContentsIsLoaded();
            if (this.targetDeletedContents.Contains(msg.EntryId))
            {
                MrsTracer.Service.Debug("Item is deleted, ignoring.", new object[0]);
                return(true);
            }
            return(false);
        }
        private Dictionary <string, List <MessageRec> > CreateFaiMap(IReadOnlyCollection <MessageRec> messages, EntryIdMap <BadItemMarker> badItemMarkers)
        {
            Dictionary <string, List <MessageRec> > dictionary = new Dictionary <string, List <MessageRec> >(StringComparer.OrdinalIgnoreCase);

            foreach (MessageRec messageRec in messages)
            {
                string text;
                if (messageRec.IsFAI && !FolderContentsMapper.ShouldItemBeIgnored(messageRec, badItemMarkers, this.faiCopyOption, out text) && !string.IsNullOrEmpty(text))
                {
                    List <MessageRec> list;
                    if (!dictionary.TryGetValue(text, out list))
                    {
                        list = new List <MessageRec>(1);
                        dictionary.Add(text, list);
                    }
                    list.Add(messageRec);
                }
            }
            return(dictionary);
        }
        public void ComputeMapping(IReadOnlyCollection <MessageRec> sourceMessages, IReadOnlyCollection <MessageRec> targetMessages, EntryIdMap <BadItemMarker> badItemMarkers, out int skippedItemCount, out ulong skippedItemSize, out List <MessageRec> itemsToCopy, out List <MessageRec> targetMessagePropsChanges)
        {
            itemsToCopy = new List <MessageRec>(sourceMessages.Count);
            targetMessagePropsChanges = new List <MessageRec>();
            skippedItemCount          = 0;
            skippedItemSize           = 0UL;
            if (sourceMessages.Count == 0)
            {
                MrsTracer.Service.Debug("No more contents in source folder", new object[0]);
                return;
            }
            EntryIdMap <MessageRec> entryIdMap  = new EntryIdMap <MessageRec>();
            HashSet <byte[]>        hashSet     = new HashSet <byte[]>(ArrayComparer <byte> .EqualityComparer);
            EntryIdMap <MessageRec> entryIdMap2 = new EntryIdMap <MessageRec>();
            Dictionary <string, List <MessageRec> > dictionary  = null;
            Dictionary <string, List <MessageRec> > dictionary2 = null;

            if (this.faiCopyOption == FAICopyOption.MapByMessageClass)
            {
                dictionary  = this.CreateFaiMap(sourceMessages, badItemMarkers);
                dictionary2 = this.CreateFaiMap(targetMessages, badItemMarkers);
            }
            foreach (MessageRec messageRec in targetMessages)
            {
                byte[] keyPlusLMTHash = this.GetKeyPlusLMTHash(messageRec, this.destHierarchy.SourceEntryIDPtag, this.destHierarchy.SourceLastModifiedTimestampPtag);
                if (keyPlusLMTHash != null)
                {
                    entryIdMap2[keyPlusLMTHash] = messageRec;
                }
                List <byte[]> secondaryKeys = this.GetSecondaryKeys(messageRec, MessageRecType.Target);
                this.RegisterUniqueTargetSecondaryKeys(messageRec, secondaryKeys, entryIdMap, hashSet);
            }
            HashSet <byte[]> uniqueSecondaryKeys = new HashSet <byte[]>(ArrayComparer <byte> .EqualityComparer);
            HashSet <byte[]> hashSet2            = new HashSet <byte[]>(ArrayComparer <byte> .EqualityComparer);

            foreach (MessageRec message in sourceMessages)
            {
                List <byte[]> secondaryKeys2 = this.GetSecondaryKeys(message, MessageRecType.Source);
                this.IdentifyDuplicateSecondaryKeys(message, secondaryKeys2, uniqueSecondaryKeys, hashSet2);
            }
            foreach (MessageRec messageRec2 in sourceMessages)
            {
                string text;
                if (FolderContentsMapper.ShouldItemBeIgnored(messageRec2, badItemMarkers, this.faiCopyOption, out text))
                {
                    skippedItemCount++;
                    skippedItemSize += (ulong)((long)messageRec2.MessageSize);
                }
                else
                {
                    MessageRec        messageRec3 = null;
                    List <MessageRec> list;
                    List <MessageRec> list2;
                    if (this.faiCopyOption == FAICopyOption.MapByMessageClass && messageRec2.IsFAI && !string.IsNullOrEmpty(text) && dictionary.TryGetValue(text, out list) && list.Count == 1 && dictionary2.TryGetValue(text, out list2) && list2.Count == 1)
                    {
                        messageRec3 = list2[0];
                        MrsTracer.Service.Debug("Mapped FAI message with message class '{0}'", new object[]
                        {
                            text
                        });
                    }
                    if (messageRec3 == null)
                    {
                        this.MapSourceToTargetMessage(messageRec2, entryIdMap2, entryIdMap, hashSet, hashSet2, out messageRec3);
                    }
                    MessageRec item = null;
                    if (this.ShouldTargetMessagePropsBeUpdated(messageRec2, messageRec3, out item))
                    {
                        skippedItemCount++;
                        skippedItemSize += (ulong)((long)messageRec2.MessageSize);
                        targetMessagePropsChanges.Add(item);
                    }
                    else if (this.ShouldItemBeCopied(messageRec2, messageRec3, hashSet))
                    {
                        itemsToCopy.Add(messageRec2);
                        this.sourceMapping[messageRec2.EntryId] = messageRec2;
                        if (messageRec3 != null)
                        {
                            this.targetMapping[messageRec2.EntryId] = messageRec3;
                        }
                    }
                    else
                    {
                        skippedItemCount++;
                        skippedItemSize += (ulong)((long)messageRec2.MessageSize);
                    }
                }
            }
        }
        public void ComputeIncrementalMapping(FolderChangesManifest folderChanges, EntryIdMap <BadItemMarker> badItemMarkers, out List <MessageRec> itemsToCopy, out byte[][] deletedTargetEntryIDs, out byte[][] readTargetEntryIDs, out byte[][] unreadTargetEntryIDs, out int skippedItemCount)
        {
            MrsTracer.Service.Function("FolderContentsMapper.ComputeIncrementalMapping", new object[0]);
            skippedItemCount      = 0;
            itemsToCopy           = null;
            deletedTargetEntryIDs = null;
            readTargetEntryIDs    = null;
            unreadTargetEntryIDs  = null;
            List <byte[]> list  = new List <byte[]>();
            List <byte[]> list2 = new List <byte[]>();
            List <byte[]> list3 = new List <byte[]>();

            if (folderChanges.ChangedMessages != null)
            {
                foreach (MessageRec messageRec in folderChanges.ChangedMessages)
                {
                    list2.Add(messageRec.EntryId);
                    if (!messageRec.IsDeleted)
                    {
                        list.Add(messageRec.EntryId);
                    }
                    else
                    {
                        list3.Add(messageRec.EntryId);
                    }
                }
            }
            if (folderChanges.ReadMessages != null)
            {
                list2.AddRange(folderChanges.ReadMessages);
            }
            if (folderChanges.UnreadMessages != null)
            {
                list2.AddRange(folderChanges.UnreadMessages);
            }
            if (list2.Count == 0)
            {
                return;
            }
            list2.Sort(ArrayComparer <byte> .Comparer);
            List <PropTag> list4 = new List <PropTag>();

            list4.Add(PropTag.SearchKey);
            list4.Add(PropTag.LastModificationTime);
            list4.Add(PropTag.MessageClass);
            List <MessageRec> list5 = null;

            if (list.Count > 0)
            {
                MrsTracer.Service.Debug("Loading changed source messages", new object[0]);
                list.Sort(ArrayComparer <byte> .Comparer);
                list5 = this.srcFolder.LookupMessages(PropTag.EntryId, list, list4.ToArray());
            }
            EntryIdMap <MessageRec> entryIdMap = new EntryIdMap <MessageRec>();

            if (this.conflictResolutionOption != ConflictResolutionOption.KeepAll)
            {
                list4.Add(this.destHierarchy.SourceEntryIDPtag);
                list4.Add(this.destHierarchy.SourceLastModifiedTimestampPtag);
                MrsTracer.Service.Debug("Looking up target messages", new object[0]);
                List <MessageRec> list6 = this.destFolder.LookupMessages(this.destHierarchy.SourceEntryIDPtag, list2, list4.ToArray());
                foreach (MessageRec messageRec2 in list6)
                {
                    byte[] array = messageRec2[this.destHierarchy.SourceEntryIDPtag] as byte[];
                    if (array != null)
                    {
                        this.targetMapping[array] = messageRec2;
                    }
                    byte[] keyPlusLMTHash = this.GetKeyPlusLMTHash(messageRec2, this.destHierarchy.SourceEntryIDPtag, this.destHierarchy.SourceLastModifiedTimestampPtag);
                    if (keyPlusLMTHash != null)
                    {
                        entryIdMap[keyPlusLMTHash] = messageRec2;
                    }
                }
            }
            if (list5 == null)
            {
                MrsTracer.Service.Debug("ChangedSourceIds {0}, SourceMessages looked up is null", new object[]
                {
                    list.Count
                });
            }
            else
            {
                if (list5.Count != list.Count)
                {
                    MrsTracer.Service.Debug("ChangedSourceIds {0}, SourceMessages looked up {1}", new object[]
                    {
                        list.Count,
                        list5.Count
                    });
                }
                itemsToCopy = new List <MessageRec>();
                foreach (MessageRec messageRec3 in list5)
                {
                    string text;
                    if (FolderContentsMapper.ShouldItemBeIgnored(messageRec3, badItemMarkers, this.faiCopyOption, out text))
                    {
                        skippedItemCount++;
                    }
                    else
                    {
                        MessageRec messageRec4 = null;
                        this.MapSourceToTargetMessageBySourceEntryId(messageRec3, entryIdMap, out messageRec4);
                        if (!this.ShouldItemBeCopied(messageRec3, messageRec4, null))
                        {
                            skippedItemCount++;
                        }
                        else
                        {
                            if (messageRec4 == null)
                            {
                                messageRec3.Flags |= MsgRecFlags.New;
                            }
                            itemsToCopy.Add(messageRec3);
                            this.sourceMapping[messageRec3.EntryId] = messageRec3;
                        }
                    }
                }
            }
            if (list3.Count > 0)
            {
                deletedTargetEntryIDs = this.RemapSourceIDsToTargetIDs(list3);
            }
            if (folderChanges.ReadMessages != null && folderChanges.ReadMessages.Count > 0)
            {
                readTargetEntryIDs = this.RemapSourceIDsToTargetIDs(folderChanges.ReadMessages);
            }
            if (folderChanges.UnreadMessages != null && folderChanges.UnreadMessages.Count > 0)
            {
                unreadTargetEntryIDs = this.RemapSourceIDsToTargetIDs(folderChanges.UnreadMessages);
            }
        }