Exemple #1
0
            public override void Write(StringTrieBuilder builder)
            {
                next.Write(builder);
#pragma warning disable 612, 618
                offset = builder.WriteValueAndFinal(value, false);
#pragma warning restore 612, 618
            }
Exemple #2
0
            public override Node Register(StringTrieBuilder builder)
            {
                next = next.Register(builder);
                // Break the linear-match sequence into chunks of at most kMaxLinearMatchLength.
#pragma warning disable 612, 618
                int maxLinearMatchLength = builder.MaxLinearMatchLength;
#pragma warning restore 612, 618
                while (length > maxLinearMatchLength)
                {
                    int nextOffset = stringOffset + length - maxLinearMatchLength;
                    length -= maxLinearMatchLength;
                    LinearMatchNode suffixNode =
                        new LinearMatchNode(strings, nextOffset, maxLinearMatchLength, next);
                    suffixNode.SetHashCode();
                    next = builder.RegisterNode(suffixNode);
                }
                Node result;
#pragma warning disable 612, 618
                if (hasValue && !builder.MatchNodesCanHaveValues)
#pragma warning restore 612, 618
                {
                    int intermediateValue = value;
                    value    = 0;
                    hasValue = false;
                    SetHashCode();
                    result = new IntermediateValueNode(intermediateValue, builder.RegisterNode(this));
                }
                else
                {
                    SetHashCode();
                    result = this;
                }
                return(builder.RegisterNode(result));
            }
Exemple #3
0
            private Node Register(StringTrieBuilder builder, int start, int limit)
            {
                int length = limit - start;

#pragma warning disable 612, 618
                if (length > builder.MaxBranchLinearSubNodeLength)
#pragma warning restore 612, 618
                {
                    // Branch on the middle unit.
                    int middle = start + length / 2;
                    return(builder.RegisterNode(
                               new SplitBranchNode(
                                   chars[middle],
                                   Register(builder, start, middle),
                                   Register(builder, middle, limit))));
                }
                ListBranchNode listNode = new ListBranchNode(length);
                do
                {
                    char c    = chars[start];
                    Node node = equal[start];
                    if (node.GetType() == typeof(ValueNode))
                    {
                        // Final value.
                        listNode.Add(c, ((ValueNode)node).Value);
                    }
                    else
                    {
                        listNode.Add(c, node.Register(builder));
                    }
                } while (++start < limit);
                return(builder.RegisterNode(listNode));
            }
Exemple #4
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);
                    }
                }
                char c = s[start++];
                int  i = Find(c);

                if (i < chars.Length && c == chars[i])
                {
                    equal[i] = equal[i].Add(builder, s, start, sValue);
                }
                else
                {
                    chars.Insert(i, c);
                    equal.Insert(i, builder.CreateSuffixNode(s, start, sValue));
                }
                return(this);
            }
Exemple #5
0
            public override void Write(StringTrieBuilder builder)
            {
                next.Write(builder);
#pragma warning disable 612, 618
                builder.Write(stringOffset, length);
                offset = builder.WriteValueAndType(hasValue, value, builder.MinLinearMatch + length - 1);
#pragma warning restore 612, 618
            }
Exemple #6
0
            public override void Write(StringTrieBuilder builder)
            {
                // Write the sub-nodes in reverse order: The jump lengths are deltas from
                // after their own positions, so if we wrote the minUnit sub-node first,
                // then its jump delta would be larger.
                // Instead we write the minUnit sub-node last, for a shorter delta.
                int  unitNumber      = length - 1;
                Node rightEdge       = equal[unitNumber];
                int  rightEdgeNumber = rightEdge == null ? firstEdgeNumber : rightEdge.Offset;

                do
                {
                    --unitNumber;
                    if (equal[unitNumber] != null)
                    {
                        equal[unitNumber].WriteUnlessInsideRightEdge(firstEdgeNumber, rightEdgeNumber, builder);
                    }
                } while (unitNumber > 0);
                // The maxUnit sub-node is written as the very last one because we do
                // not jump for it at all.
                unitNumber = length - 1;
                if (rightEdge == null)
                {
#pragma warning disable 612, 618
                    builder.WriteValueAndFinal(values[unitNumber], true);
#pragma warning restore 612, 618
                }
                else
                {
                    rightEdge.Write(builder);
                }
#pragma warning disable 612, 618
                offset = builder.Write(units[unitNumber]);
#pragma warning restore 612, 618
                // Write the rest of this node's unit-value pairs.
                while (--unitNumber >= 0)
                {
                    int  value;
                    bool isFinal;
                    if (equal[unitNumber] == null)
                    {
                        // Write the final value for the one string ending with this unit.
                        value   = values[unitNumber];
                        isFinal = true;
                    }
                    else
                    {
                        // Write the delta to the start position of the sub-node.
                        Debug.Assert(equal[unitNumber].Offset > 0);
                        value   = offset - equal[unitNumber].Offset;
                        isFinal = false;
                    }
#pragma warning disable 612, 618
                    builder.WriteValueAndFinal(value, isFinal);
                    offset = builder.Write(units[unitNumber]);
#pragma warning restore 612, 618
                }
            }
Exemple #7
0
 public override void Write(StringTrieBuilder builder)
 {
     // Encode the less-than branch first.
     lessThan.WriteUnlessInsideRightEdge(firstEdgeNumber, greaterOrEqual.Offset, builder);
     // Encode the greater-or-equal branch last because we do not jump for it at all.
     greaterOrEqual.Write(builder);
     // Write this node.
     Debug.Assert(lessThan.Offset > 0);
     builder.WriteDeltaTo(lessThan.Offset);  // less-than
     offset = builder.Write(unit);
 }
Exemple #8
0
            public override Node Add(StringTrieBuilder builder, ICharSequence s, int start, int sValue)
            {
                if (start == s.Length)
                {
                    throw new ArgumentException("Duplicate string.");
                }
                // Replace self with a node for the remaining string suffix and value.
                ValueNode node = builder.CreateSuffixNode(s, start, sValue);

                node.SetValue(value);
                return(node);
            }
Exemple #9
0
 // See MarkRightEdgesFirst.
 public void WriteUnlessInsideRightEdge(int firstRight, int lastRight,
                                        StringTrieBuilder builder)
 {
     // Note: Edge numbers are negative, lastRight<=firstRight.
     // If offset>0 then this node and its sub-nodes have been written already
     // and we need not write them again.
     // If this node is part of the unwritten right branch edge,
     // then we wait until that is written.
     if (offset < 0 && (offset < lastRight || firstRight < offset))
     {
         Write(builder);
     }
 }
Exemple #10
0
 public override void Write(StringTrieBuilder builder)
 {
     next.Write(builder);
     if (length <= builder.MinLinearMatch)
     {
         offset = builder.WriteValueAndType(hasValue, value, length - 1);
     }
     else
     {
         builder.Write(length - 1);
         offset = builder.WriteValueAndType(hasValue, value, 0);
     }
 }
Exemple #11
0
            public override void Write(StringTrieBuilder builder)
            {
                next.Write(builder);
#pragma warning disable 612, 618
                if (length <= builder.MinLinearMatch)
                {
                    offset = builder.WriteValueAndType(hasValue, value, length - 1);
                }
                else
                {
                    builder.Write(length - 1);
                    offset = builder.WriteValueAndType(hasValue, value, 0);
#pragma warning restore 612, 618
                }
            }
Exemple #12
0
            public override Node Register(StringTrieBuilder builder)
            {
                Node           subNode = Register(builder, 0, chars.Length);
                BranchHeadNode head    = new BranchHeadNode(chars.Length, subNode);
                Node           result  = head;

                if (hasValue)
                {
                    if (builder.MatchNodesCanHaveValues)
                    {
                        head.SetValue(value);
                    }
                    else
                    {
                        result = new IntermediateValueNode(value, builder.RegisterNode(head));
                    }
                }
                return(builder.RegisterNode(result));
            }
Exemple #13
0
 /// <summary>
 /// Recursive method for registering unique nodes,
 /// after all (string, value) pairs have been added.
 /// Final-value nodes are pre-registered while
 /// <see cref="Add(StringTrieBuilder, ICharSequence, int, int)"/>ing
 /// (string, value) pairs. Other nodes created while
 /// <see cref="Add(StringTrieBuilder, ICharSequence, int, int)"/>ing
 /// <see cref="RegisterNode(Node)"/> themselves later and might replace
 /// themselves with new types of nodes for <see cref="Write(StringTrieBuilder)"/>ing.
 /// </summary>
 /// <returns>The registered version of this node which implements <see cref="Write(StringTrieBuilder)"/>.</returns>
 public virtual Node Register(StringTrieBuilder builder)
 {
     return(this);
 }
Exemple #14
0
 public override void Write(StringTrieBuilder builder)
 {
     next.Write(builder);
     builder.Write(stringOffset, length);
     offset = builder.WriteValueAndType(hasValue, value, builder.MinLinearMatch + length - 1);
 }
Exemple #15
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);
            }
Exemple #16
0
 public override void Write(StringTrieBuilder builder)
 {
     next.Write(builder);
     offset = builder.WriteValueAndFinal(value, false);
 }
Exemple #17
0
 /// <summary>
 /// Recursive method for adding a new (string, value) pair.
 /// Matches the remaining part of <paramref name="s"/> from <paramref name="start"/>,
 /// and adds a new node where there is a mismatch.
 /// </summary>
 /// <returns>This or a replacement <see cref="Node"/>.</returns>
 public virtual Node Add(StringTrieBuilder builder, ICharSequence s, int start, int sValue)
 {
     return(this);
 }
Exemple #18
0
 // Write() must set the offset to a positive value.
 public abstract void Write(StringTrieBuilder builder);
Exemple #19
0
 public override void Write(StringTrieBuilder builder)
 {
     offset = builder.WriteValueAndFinal(value, true);
 }