/// <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)); }
/// <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); } }
public void Clear() { Leaf = null; Prefix = string.Empty; Edges.Clear(); }