Ejemplo n.º 1
0
        public TType Apply(TType source, IDiff <TType> patch)
        {
            // ReSharper disable once PossibleInvalidCastExceptionInForeachLoop
            foreach (var item in patch.Cast <IDiffValue>())
            {
                switch (item)
                {
                case IDiffItemReplaced <TType> itemReplaced:
                    return(itemReplaced.NewValue);

                case IDiffItemChanged itemChanged:
                    Type  sourceType = source.GetType();
                    IDiff diff       = itemChanged.ValueDiff;
                    IApplyPatchAlgorithm algorithm;

                    if (!this.aTypes.TryGetValue(sourceType, out algorithm))
                    {
                        algorithm = this.aMergerImplementation.Partial.Algorithms.GetApplyPatchAlgorithm(sourceType, this.aRules);
                    }

                    return((TType)algorithm.Apply(source, diff));

                default:
                    throw new InvalidOperationException();
                }
            }

            return(source);
        }
        private TType ApplyInternal(IEnumerable <TItemType> source, IDiff <TType> patch)
        {
            HashSet <TItemType> ret = new HashSet <TItemType>(source, this.aItemComparer);

            foreach (var item in patch.Cast <IDiffUnorderedCollectionItem>())
            {
                switch (item)
                {
                case IDiffItemAdded <TItemType> itemAdded:
                    ret.Add(itemAdded.NewValue);
                    break;

                case IDiffItemRemoved <TItemType> itemRemoved:
                    ret.Remove(itemRemoved.OldValue);
                    break;

                case IDiffItemReplaced <TItemType> itemReplaced:
                    ret.Remove(itemReplaced.OldValue);
                    ret.Add(itemReplaced.NewValue);
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }

            return(this.aConvertor(ret));
        }
Ejemplo n.º 3
0
        public IDiff <TType> MergeDiffs(IDiff <TType> left, IDiff <TType> right, IConflictContainer conflicts)
        {
            if (this.aMergeItemsDiffs == null)
            {
                this.aMergeItemsDiffs = this.aMergerImplementation.Partial.Algorithms.GetMergeDiffsAlgorithm <TItemType>();
            }

            List <IDiffItem> ret = new List <IDiffItem>();

            foreach (var(leftItems, rightItems) in new MergeJoin(new Chunker(left.Cast <IDiffOrderedCollectionItem>()), new Chunker(right.Cast <IDiffOrderedCollectionItem>())))
            {
                if (leftItems == null)
                {
                    ret.AddRange(rightItems);
                }
                else if (rightItems == null)
                {
                    ret.AddRange(leftItems);
                }
                else
                {
                    this.ProcessConflicts(ret, leftItems, rightItems, conflicts);
                }
            }

            return(new Diff <TType>(ret));
        }
Ejemplo n.º 4
0
        private TType ApplyInternal(IEnumerable <TItemType> source, IDiff <TType> patch)
        {
            List <TItemType> ret = new List <TItemType>();

            using (IEnumerator <TItemType> enumerator = source.GetEnumerator())
            {
                bool lastMoveNext = enumerator.MoveNext();
                int  currentIndex = 0;

                foreach (var item in patch.Cast <IDiffOrderedCollectionItem>())
                {
                    while (currentIndex < item.ItemIndex)
                    {
                        ret.Add(enumerator.Current);
                        lastMoveNext = enumerator.MoveNext();
                        currentIndex++;
                    }

                    switch (item)
                    {
                    case IDiffItemAdded <TItemType> itemAdded:
                        ret.Add(itemAdded.NewValue);
                        break;

                    case IDiffItemChanged <TItemType> itemChanged:
                        ret.Add(this.aApplyItemDiff.Apply(enumerator.Current, itemChanged.ValueDiff));
                        lastMoveNext = enumerator.MoveNext();
                        currentIndex++;
                        break;

                    case IDiffItemRemoved <TItemType> _:
                        lastMoveNext = enumerator.MoveNext();
                        currentIndex++;
                        break;

                    case IDiffItemReplaced <TItemType> itemReplaced:
                        lastMoveNext = enumerator.MoveNext();
                        ret.Add(itemReplaced.NewValue);
                        currentIndex++;
                        break;

                    default:
                        throw new InvalidOperationException();
                    }
                }

                while (lastMoveNext)
                {
                    ret.Add(enumerator.Current);
                    lastMoveNext = enumerator.MoveNext();
                }
            }

            return(this.aConvertor(ret));
        }
        public IDiff <TType> MergeDiffs(IDiff <TType> left, IDiff <TType> right, IConflictContainer conflicts)
        {
            if (this.aIdAccessor == null)
            {
                if (this.aIdProperty == null)
                {
                    ParameterExpression obj = Expression.Parameter(typeof(TItemType), "obj");

                    Expression <Func <TItemType, TIdType> > identityFunction = Expression.Lambda <Func <TItemType, TIdType> >(
                        obj, obj
                        );

                    this.aIdAccessor = identityFunction.Compile();
                }
                else
                {
                    this.aIdAccessor = IdHelpers.CreateIdAccessor <TItemType, TIdType>(this.aIdProperty);
                }

                this.aMergeItemsDiffs = this.aMergerImplementation.Partial.Algorithms.GetMergeDiffsAlgorithm <TItemType>();
            }

            Dictionary <TIdType, IDiffUnorderedCollectionItem> rightIndex = new Dictionary <TIdType, IDiffUnorderedCollectionItem>(right.Count);

            foreach (IDiffItem item in right)
            {
                rightIndex[this.GetID(item)] = (IDiffUnorderedCollectionItem)item;
            }

            List <IDiffItem> ret = new List <IDiffItem>(left.Count + right.Count);

            foreach (var leftItem in left.Cast <IDiffUnorderedCollectionItem>())
            {
                IDiffUnorderedCollectionItem rightItem;

                TIdType id = this.GetID(leftItem);

                if (rightIndex.TryGetValue(id, out rightItem))
                {
                    rightIndex.Remove(id);

                    this.ProcessConflict(id, leftItem, rightItem, ret, conflicts);
                }
                else
                {
                    ret.Add(leftItem);
                }
            }

            ret.AddRange(rightIndex.Values);

            return(new Diff <TType>(ret));
        }
Ejemplo n.º 6
0
        private TType ApplyInternal(IEnumerable <KeyValuePair <TKeyType, TItemType> > source, IDiff <TType> patch)
        {
            Dictionary <TKeyType, TItemType> ret = new Dictionary <TKeyType, TItemType>();

            foreach (KeyValuePair <TKeyType, TItemType> item in source)
            {
                ret[item.Key] = item.Value;
            }

            foreach (var item in patch.Cast <IDiffKeyValueCollectionItem <TKeyType> >())
            {
                switch (item)
                {
                case IDiffItemAdded <TItemType> itemAdded:
                    ret[item.Key] = itemAdded.NewValue;
                    break;

                case IDiffItemChanged <TItemType> itemChanged:
                    ret[item.Key] = this.aApplyItemDiff.Apply(ret[item.Key], itemChanged.ValueDiff);
                    break;

                case IDiffItemRemoved <TItemType> _:
                    ret.Remove(item.Key);
                    break;

                case IDiffItemReplaced <TItemType> itemReplaced:
                    ret[item.Key] = itemReplaced.NewValue;
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }

            return(this.aConvertor(ret));
        }
Ejemplo n.º 7
0
        public IDiff <TType> MergeDiffs(IDiff <TType> left, IDiff <TType> right, IConflictContainer conflicts)
        {
            if (this.aMergeItemsDiffs == null)
            {
                this.aMergeItemsDiffs = this.aMergerImplementation.Partial.Algorithms.GetMergeDiffsAlgorithm <TItemType>();
            }

            Dictionary <TKeyType, IDiffKeyValueCollectionItem <TKeyType> > rightIndex = new Dictionary <TKeyType, IDiffKeyValueCollectionItem <TKeyType> >(right.Count);

            foreach (IDiffItem item in right)
            {
                rightIndex[((IDiffKeyValueCollectionItem <TKeyType>)item).Key] = (IDiffKeyValueCollectionItem <TKeyType>)item;
            }

            List <IDiffItem> ret = new List <IDiffItem>(left.Count + right.Count);

            foreach (var leftItem in left.Cast <IDiffKeyValueCollectionItem <TKeyType> >())
            {
                IDiffKeyValueCollectionItem <TKeyType> rightItem;

                if (rightIndex.TryGetValue(leftItem.Key, out rightItem))
                {
                    rightIndex.Remove(leftItem.Key);

                    this.ProcessConflict(leftItem.Key, leftItem, rightItem, ret, conflicts);
                }
                else
                {
                    ret.Add(leftItem);
                }
            }

            ret.AddRange(rightIndex.Values);

            return(new Diff <TType>(ret));
        }
        private TType ApplyInternal(IEnumerable <TItemType> source, IDiff <TType> patch)
        {
            Dictionary <TIdType, TItemType> ret = source.ToDictionary(this.aIdAccessor);

            foreach (var item in patch.Cast <IDiffUnorderedCollectionItem>())
            {
                switch (item)
                {
                case IDiffItemAdded <TItemType> itemAdded:
                {
                    TIdType id;
                    if (itemAdded is IDiffUnorderedCollectionItemWithID <TIdType> itemWithID)
                    {
                        id = itemWithID.Id;
                    }
                    else
                    {
                        id = this.aIdAccessor(itemAdded.NewValue);
                    }

                    ret[id] = itemAdded.NewValue;
                    break;
                }

                case IDiffItemRemoved <TItemType> itemRemoved:
                {
                    TIdType id;
                    if (itemRemoved is IDiffUnorderedCollectionItemWithID <TIdType> itemWithID)
                    {
                        id = itemWithID.Id;
                    }
                    else
                    {
                        id = this.aIdAccessor(itemRemoved.OldValue);
                    }

                    ret.Remove(id);
                    break;
                }

                case IDiffItemReplaced <TItemType> itemReplaced:
                {
                    TIdType idOld;
                    TIdType idNew;
                    if (itemReplaced is IDiffUnorderedCollectionItemWithID <TIdType> itemWithID)
                    {
                        idNew = idOld = itemWithID.Id;
                    }
                    else
                    {
                        idOld = this.aIdAccessor(itemReplaced.OldValue);
                        idNew = this.aIdAccessor(itemReplaced.NewValue);
                    }

                    ret.Remove(idOld);
                    ret[idNew] = itemReplaced.NewValue;
                    break;
                }

                case IDiffItemChanged <TItemType> itemChanged:
                {
                    TIdType id = ((IDiffUnorderedCollectionItemWithID <TIdType>)itemChanged).Id;

                    ret[id] = this.aApplyItemDiff.Apply(ret[id], itemChanged.ValueDiff);
                    break;
                }

                default:
                    throw new InvalidOperationException();
                }
            }

            return(this.aConvertor(ret.Values));
        }