Exemplo n.º 1
0
            public override Node Add(StringTrieBuilder builder, ICharSequence s, int start, int sValue)
            {
                if (start == s.Length)
                {
                    if (hasValue)
                    {
                        throw new ArgumentException("Duplicate string.");
                    }
                    else
                    {
                        SetValue(sValue);
                        return(this);
                    }
                }
                int limit = stringOffset + length;

                for (int i = stringOffset; i < limit; ++i, ++start)
                {
                    if (start == s.Length)
                    {
                        // s is a prefix with a new value. Split self into two linear-match nodes.
                        int             prefixLength = i - stringOffset;
                        LinearMatchNode suffixNode   = new LinearMatchNode(strings, i, length - prefixLength, next);
                        suffixNode.SetValue(sValue);
                        length = prefixLength;
                        next   = suffixNode;
                        return(this);
                    }
                    char thisChar = strings[i];
                    char newChar  = s[start];
                    if (thisChar != newChar)
                    {
                        // Mismatch, insert a branch node.
                        DynamicBranchNode branchNode = new DynamicBranchNode();
                        // Reuse this node for one of the remaining substrings, if any.
                        Node result, thisSuffixNode;
                        if (i == stringOffset)
                        {
                            // Mismatch on first character, turn this node into a suffix.
                            if (hasValue)
                            {
                                // Move the value for prefix length "start" to the new node.
                                branchNode.SetValue(value);
                                value    = 0;
                                hasValue = false;
                            }
                            ++stringOffset;
                            --length;
                            thisSuffixNode = length > 0 ? this : next;
                            // C++: if(length==0) { delete this; }
                            result = branchNode;
                        }
                        else if (i == limit - 1)
                        {
                            // Mismatch on last character, keep this node for the prefix.
                            --length;
                            thisSuffixNode = next;
                            next           = branchNode;
                            result         = this;
                        }
                        else
                        {
                            // Mismatch on intermediate character, keep this node for the prefix.
                            int prefixLength = i - stringOffset;
                            ++i;  // Suffix start offset (after thisChar).
                            thisSuffixNode = new LinearMatchNode(
                                strings, i, length - (prefixLength + 1), next);
                            length = prefixLength;
                            next   = branchNode;
                            result = this;
                        }
                        ValueNode newSuffixNode = builder.CreateSuffixNode(s, start + 1, sValue);
                        branchNode.Add(thisChar, thisSuffixNode);
                        branchNode.Add(newChar, newSuffixNode);
                        return(result);
                    }
                }
                // s matches all of this node's characters.
                next = next.Add(builder, s, start, sValue);
                return(this);
            }