Esempio n. 1
0
        /// <summary>
        /// Returns a list of references that match the direction and reference type.
        /// </summary>
        /// <param name="referenceTypeId">The reference type identifier.</param>
        /// <param name="isInverse">if set to <c>true</c> this is inverse reference.</param>
        /// <returns>A list of references that match the direction and reference type.</returns>
        public IList <IReference> Find(
            NodeId referenceTypeId,
            bool isInverse)
        {
            List <IReference> hits = new List <IReference>();

            // check for null.
            if (NodeId.IsNull(referenceTypeId))
            {
                return(hits);
            }

            // look up the reference type.
            ReferenceTypeEntry entry = null;

            if (!m_references.TryGetValue(referenceTypeId, out entry))
            {
                return(hits);
            }

            // find the references.
            Find(entry, isInverse, hits);

            return(hits);
        }
Esempio n. 2
0
        /// <summary>
        /// Checks the isInverse flag are returns true if a specified target exists.
        /// </summary>
        /// <param name="entry">The entry.</param>
        /// <param name="reference">The reference.</param>
        /// <returns>
        ///     <c>true</c> if the specified entry contains key; otherwise, <c>false</c>.
        /// </returns>
        private static bool ContainsKey(ReferenceTypeEntry entry, IReference reference)
        {
            // handle reference to external targets.
            if (reference.TargetId.IsAbsolute)
            {
                Dictionary <ExpandedNodeId, LinkedListNode <KeyValuePair <IReference, T> > > targets = null;

                if (reference.IsInverse)
                {
                    targets = entry.InverseExternalTargets;
                }
                else
                {
                    targets = entry.ForwardExternalTargets;
                }

                if (targets == null)
                {
                    return(false);
                }

                return(targets.ContainsKey(reference.TargetId));
            }

            // handle reference to internal target.
            else
            {
                NodeIdDictionary <LinkedListNode <KeyValuePair <IReference, T> > > targets = null;

                if (reference.IsInverse)
                {
                    targets = entry.InverseTargets;
                }
                else
                {
                    targets = entry.ForwardTargets;
                }

                if (targets == null)
                {
                    return(false);
                }

                return(targets.ContainsKey((NodeId)reference.TargetId));
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Add references to a list that match the criteria.
        /// </summary>
        /// <param name="entry">The entry.</param>
        /// <param name="isInverse">if set to <c>true</c> this is inverse reference.</param>
        /// <param name="hits">The hits.</param>
        private static void Find(
            ReferenceTypeEntry entry,
            bool isInverse,
            List <IReference> hits)
        {
            if (isInverse)
            {
                if (entry.InverseTargets != null)
                {
                    foreach (LinkedListNode <KeyValuePair <IReference, T> > target in entry.InverseTargets.Values)
                    {
                        hits.Add(target.Value.Key);
                    }
                }

                if (entry.InverseExternalTargets != null)
                {
                    foreach (LinkedListNode <KeyValuePair <IReference, T> > target in entry.InverseExternalTargets.Values
                             )
                    {
                        hits.Add(target.Value.Key);
                    }
                }
            }
            else
            {
                if (entry.ForwardTargets != null)
                {
                    foreach (LinkedListNode <KeyValuePair <IReference, T> > target in entry.ForwardTargets.Values)
                    {
                        hits.Add(target.Value.Key);
                    }
                }

                if (entry.ForwardExternalTargets != null)
                {
                    foreach (LinkedListNode <KeyValuePair <IReference, T> > target in entry.ForwardExternalTargets.Values
                             )
                    {
                        hits.Add(target.Value.Key);
                    }
                }
            }
        }
Esempio n. 4
0
        /// <summary cref="IDictionary.Remove" />
        public bool Remove(IReference key)
        {
            // validate key.
            if (!ValidateReference(key, false))
            {
                return(false);
            }

            m_version++;

            // look up the reference type.
            ReferenceTypeEntry entry = null;

            if (!m_references.TryGetValue(key.ReferenceTypeId, out entry))
            {
                return(false);
            }

            // handle reference to external targets.
            if (key.TargetId.IsAbsolute)
            {
                Dictionary <ExpandedNodeId, LinkedListNode <KeyValuePair <IReference, T> > > targets = null;

                if (key.IsInverse)
                {
                    targets = entry.InverseExternalTargets;
                }
                else
                {
                    targets = entry.ForwardExternalTargets;
                }

                if (targets == null)
                {
                    return(false);
                }

                LinkedListNode <KeyValuePair <IReference, T> > node;

                if (!targets.TryGetValue(key.TargetId, out node))
                {
                    return(false);
                }

                m_list.Remove(node);
                targets.Remove(key.TargetId);
            }

            // handle reference to internal target.
            else
            {
                NodeIdDictionary <LinkedListNode <KeyValuePair <IReference, T> > > targets = null;

                if (key.IsInverse)
                {
                    targets = entry.InverseTargets;
                }
                else
                {
                    targets = entry.ForwardTargets;
                }

                if (targets == null)
                {
                    return(false);
                }

                LinkedListNode <KeyValuePair <IReference, T> > node;

                if (!targets.TryGetValue((NodeId)key.TargetId, out node))
                {
                    return(false);
                }

                m_list.Remove(node);
                targets.Remove((NodeId)key.TargetId);
            }

            // remove empty reference.
            if (entry.IsEmpty)
            {
                m_references.Remove(key.ReferenceTypeId);
            }

            return(true);
        }
Esempio n. 5
0
        /// <summary>
        /// Removes all of the references of the specified type and direction.
        /// </summary>
        /// <param name="referenceTypeId">The reference type identifier.</param>
        /// <param name="isInverse">if set to <c>true</c> this is inverse reference.</param>
        /// <returns>The result of removal.</returns>
        public bool RemoveAll(NodeId referenceTypeId, bool isInverse)
        {
            // check for null.
            if (NodeId.IsNull(referenceTypeId))
            {
                return(false);
            }

            // look up the reference type.
            ReferenceTypeEntry entry = null;

            if (!m_references.TryGetValue(referenceTypeId, out entry))
            {
                return(false);
            }

            if (isInverse)
            {
                if (entry.InverseTargets != null)
                {
                    foreach (LinkedListNode <KeyValuePair <IReference, T> > node in entry.InverseTargets.Values)
                    {
                        if (Object.ReferenceEquals(m_list, node.List))
                        {
                            m_list.Remove(node);
                        }

                        entry.InverseTargets = null;
                    }
                }

                if (entry.InverseExternalTargets != null)
                {
                    foreach (LinkedListNode <KeyValuePair <IReference, T> > node in entry.InverseExternalTargets.Values)
                    {
                        if (Object.ReferenceEquals(m_list, node.List))
                        {
                            m_list.Remove(node);
                        }
                    }

                    entry.InverseExternalTargets = null;
                }
            }
            else
            {
                if (entry.ForwardTargets != null)
                {
                    foreach (LinkedListNode <KeyValuePair <IReference, T> > node in entry.ForwardTargets.Values)
                    {
                        if (Object.ReferenceEquals(m_list, node.List))
                        {
                            m_list.Remove(node);
                        }
                    }

                    entry.ForwardTargets = null;
                }

                if (entry.ForwardExternalTargets != null)
                {
                    foreach (LinkedListNode <KeyValuePair <IReference, T> > node in entry.ForwardExternalTargets.Values)
                    {
                        if (Object.ReferenceEquals(m_list, node.List))
                        {
                            m_list.Remove(node);
                        }
                    }

                    entry.ForwardExternalTargets = null;
                }
            }

            // check for empty set.
            if (entry.IsEmpty)
            {
                m_references.Remove(referenceTypeId);
            }

            return(true);
        }
Esempio n. 6
0
        /// <summary>
        /// Adds or replaces a reference.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <param name="replace">if set to <c>true</c> reference is replaced.</param>
        private void Add(IReference key, T value, bool replace)
        {
            // validate key.
            ValidateReference(key, true);

            m_version++;

            // look up the reference type.
            ReferenceTypeEntry entry = null;

            if (!m_references.TryGetValue(key.ReferenceTypeId, out entry))
            {
                entry = new ReferenceTypeEntry();
                m_references.Add(key.ReferenceTypeId, entry);
            }

            // handle reference to external targets.
            if (key.TargetId.IsAbsolute)
            {
                Dictionary <ExpandedNodeId, LinkedListNode <KeyValuePair <IReference, T> > > targets = null;

                if (key.IsInverse)
                {
                    if (entry.InverseExternalTargets == null)
                    {
                        entry.InverseExternalTargets = new Dictionary <ExpandedNodeId, LinkedListNode <KeyValuePair <IReference, T> > >();
                    }

                    targets = entry.InverseExternalTargets;
                }
                else
                {
                    if (entry.ForwardExternalTargets == null)
                    {
                        entry.ForwardExternalTargets = new Dictionary <ExpandedNodeId, LinkedListNode <KeyValuePair <IReference, T> > >();
                    }

                    targets = entry.ForwardExternalTargets;
                }

                // create a new target.
                LinkedListNode <KeyValuePair <IReference, T> > node = new LinkedListNode <KeyValuePair <IReference, T> >(new KeyValuePair <IReference, T>(key, value));

                // check if target already exists.
                LinkedListNode <KeyValuePair <IReference, T> > existingNode = null;

                if (!targets.TryGetValue(key.TargetId, out existingNode))
                {
                    existingNode = node;
                    m_list.AddLast(node);
                }

                // need to replace reference in linked linked as well as the target list.
                else
                {
                    if (!replace)
                    {
                        throw new ArgumentException("Key already exists in dictionary.", "key");
                    }

                    m_list.AddAfter(existingNode, node);
                    m_list.Remove(existingNode);
                }

                targets[key.TargetId] = node;
            }

            // handle reference to internal target.
            else
            {
                NodeIdDictionary <LinkedListNode <KeyValuePair <IReference, T> > > targets = null;

                if (key.IsInverse)
                {
                    if (entry.InverseTargets == null)
                    {
                        entry.InverseTargets = new NodeIdDictionary <LinkedListNode <KeyValuePair <IReference, T> > >();
                    }

                    targets = entry.InverseTargets;
                }
                else
                {
                    if (entry.ForwardTargets == null)
                    {
                        entry.ForwardTargets = new NodeIdDictionary <LinkedListNode <KeyValuePair <IReference, T> > >();
                    }

                    targets = entry.ForwardTargets;
                }

                NodeId targetId = (NodeId)key.TargetId;

                // create a new target.
                LinkedListNode <KeyValuePair <IReference, T> > node = new LinkedListNode <KeyValuePair <IReference, T> >(new KeyValuePair <IReference, T>(key, value));

                // check if target already exists.
                LinkedListNode <KeyValuePair <IReference, T> > existingNode = null;

                if (!targets.TryGetValue(targetId, out existingNode))
                {
                    existingNode = node;
                    m_list.AddLast(node);
                }

                // need to replace reference in linked linked as well as the target list.
                else
                {
                    if (!replace)
                    {
                        throw new ArgumentException("Key already exists in dictionary.", "key");
                    }

                    m_list.AddAfter(existingNode, node);
                    m_list.Remove(existingNode);
                }

                targets[targetId] = node;
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Returns the target entry associated with the reference.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <returns>The target entry associated with the reference.</returns>
        private bool TryGetEntry(IReference key, out KeyValuePair <IReference, T> value)
        {
            value = new KeyValuePair <IReference, T>();

            // validate key.
            if (!ValidateReference(key, false))
            {
                return(false);
            }

            // look up the reference type.
            ReferenceTypeEntry entry = null;

            if (!m_references.TryGetValue(key.ReferenceTypeId, out entry))
            {
                return(false);
            }

            // handle reference to external targets.
            if (key.TargetId.IsAbsolute)
            {
                Dictionary <ExpandedNodeId, LinkedListNode <KeyValuePair <IReference, T> > > targets = null;

                if (key.IsInverse)
                {
                    targets = entry.InverseExternalTargets;
                }
                else
                {
                    targets = entry.ForwardExternalTargets;
                }

                if (targets == null)
                {
                    return(false);
                }

                LinkedListNode <KeyValuePair <IReference, T> > node;

                if (targets.TryGetValue(key.TargetId, out node))
                {
                    value = node.Value;
                    return(true);
                }
            }

            // handle reference to internal target.
            else
            {
                NodeIdDictionary <LinkedListNode <KeyValuePair <IReference, T> > > targets = null;

                if (key.IsInverse)
                {
                    targets = entry.InverseTargets;
                }
                else
                {
                    targets = entry.ForwardTargets;
                }

                if (targets == null)
                {
                    return(false);
                }

                LinkedListNode <KeyValuePair <IReference, T> > node;

                if (targets.TryGetValue((NodeId)key.TargetId, out node))
                {
                    value = node.Value;
                    return(true);
                }
            }

            return(false);
        }