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 void ApplyFolderChanges(SyncContext ctx, FolderChangesManifest folderChanges, FolderMapping fm, ISourceFolder srcFolder, IDestinationFolder destFolder) { int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; FolderContentsMapper folderContentsMapper = FolderContentsMapper.Create(fm, srcFolder, this.SourceHierarchy, destFolder, this.DestHierarchy, base.MRSJob.CachedRequestJob.ConflictResolutionOption ?? ConflictResolutionOption.KeepSourceItem, base.MRSJob.CachedRequestJob.AssociatedMessagesCopyOption ?? FAICopyOption.DoNotCopy, (base.MRSJob.CachedRequestJob.SyncProtocol == SyncProtocol.Imap) ? FolderContentsMapperFlags.ImapSync : FolderContentsMapperFlags.None); List <MessageRec> list; byte[][] array; byte[][] array2; byte[][] array3; int skipped; folderContentsMapper.ComputeIncrementalMapping(folderChanges, (base.SyncState == null) ? null : base.SyncState.BadItems, out list, out array, out array2, out array3, out skipped); this.CopyMessageBatch(folderContentsMapper, list, fm); destFolder.DeleteMessages(array); destFolder.SetReadFlagsOnMessages(SetReadFlags.None, array2); destFolder.SetReadFlagsOnMessages(SetReadFlags.ClearRead, array3); if (list != null) { foreach (MessageRec messageRec in list) { if (messageRec.IsNew) { num++; } else { num2++; } } } if (array != null) { num3 += array.Length; } if (array2 != null) { num4 += array2.Length; } if (array3 != null) { num5 += array3.Length; } ctx.CopyMessagesCount += new CopyMessagesCount(num, num2, num3, num4, num5, skipped); }
protected virtual bool ShouldItemBeCopied(MessageRec sourceMR, MessageRec targetMR, HashSet <byte[]> duplicateTargetSecondaryKeys) { if (targetMR == null) { return(true); } if (!sourceMR.IsFAI && this.conflictResolutionOption == ConflictResolutionOption.KeepAll) { return(false); } DateTime dateTimeValue = FolderContentsMapper.GetDateTimeValue(sourceMR, PropTag.LastModificationTime); DateTime dateTimeValue2 = FolderContentsMapper.GetDateTimeValue(targetMR, this.destHierarchy.SourceLastModifiedTimestampPtag); DateTime dateTimeValue3 = FolderContentsMapper.GetDateTimeValue(targetMR, PropTag.LastModificationTime); return(dateTimeValue != dateTimeValue2 && (this.conflictResolutionOption != ConflictResolutionOption.KeepLatestItem || !(dateTimeValue <= dateTimeValue3))); }
private byte[] GetKeyPlusLMTHash(MessageRec mr, PropTag keyPtag, PropTag lmtPtag) { byte[] array = ((keyPtag == PropTag.EntryId) ? mr.EntryId : mr[keyPtag]) as byte[]; if (array == null) { return(null); } if (this.conflictResolutionOption != ConflictResolutionOption.KeepAll) { return(array); } byte[] bytes = BitConverter.GetBytes(FolderContentsMapper.GetDateTimeValue(mr, lmtPtag).ToBinary()); byte[] array2 = new byte[array.Length + bytes.Length]; array.CopyTo(array2, 0); bytes.CopyTo(array2, array.Length); return(array2); }
public void MergeFolderContentsPaged(FolderMapping folder, FolderContentsCrawler sourceFolderCrawler, IDestinationFolder destFolder, TimeSpan maxOperationDuration) { MrsTracer.Service.Function("MailboxMerger.MergeFolderContentsPaged({0})", new object[] { folder.FullFolderName }); ISourceFolder wrappedObject = sourceFolderCrawler.WrappedObject; if (this.ContentRestriction != null) { wrappedObject.SetContentsRestriction(this.ContentRestriction); } FolderContentsMapper folderContentsMapper = FolderContentsMapper.Create(folder, wrappedObject, this.SourceHierarchy, destFolder, this.DestHierarchy, this.GetConflictResolutionOption(folder), base.MRSJob.CachedRequestJob.AssociatedMessagesCopyOption ?? FAICopyOption.DoNotCopy, (base.MRSJob.CachedRequestJob.SyncProtocol == SyncProtocol.Imap) ? FolderContentsMapperFlags.ImapSync : FolderContentsMapperFlags.None); DateTime utcNow = DateTime.UtcNow; int alreadyCopiedCount; ulong alreadyCopiedSize; List <MessageRec> itemsToCopy; List <MessageRec> list; while (folderContentsMapper.ComputeMappingPaged(sourceFolderCrawler, (base.SyncState == null) ? null : base.SyncState.BadItems, out alreadyCopiedCount, out alreadyCopiedSize, out itemsToCopy, out list)) { SyncProtocol syncProtocol = base.MRSJob.CachedRequestJob.SyncProtocol; foreach (MessageRec messageRec in list) { destFolder.SetMessageProps(messageRec.EntryId, messageRec.AdditionalProps); } base.MailboxSizeTracker.TrackFolder(folder.EntryId, sourceFolderCrawler.TotalMessageCount, alreadyCopiedCount, alreadyCopiedSize); base.MRSJob.MessagesWritten += base.MailboxSizeTracker.AlreadyCopiedCount; base.MRSJob.MessageSizeWritten += base.MailboxSizeTracker.AlreadyCopiedSize; base.MRSJob.TotalMessages = base.MailboxSizeTracker.MessageCount; base.MRSJob.TotalMessageByteSize = base.MailboxSizeTracker.TotalMessageSize; this.CopyMessageBatch(folderContentsMapper, itemsToCopy, folder); DateTime utcNow2 = DateTime.UtcNow; if (utcNow2 - utcNow >= maxOperationDuration) { MrsTracer.Service.Debug("MergeFolderContentsPaged times out for assigned duration {0}. Start:{1}, End:{2}", new object[] { maxOperationDuration, utcNow, utcNow2 }); return; } } }
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 MergeFolderContents(FolderMapping fm, ISourceFolder srcFolder, IDestinationFolder destFolder) { MrsTracer.Service.Function("MailboxMerger.MergeFolderContents({0})", new object[] { fm.FullFolderName }); if (this.ContentRestriction != null) { srcFolder.SetContentsRestriction(this.ContentRestriction); } FolderContentsMapper folderContentsMapper = FolderContentsMapper.Create(fm, srcFolder, this.SourceHierarchy, destFolder, this.DestHierarchy, this.GetConflictResolutionOption(fm), base.MRSJob.CachedRequestJob.AssociatedMessagesCopyOption ?? FAICopyOption.DoNotCopy, (base.MRSJob.CachedRequestJob.SyncProtocol == SyncProtocol.Imap) ? FolderContentsMapperFlags.ImapSync : FolderContentsMapperFlags.None); int num; ulong num2; List <MessageRec> list; List <MessageRec> list2; folderContentsMapper.ComputeMapping((base.SyncState == null) ? null : base.SyncState.BadItems, out num, out num2, out list, out list2); SyncProtocol syncProtocol = base.MRSJob.CachedRequestJob.SyncProtocol; foreach (MessageRec messageRec in list2) { destFolder.SetMessageProps(messageRec.EntryId, messageRec.AdditionalProps); } base.MailboxSizeTracker.TrackFolder(fm.EntryId, list, num, num2); int num3; ulong num4; base.MailboxSizeTracker.GetFolderSize(fm.EntryId, out num3, out num4); base.Report.Append(MrsStrings.ReportFolderMergeStats(num3 - num, new ByteQuantifiedSize(num4 - num2).ToString(), num, new ByteQuantifiedSize(num2).ToString())); base.MRSJob.TotalMessages = base.MailboxSizeTracker.MessageCount; base.MRSJob.TotalMessageByteSize = base.MailboxSizeTracker.TotalMessageSize; base.MRSJob.MessagesWritten = base.MailboxSizeTracker.AlreadyCopiedCount; base.MRSJob.MessageSizeWritten = base.MailboxSizeTracker.AlreadyCopiedSize; this.CopyMessageBatch(folderContentsMapper, list, fm); base.MailboxSizeTracker.TrackFolder(fm.EntryId, null, num3, num4); }
private void CopyMessageBatch(FolderContentsMapper mapper, List <MessageRec> itemsToCopy, FolderMapping fm) { if (itemsToCopy == null || itemsToCopy.Count == 0) { return; } MrsTracer.Service.Debug("Sorting {0} messages in folder '{1}'", new object[] { itemsToCopy.Count, fm.FullFolderName }); MessageRecSorter messageRecSorter = new MessageRecSorter(); Queue <List <MessageRec> > queue = messageRecSorter.Sort(itemsToCopy, (base.MRSJob.CachedRequestJob.SyncProtocol == SyncProtocol.Imap) ? MessageRecSortBy.SkipSort : MessageRecSortBy.DescendingTimeStamp); byte[][] folderIDs = new byte[][] { fm.TargetFolder.EntryId }; while (queue.Count > 0) { base.MRSJob.CheckServersHealth(); List <MessageRec> list = queue.Dequeue(); ulong num = 0UL; foreach (MessageRec messageRec in list) { num += (ulong)((long)messageRec.MessageSize); } MrsTracer.Service.Debug("Copying a batch of {0} messages, {1}", new object[] { list.Count, new ByteQuantifiedSize(num) }); List <BadMessageRec> list2 = new List <BadMessageRec>(); MapiUtils.ExportMessagesWithBadItemDetection(base.SourceMailbox, list, delegate { IFxProxyPool fxProxyPool = this.DestMailbox.GetFxProxyPool(folderIDs); IFxProxyPool fxProxyTransformer = mapper.GetFxProxyTransformer(fxProxyPool); return(this.CreateFxProxyPoolTransmissionPipeline(fxProxyTransformer)); }, ExportMessagesFlags.OneByOne, ((base.Flags & MailboxCopierFlags.TargetIsPST) != MailboxCopierFlags.None) ? MailboxCopierBase.PSTIncludeMessagePtags : null, null, base.MRSJob.TestIntegration, ref list2); if (list2 != null && list2.Count > 0) { List <BadMessageRec> list3 = new List <BadMessageRec>(); foreach (BadMessageRec badMessageRec in list2) { if (badMessageRec.Kind == BadItemKind.MissingItem) { MrsTracer.Service.Warning("Message {0} is missing in source, skipping.", new object[] { TraceUtils.DumpEntryId(badMessageRec.EntryId) }); } else { list3.Add(badMessageRec); } } this.ReportBadItems(list3); } if (base.MRSJob.TestIntegration.LogContentDetails) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(string.Format("CopyMessageBatch: {0} items copied", list.Count)); foreach (MessageRec messageRec2 in list) { stringBuilder.AppendLine(string.Format("ItemID {0}, FolderID {1}{2}", TraceUtils.DumpEntryId(messageRec2.EntryId), TraceUtils.DumpEntryId(messageRec2.FolderId), messageRec2.IsFAI ? ", FAI" : string.Empty)); } base.MRSJob.Report.AppendDebug(stringBuilder.ToString()); } base.MRSJob.MessagesWritten += list.Count; base.MRSJob.MessageSizeWritten += num; base.MRSJob.ProgressTracker.AddItems((uint)list.Count); SaveStateFlags saveStateFlags = SaveStateFlags.Lazy; if (num > 0UL) { base.UpdateTimestampWhenPersistentProgressWasMade(); saveStateFlags |= SaveStateFlags.RelinquishLongRunningJob; } base.MRSJob.SaveState(saveStateFlags, null); } }
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 TranslatingMessageProxy(IMessageProxy destMessage, PropValueData[] dataToSetOnSave, FolderContentsMapper mapper) : base(destMessage, mapper) { this.dataToSetOnSave = dataToSetOnSave; }
public TranslatingFolderProxy(FolderContentsMapper.TranslatingProxyPool owner, IFolderProxy destFolder, FolderContentsMapper mapper) : base(destFolder, mapper) { this.owner = owner; }
public TranslatingEntryProxy(IMapiFxProxyEx destProxy, FolderContentsMapper mapper) : base(destProxy, true) { this.mapper = mapper; }
public TranslatingProxyPool(FolderContentsMapper mapper, IFxProxyPool destination) : base(destination, true) { this.mapper = mapper; this.uploadedSourceIDs = new List <byte[]>(); }
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); } }