Example #1
0
        /// <summary>
        /// searches for the longest prefix match
        /// </summary>
        public (string key, TValue value, bool found) LongestPrefix(string prefix)
        {
            LeafNode <TValue> last = null;
            var node   = _root;
            var search = prefix;

            //for {
            while (true)
            {
                // Look for a leaf node
                if (node.IsLeaf)
                {
                    last = node.Leaf;
                }

                // Check for key exhaution
                if (search.Length == 0)
                {
                    break;
                }

                // Look for an edge
                if (!node.TryGetEdge(search[0], out node))
                {
                    break;
                }

                // Consume the search prefix
                if (search.StartsWith(node.Prefix))
                {
                    search = search.Substring(node.Prefix.Length);
                }
                else
                {
                    break;
                }
            }

            return(last != null ? (last.Key, last.Value, true) : (string.Empty, default(TValue), false));
        }
Example #2
0
        /// <summary>
        /// adds new entry or updates an existing entry
        /// </summary>
        /// <returns>is entry updated, and old value if it was</returns>
        public (TValue oldValue, bool updated) Insert(string key, TValue value)
        {
            _values[key] = value;

            var node   = _root;
            var search = key;

            while (true)
            {
                // Handle key exhaution
                if (search.Length == 0)
                {
                    if (node.IsLeaf)
                    {
                        var old = node.Leaf.Value;
                        node.Leaf.Value = value;
                        return(old, true);
                    }

                    node.Leaf = new LeafNode <TValue>
                    {
                        Key   = key,
                        Value = value,
                    };
                    return(default(TValue), false);
                }

                var parent = node;

                // Look for the edge
                // No edge, create one
                if (!node.TryGetEdge(search[0], out node))
                {
                    parent.AddEdge(search[0], new Node <TValue>
                    {
                        Leaf = new LeafNode <TValue>
                        {
                            Key   = key,
                            Value = value,
                        },
                        Prefix = search,
                    });
                    return(default(TValue), false);
                }

                // Determine longest prefix of the search key on match
                var commonPrefix = StringHelpers.FindLongestPrefix(search, node.Prefix);
                if (commonPrefix == node.Prefix.Length)
                {
                    search = search.Substring(commonPrefix);
                    continue;
                }

                // Split the node
                var child = new Node <TValue>
                {
                    Prefix = search.Substring(0, commonPrefix),
                };
                parent.SetEdge(search[0], child);

                // Restore the existing node
                child.AddEdge(node.Prefix[commonPrefix], node);
                node.Prefix = node.Prefix.Substring(commonPrefix);

                // Create a new leaf node
                var leaf = new LeafNode <TValue>
                {
                    Key   = key,
                    Value = value,
                };

                // If the new key is a subset, add to to this node
                search = search.Substring(commonPrefix);
                if (search.Length == 0)
                {
                    child.Leaf = leaf;
                    return(default(TValue), false);
                }

                // Create a new edge for the node
                child.AddEdge(search[0], new Node <TValue>
                {
                    Leaf   = leaf,
                    Prefix = search,
                });
                return(default(TValue), false);
            }
        }
Example #3
0
 public void Clear()
 {
     Leaf   = null;
     Prefix = string.Empty;
     Edges.Clear();
 }