/// <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++; }
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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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)); }
/// <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)); }