Exemplo n.º 1
0
        private void RegisterBase(XElement basis, ref int trgid, XElement e, ConcurrentDictionary <int, EndpointPack> trg,
                                  ConcurrentDictionary <string, InterPack> idinter,
                                  ConcurrentDictionary <string, InterPack> codeinter)
        {
            int    id    = Interlocked.Increment(ref trgid);
            var    key   = new XDiffKey(_options, e);
            string _id   = _options.IsNameIndepended ? key.Id : (key.Name + "_" + key.Id);
            string _code = _options.IsNameIndepended ? key.Code : (key.Name + "_" + key.Code);

            if (_options.IsHierarchy)
            {
                SetupParentAttribute(basis, e);
            }
            var ep = new EndpointPack {
                Key = key, Element = e, Bag = new ConcurrentBag <XElement>()
            };

            trg[id] = ep;

            if (!string.IsNullOrWhiteSpace(key.Id))
            {
                idinter.AddOrUpdate(_id, _ => new InterPack {
                    Target = ep
                }, (k, _) => {
                    if (null != _.Target)
                    {
                        throw new Exception("double id match in trg " + _.Target.Key);
                    }
                    _.Target = ep;
                    ConcurrentBag <XElement> _bag = _.Source.Bag;
                    _.Source.Bag = ep.Bag;
                    foreach (XElement c in _bag)
                    {
                        ep.Bag.Add(c);
                    }

                    ep.IsBound       = true;
                    _.Source.IsBound = true;
                    return(_);
                });
            }
            if (!string.IsNullOrWhiteSpace(key.Code))
            {
                codeinter.AddOrUpdate(_code, _ => new InterPack {
                    Target = ep
                }, (k, _) => {
                    if (null != _.Target)
                    {
                        throw new Exception("double code match in trg " + _.Target.Key);
                    }
                    _.Target = ep;
                    if (_.Source.Bag != ep.Bag)
                    {
                        ConcurrentBag <XElement> _bag = _.Source.Bag;
                        _.Source.Bag = ep.Bag;
                        foreach (XElement c in _bag)
                        {
                            ep.Bag.Add(c);
                        }
                    }
                    ep.IsBound       = true;
                    _.Source.IsBound = true;
                    return(_);
                });
            }
            return;
        }
Exemplo n.º 2
0
        private void RegisterDelta(XElement newest, ref int srcid, XElement e, ConcurrentDictionary <int, EndpointPack> src,
                                   ConcurrentDictionary <string, InterPack> idinter,
                                   ConcurrentDictionary <string, InterPack> codeinter)
        {
            int    id    = Interlocked.Increment(ref srcid);
            var    key   = new XDiffKey(_options, e);
            string _id   = _options.IsNameIndepended ? key.Id : (key.Name + "_" + key.Id);
            string _code = _options.IsNameIndepended ? key.Code : (key.Name + "_" + key.Code);

            if (_options.IsHierarchy)
            {
                SetupParentAttribute(newest, e);
            }
            var ep = new EndpointPack {
                Key = key, Element = e, Bag = new ConcurrentBag <XElement>()
            };

            ep.Bag.Add(e);
            src[id] = ep;
            EndpointPack _idpack = null;
            EndpointPack _idtrg  = null;

            if (!string.IsNullOrWhiteSpace(key.Id) && 0 != key.Id.ToInt())
            {
                idinter.AddOrUpdate(_id, _ => new InterPack {
                    Source = _idpack = ep
                }, (k, _) => {
                    if (null != _.Source)
                    {
                        _idpack = _.Source;                         //it's not problem if same as code binding
                        _.Source.Bag.Add(e);
                        ep.IsBound = true;
                    }
                    else
                    {
                        _.Source         = ep;
                        _idpack          = _.Source;
                        _.Source.Bag     = _.Target.Bag;
                        _.Target.IsBound = true;
                        _idtrg           = _.Target;
                        ep.IsBound       = true;
                        _.Target.Bag.Add(ep.Element);
                    }
                    return(_);
                });
            }


            if (!string.IsNullOrWhiteSpace(key.Code))
            {
                codeinter.AddOrUpdate(_code, _ => {
                    if (null != _idpack && _idpack != ep)
                    {
                        throw new Exception("ambigous source (1)" + ep.Key);
                    }
                    if (null != _idtrg)
                    {
                        throw new Exception("ambigous source (2)" + ep.Key);
                    }
                    return(new InterPack {
                        Source = ep
                    });
                }, (k, _) => {
                    if (_.Source != null && _idpack != null && _.Source != _idpack)
                    {
                        throw new Exception("ambigous source (3)" + ep.Key);
                    }
                    if (null != _idtrg && _idtrg != _.Target)
                    {
                        throw new Exception("ambigous source (4)" + ep.Key);
                    }
                    if (null != _.Source)
                    {
                        _.Source.Bag.Add(e);
                        ep.IsBound = true;
                    }
                    else
                    {
                        _.Source         = ep;
                        _.Source.Bag     = _.Target.Bag;
                        _.Target.IsBound = true;
                        ep.IsBound       = true;
                        _.Target.Bag.Add(ep.Element);
                    }
                    return(_);
                });
            }
        }