Пример #1
0
        internal ResolvedAttributeSet Merge(ResolvedAttribute toMerge, CdmAttributeContext attCtx = null)
        {
            ResolvedAttributeSet rasResult = this;

            if (toMerge != null)
            {
                if (rasResult.ResolvedName2resolvedAttribute.ContainsKey(toMerge.ResolvedName))
                {
                    ResolvedAttribute existing = rasResult.ResolvedName2resolvedAttribute[toMerge.ResolvedName];
                    if (this.RefCnt > 1 && existing.Target != toMerge.Target)
                    {
                        rasResult = rasResult.Copy(); // copy on write
                        existing  = rasResult.ResolvedName2resolvedAttribute[toMerge.ResolvedName];
                    }
                    existing.Target = toMerge.Target; // replace with newest version
                    existing.Arc    = toMerge.Arc;

                    ResolvedTraitSet rtsMerge = existing.ResolvedTraits.MergeSet(toMerge.ResolvedTraits); // newest one may replace
                    if (rtsMerge != existing.ResolvedTraits)
                    {
                        rasResult = rasResult.Copy(); // copy on write
                        existing  = rasResult.ResolvedName2resolvedAttribute[toMerge.ResolvedName];
                        existing.ResolvedTraits = rtsMerge;
                    }
                }
                else
                {
                    if (this.RefCnt > 1)
                    {
                        rasResult = rasResult.Copy(); // copy on write
                    }
                    if (rasResult == null)
                    {
                        rasResult = this;
                    }
                    rasResult.ResolvedName2resolvedAttribute.Add(toMerge.ResolvedName, toMerge);
                    // don't use the attCtx on the actual attribute, that's only for doing appliers
                    if (attCtx != null)
                    {
                        rasResult.CacheAttributeContext(attCtx, toMerge);
                    }
                    //toMerge.InsertOrder = rasResult.Set.Count;
                    rasResult.Set.Add(toMerge);
                }
                this.BaseTrait2Attributes = null;
            }
            return(rasResult);
        }
Пример #2
0
        internal ResolvedAttributeSet Merge(ResolvedAttribute toMerge, CdmAttributeContext attCtx = null)
        {
            ResolvedAttributeSet rasResult = this;

            if (toMerge != null)
            {
                // if there is already a resolve attribute present, remove it before adding the new attribute
                if (rasResult.ResolvedName2resolvedAttribute.ContainsKey(toMerge.ResolvedName))
                {
                    ResolvedAttribute existing = rasResult.ResolvedName2resolvedAttribute[toMerge.ResolvedName];
                    if (this.RefCnt > 1 && existing.Target != toMerge.Target)
                    {
                        rasResult = rasResult.Copy(); // copy on write
                        existing  = rasResult.ResolvedName2resolvedAttribute[toMerge.ResolvedName];
                    }
                    else
                    {
                        rasResult = this;
                    }

                    if (existing.Target is CdmAttribute)
                    {
                        rasResult.ResolvedAttributeCount -= existing.Target.AttributeCount;
                    }
                    else if (existing.Target is ResolvedAttributeSet)
                    {
                        rasResult.ResolvedAttributeCount -= existing.Target.ResolvedAttributeCount;
                    }

                    if (toMerge.Target is CdmAttribute)
                    {
                        rasResult.ResolvedAttributeCount += toMerge.Target.AttributeCount;
                    }
                    else if (toMerge.Target is ResolvedAttributeSet)
                    {
                        rasResult.ResolvedAttributeCount += toMerge.Target.ResolvedAttributeCount;
                    }

                    existing.Target = toMerge.Target; // replace with newest version
                    existing.Arc    = toMerge.Arc;

                    // Replace old context mappings with mappings to new attribute
                    rasResult.RemoveCachedAttributeContext(existing.AttCtx);
                    rasResult.CacheAttributeContext(attCtx, existing);

                    ResolvedTraitSet rtsMerge = existing.ResolvedTraits.MergeSet(toMerge.ResolvedTraits); // newest one may replace
                    if (rtsMerge != existing.ResolvedTraits)
                    {
                        rasResult = rasResult.Copy(); // copy on write
                        existing  = rasResult.ResolvedName2resolvedAttribute[toMerge.ResolvedName];
                        existing.ResolvedTraits = rtsMerge;
                    }
                }
                else
                {
                    if (this.RefCnt > 1)
                    {
                        rasResult = rasResult.Copy(); // copy on write
                    }
                    if (rasResult == null)
                    {
                        rasResult = this;
                    }
                    rasResult.ResolvedName2resolvedAttribute.Add(toMerge.ResolvedName, toMerge);
                    // don't use the attCtx on the actual attribute, that's only for doing appliers
                    if (attCtx != null)
                    {
                        rasResult.CacheAttributeContext(attCtx, toMerge);
                    }
                    //toMerge.InsertOrder = rasResult.Set.Count;
                    rasResult.Set.Add(toMerge);
                    rasResult.ResolvedAttributeCount += toMerge.ResolvedAttributeCount;
                }
                this.BaseTrait2Attributes = null;
            }
            return(rasResult);
        }