예제 #1
0
 /// <summary>
 /// Default constructor: Initializes the maximum number of child edges allowed in tree
 /// Creates child node of type “IMultiWaySuffixEdge”, that implies that the references to child node will be in-memory.
 /// </summary>
 /// <param name="sequence">Sequence of the tree</param>
 /// <param name="maximumChildrenCount">Number of allowed child edges</param>
 public MultiWaySuffixTree(ISequence sequence, int maximumChildrenCount)
 {
     InitializeReferenceSequence(sequence);
     _maximumChildrenCount = maximumChildrenCount;
     Root = new MultiWaySuffixEdge();
     Count++;
 }
예제 #2
0
        public virtual IEdge Split(IEdge edge, int splitAt)
        {
            // This is a leaf node with both start and end indices pointing to
            // terminating symbol. Don't insert this.
            if (splitAt == _sequence.Count)
            {
                return(edge);
            }

            MultiWaySuffixEdge mwCurrentEdge = edge as MultiWaySuffixEdge;

            if (mwCurrentEdge == null)
            {
                throw new ArgumentNullException("edge");
            }

            // Create the new edge
            MultiWaySuffixEdge newEdge =
                new MultiWaySuffixEdge(splitAt + 1, mwCurrentEdge.EndIndex);

            // Copy the children of old edge to new edge
            newEdge.ReplaceChildren(mwCurrentEdge.GetChildren());

            // Update the old edge
            mwCurrentEdge.EndIndex = splitAt;

            // Set new edge as child edge to old edge
            mwCurrentEdge.ClearChildren();
            mwCurrentEdge.AddChild(newEdge);
            Count++;

            return(mwCurrentEdge);
        }
예제 #3
0
        /// <summary>
        /// Find the child edge, whose first character starts with given character.
        /// </summary>
        /// <param name="edge">Parent edge</param>
        /// <param name="character">First character of required edge</param>
        /// <returns>Edge found</returns>
        public virtual IEdge Find(IEdge edge, byte character)
        {
            MultiWaySuffixEdge mwEdge = edge as MultiWaySuffixEdge;

            if (mwEdge == null)
            {
                throw new ArgumentNullException("edge");
            }

            if (mwEdge.GetChildren() == null)
            {
                return(null);
            }

            int charIndex = 0;

            foreach (IEdge childEdge in mwEdge.GetChildren())
            {
                charIndex = childEdge.StartIndex;

                if (charIndex < _sequence.Count)
                {
                    if (GetReferenceSymbol(charIndex) == character)
                    {
                        return(childEdge);
                    }
                }
            }

            return(null);
        }
예제 #4
0
        /// <summary>
        /// Update the old node with new node, requires merging the child edges.
        /// </summary>
        /// <param name="parentEdge">Parent edge.</param>
        /// <param name="oldEdge">Old edge</param>
        /// <param name="newEdge">new edge</param>
        /// <returns></returns>
        public virtual bool Update(IEdge parentEdge, IEdge oldEdge, IEdge newEdge)
        {
            MultiWaySuffixEdge mwParentEdge = parentEdge as MultiWaySuffixEdge;

            if (mwParentEdge == null)
            {
                throw new ArgumentNullException("parentEdge");
            }

            if (oldEdge == null)
            {
                throw new ArgumentNullException("oldEdge");
            }

            if (newEdge == null)
            {
                throw new ArgumentNullException("newEdge");
            }

            for (int index = 0; index < mwParentEdge.GetChildren().Length; index++)
            {
                if (mwParentEdge.GetChildren()[index] == oldEdge)
                {
                    mwParentEdge.GetChildren()[index] = newEdge;
                    return(true);
                }
            }

            return(false);
        }
예제 #5
0
        /// <summary>
        /// Remove the edge from tree, the edge and all its children will be removed.
        /// </summary>
        /// <param name="parentEdge">Parent edge.</param>
        /// <param name="edge">Edge to be removed.</param>
        /// <returns>Success flag</returns>
        public virtual bool Remove(IEdge parentEdge, IEdge edge)
        {
            MultiWaySuffixEdge mwParentEdge = parentEdge as MultiWaySuffixEdge;

            if (mwParentEdge == null)
            {
                throw new ArgumentNullException("parentEdge");
            }

            if (edge == null)
            {
                throw new ArgumentNullException("edge");
            }

            for (int index = 0; index < mwParentEdge.GetChildren().Length; index++)
            {
                if (mwParentEdge.GetChildren()[index] == edge)
                {
                    mwParentEdge.GetChildren()[index] = null;
                    Count--;
                    return(true);
                }
            }

            return(false);
        }
예제 #6
0
        /// <summary>
        /// Insert a edge at given parent.
        /// </summary>
        /// <param name="parentEdge">Parent edge.</param>
        /// <param name="startIndex">Start index of edge</param>
        /// <param name="endIndex">End index of edge</param>
        /// <returns>New edge created</returns>
        public override IEdge Insert(IEdge parentEdge, int startIndex, int endIndex)
        {
            // This is a leaf node with both start and end indices pointing to
            // terminating symbol. Don't insert this.
            if (startIndex >= Sequence.Count)
            {
                return(null);
            }

            if (PersisntThreshold > Count)
            {
                return(base.Insert(parentEdge, startIndex, endIndex));
            }

            PersistentMultiWaySuffixEdge edge = new PersistentMultiWaySuffixEdge(
                startIndex,
                endIndex,
                MaximumChildrenCount);

            edge.Key = EdgeStore.Write(edge);

            // Parent edge of type PersistentMultiWaySuffixEdge
            PersistentMultiWaySuffixEdge pmwParentEdge = parentEdge as PersistentMultiWaySuffixEdge;

            if (pmwParentEdge != null)
            {
                pmwParentEdge.AddChild(edge.Key);
                Count++;
                return(edge);
            }

            // Parent edge of type MultiWaySuffixEdge
            MultiWaySuffixEdge mwParentEdge = parentEdge as MultiWaySuffixEdge;

            if (mwParentEdge != null)
            {
                if (mwParentEdge.GetChildren() == null)
                {
                    mwParentEdge.AddChild(edge);
                    Count++;
                    return(edge);
                }

                if (mwParentEdge.GetChildren().Length < MaximumChildrenCount)
                {
                    mwParentEdge.AddChild(edge);
                    Count++;
                    return(edge);
                }

                // No more children edge can be added.
                throw new InvalidOperationException(string.Format(
                                                        CultureInfo.CurrentCulture,
                                                        "Cannot add more than {0} child nodes to edge.",
                                                        MaximumChildrenCount));
            }

            return(edge);
        }
예제 #7
0
        /// <summary>
        /// Insert a edge at given parent.
        /// </summary>
        /// <param name="parentEdge">Parent edge.</param>
        /// <param name="startIndex">Start index of edge</param>
        /// <param name="endIndex">End index of edge</param>
        /// <returns>New edge created</returns>
        public virtual IEdge Insert(IEdge parentEdge, int startIndex, int endIndex)
        {
            // This is a leaf node with both start and end indices pointing to
            // terminating symbol. Don't insert this.
            if (startIndex >= _sequence.Count)
            {
                return(null);
            }

            MultiWaySuffixEdge mwParentEdge = parentEdge as MultiWaySuffixEdge;

            if (mwParentEdge == null)
            {
                throw new ArgumentNullException("parentEdge");
            }

            if (mwParentEdge.GetChildren() == null)
            {
                IEdge edge = new MultiWaySuffixEdge(startIndex, endIndex);
                mwParentEdge.AddChild(edge);
                Count++;
                return(edge);
            }

            if (mwParentEdge.GetChildren().Length < _maximumChildrenCount)
            {
                IEdge edge = new MultiWaySuffixEdge(startIndex, endIndex);
                mwParentEdge.AddChild(edge);
                Count++;
                return(edge);
            }

            // No more children edge can be added.
            throw new InvalidOperationException(string.Format(
                                                    CultureInfo.CurrentCulture,
                                                    "Cannot add more than {0} child nodes to edge.",
                                                    _maximumChildrenCount));
        }
예제 #8
0
        /// <summary>
        /// Merge the given branch at the root of Suffix Tree.
        /// Asummption:
        ///  The root node of the given branch contains only one edge, which is the branch to be merged.
        /// </summary>
        /// <param name="branch">Branch to be merged.</param>
        /// <returns>Success flag.</returns>
        public bool Merge(IMultiWaySuffixTree branch)
        {
            if (branch == null)
            {
                throw new NotImplementedException("branch");
            }

            MultiWaySuffixEdge mwBranchEdge = branch.Root as MultiWaySuffixEdge;

            if (mwBranchEdge.GetChildren() == null)
            {
                return(false);
            }

            MultiWaySuffixEdge mwRoot = Root as MultiWaySuffixEdge;

            if (mwRoot.GetChildren() == null)
            {
                mwRoot.AddChild(mwBranchEdge.GetChildren()[0]);
                Count += (branch.Count - 1); // - the original root edge of branch
                return(true);
            }

            if (mwRoot.GetChildren().Length < _maximumChildrenCount)
            {
                mwRoot.AddChild(mwBranchEdge.GetChildren()[0]);
                Count += (branch.Count - 1); // - the original root edge of branch
                return(true);
            }

            // No more children edge can be added.
            throw new InvalidOperationException(string.Format(
                                                    CultureInfo.CurrentCulture,
                                                    "Cannot add more than {0} child nodes to edge.",
                                                    _maximumChildrenCount));
        }