Exemple #1
0
        private ChangesCollection CollectChanges()
        {
            if (_changes == null)
            {
                var target  = Target;
                var added   = new HashSet <Item>();
                var deleted = new HashSet <Item>();
                var delta   = new List <Delta>();
                var keys    = new Dictionary <string, ChangeKey>();

                _changes = new ChangesCollection
                {
                    Added   = added,
                    Deleted = deleted,
                    Delta   = delta,
                    Keys    = keys
                };

                if (!Transaction.Changed.TryGetValue(Target, out var changed))
                {
                    changed = new HashSet <string>();
                    Transaction.Changed[Target] = changed;
                }

                if (changed.Contains(null))
                {
                    Delta lastOp = null;

                    void packOp()
                    {
                        if (lastOp != null)
                        {
                            delta.Add(lastOp);
                        }
                    }

                    for (var item = Target._start; item != null; item = item.Right as Item)
                    {
                        if (item.Deleted)
                        {
                            if (Deletes(item) && !Adds(item))
                            {
                                if (lastOp == null || lastOp.Delete == null)
                                {
                                    packOp();
                                    lastOp = new Delta {
                                        Delete = 0
                                    };
                                }

                                lastOp.Delete += item.Length;
                                deleted.Add(item);
                            }
                            else
                            {
                                // Do nothing.
                            }
                        }
                        else
                        {
                            if (Adds(item))
                            {
                                if (lastOp == null || lastOp.Insert == null)
                                {
                                    packOp();
                                    lastOp = new Delta {
                                        Insert = new List <object>(1)
                                    };
                                }

                                (lastOp.Insert as List <object>).AddRange(item.Content.GetContent());
                                added.Add(item);
                            }
                            else
                            {
                                if (lastOp == null || lastOp.Retain == null)
                                {
                                    packOp();
                                    lastOp = new Delta {
                                        Retain = 0
                                    };
                                }

                                lastOp.Retain += item.Length;
                            }
                        }
                    }

                    if (lastOp != null && lastOp.Retain == null)
                    {
                        packOp();
                    }
                }

                foreach (var key in changed)
                {
                    if (key != null)
                    {
                        ChangeAction action;
                        object       oldValue;
                        var          item = target._map[key];

                        if (Adds(item))
                        {
                            var prev = item.Left;
                            while (prev != null && Adds(prev))
                            {
                                prev = (prev as Item).Left;
                            }

                            if (Deletes(item))
                            {
                                if (prev != null && Deletes(prev))
                                {
                                    action   = ChangeAction.Delete;
                                    oldValue = (prev as Item).Content.GetContent().Last();
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else
                            {
                                if (prev != null && Deletes(prev))
                                {
                                    action   = ChangeAction.Update;
                                    oldValue = (prev as Item).Content.GetContent().Last();
                                }
                                else
                                {
                                    action   = ChangeAction.Add;
                                    oldValue = null;
                                }
                            }
                        }
                        else
                        {
                            if (Deletes(item))
                            {
                                action   = ChangeAction.Delete;
                                oldValue = item.Content.GetContent().Last();
                            }
                            else
                            {
                                break;
                            }
                        }

                        keys[key] = new ChangeKey {
                            Action = action, OldValue = oldValue
                        };
                    }
                }
            }

            return(_changes);
        }
Exemple #2
0
        public void TestChangeEvent()
        {
            Init(users: 2);
            var map0 = Maps[Users[0]];

            ChangesCollection changes   = null;
            ChangeKey         keyChange = null;

            map0.EventHandler += (s, e) =>
            {
                changes = e.Event.Changes;
            };

            map0.Set("a", 1);
            Assert.IsTrue(changes.Keys.TryGetValue("a", out keyChange));
            Assert.AreEqual(ChangeAction.Add, keyChange.Action);
            Assert.IsNull(keyChange.OldValue);
            changes = null;

            map0.Set("a", 2);
            Assert.IsTrue(changes.Keys.TryGetValue("a", out keyChange));
            Assert.AreEqual(ChangeAction.Update, keyChange.Action);
            Assert.AreEqual(1, keyChange.OldValue);
            changes = null;

            Users[0].Transact(tr =>
            {
                map0.Set("a", 3);
                map0.Set("a", 4);
            });

            Assert.IsTrue(changes.Keys.TryGetValue("a", out keyChange));
            Assert.AreEqual(ChangeAction.Update, keyChange.Action);
            Assert.AreEqual(2, keyChange.OldValue);
            changes = null;

            Users[0].Transact(tr =>
            {
                map0.Set("b", 1);
                map0.Set("b", 2);
            });

            Assert.IsTrue(changes.Keys.TryGetValue("b", out keyChange));
            Assert.AreEqual(ChangeAction.Add, keyChange.Action);
            Assert.IsNull(keyChange.OldValue);
            changes = null;

            Users[0].Transact(tr =>
            {
                map0.Set("c", 1);
                map0.Delete("c");
            });

            Assert.AreEqual(0, changes.Keys.Count);
            changes = null;

            Users[0].Transact(tr =>
            {
                map0.Set("d", 1);
                map0.Set("d", 2);
            });

            Assert.IsTrue(changes.Keys.TryGetValue("d", out keyChange));
            Assert.AreEqual(ChangeAction.Add, keyChange.Action);
            Assert.IsNull(keyChange.OldValue);
            changes = null;

            CompareUsers();
        }