Beispiel #1
0
 public UTree(byte[] store, int count)
 {
     _store       = store;
     _root        = new UNode();
     _activePoint = new ActivePoint(_root, 0, 0);
     ConstructFromInitialStoreValues(count);
 }
Beispiel #2
0
        // 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.
        }
Beispiel #3
0
 private void ActiveNodeHasEdgeForSymbol(byte symbol, UNode uNode)
 {
     _activePoint.SetSuffixLinkToActiveNodeAndReturnActiveNode(uNode);
     _activePoint = _activePoint.MoveToEdgeStartingWith(symbol);
     if (_activePoint.PointsToTheEndOfActiveEdge())
     {
         _activePoint = _activePoint.MoveToNextNodeOfActiveEdge();
     }
 }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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++;
        }