public UTree(byte[] store, int count) { _store = store; _root = new UNode(); _activePoint = new ActivePoint(_root, 0, 0); ConstructFromInitialStoreValues(count); }
// searchLimit = how much of suffix to match, maximally public int Match(byte[] suffix, int searchLimit, out int startingIndex) { UNode currentUNode = _root; UEdge currentEdge = null; for (int i = 0; i < suffix.Length && i < searchLimit; i++) { byte matchMe = suffix[i]; UEdge nextEdge; nextEdge = currentUNode.Edges[matchMe]; if (nextEdge == null) { if (currentEdge == null) { // in this case, we're at the root uNode. no match is made. return -1. startingIndex = -1; return(-1); } startingIndex = currentEdge.From - (i - 1); return(i - 1); // matched every letter except this one. } currentEdge = nextEdge; int j; int jLimit = Math.Min(currentEdge.Length, suffix.Length - i); for (j = 0; j < jLimit; j++) { if (_store[currentEdge.From + j] != suffix[i + j]) { if (i + j < suffix.Length) { // we only got part way through this edge. include what we have and end here. startingIndex = currentEdge.From - i; return(i + j); } break; } } // j is the amount of the suffix the edge represents i += j - 1; if (i == suffix.Length - 1) { // matched whole string startingIndex = currentEdge.From - (i - (j - 1)); return(suffix.Length); } if (currentEdge.Next == null) { // end of the line. return what we have. startingIndex = currentEdge.From - (i - (j - 1)); return(i); } currentUNode = currentEdge.Next; } startingIndex = -1; return(-1); // no match at all? we might not get here actually. }
private void ActiveNodeHasEdgeForSymbol(byte symbol, UNode uNode) { _activePoint.SetSuffixLinkToActiveNodeAndReturnActiveNode(uNode); _activePoint = _activePoint.MoveToEdgeStartingWith(symbol); if (_activePoint.PointsToTheEndOfActiveEdge()) { _activePoint = _activePoint.MoveToNextNodeOfActiveEdge(); } }
private UNode InternalWithoutEdgeForSymbol(int index, byte symbol, UNode uNode) { _activePoint.AddEdgeToActiveNode(symbol, new UEdge(index, _store.Length, null)); UNode activeUNode = _activePoint.SetSuffixLinkToActiveNodeAndReturnActiveNode(uNode); _activePoint = _activePoint.HasASuffixLink() ? _activePoint.MoveToSuffixLink() : _activePoint.MoveTo(_root); return(activeUNode); }
private UNode EdgeFromRootWithoutSymbol(int index, byte symbol, UNode oldUNode) { UNode newUNode = new UNode(); _activePoint.SplitActiveEdge(_store, newUNode, index, symbol); _activePoint.SetSuffixLinkTo(oldUNode, newUNode); _activePoint = _activePoint.MoveToEdgeStartingWithAndByActiveLengthLessOne(_root, _store[index - _remainder + 2]); _activePoint = WalkDownTree(index); return(newUNode); }
private UNode EdgeFromInternalWithoutSymbol(int index, byte symbol, UNode oldUNode) { UNode newUNode = new UNode(); _activePoint.SplitActiveEdge(_store, newUNode, index, symbol); _activePoint.SetSuffixLinkTo(oldUNode, newUNode); _activePoint = _activePoint.HasASuffixLink() ? _activePoint.MoveToSuffixLink() : _activePoint.MoveTo(_root); _activePoint = WalkDownTree(index); return(newUNode); }
private void Add(int index, byte symbol) { bool symbolFound = false; UNode lastAddedUNode = null; _remainder++; while (!symbolFound && _remainder > 0) { if (_activePoint.PointsToActiveNode()) { if (_activePoint.ActiveNodeHasEdgeFor(symbol)) { ActiveNodeHasEdgeForSymbol(symbol, lastAddedUNode); symbolFound = true; } else { if (_activePoint.IsThisTheActiveNode(_root)) { RootHasNoEdgeForSymbol(index, symbol); } else { lastAddedUNode = InternalWithoutEdgeForSymbol(index, symbol, lastAddedUNode); } _remainder--; } } else { if (_activePoint.PointsToActiveEdge(_store, symbol)) { ActiveEdgeWithSymbol(); symbolFound = true; } else { lastAddedUNode = _activePoint.IsThisTheActiveNode(_root) ? EdgeFromRootWithoutSymbol(index, symbol, lastAddedUNode) : EdgeFromInternalWithoutSymbol(index, symbol, lastAddedUNode); _remainder--; } } } InsertionPoint++; }