/// <summary> /// Tries to get the Value associated with a given Key /// </summary> /// <param name="key">Key</param> /// <param name="value">Value, will be null if the key does not exist or has no value associated with it</param> /// <returns>True if the Key exists in the Trie and has a value associated with it, False if it does not</returns> public bool TryGetValue(TKey key, out TValue value) { value = null; ITrieNode <TKeyBit, TValue> node = this._root; IEnumerable <TKeyBit> bs = this._keyMapper(key); foreach (TKeyBit b in bs) { //Bail out early if key does not exist if (!node.TryGetChild(b, out node)) { return(false); } } if (node.HasValue) { value = node.Value; return(true); } else { return(false); } }
/// <summary> /// Finds and returns a Node that has the shortest prefix match greater than or equal to the given Key using the given Key to Key Bit mapping function /// </summary> /// <param name="bs">Key Bits</param> /// <returns>Null if the Key does not map to a Node</returns> /// <remarks> /// The ability to provide a specific sequence of key bits may be useful for custom lookups where you don't necessarily have a value of the <strong>TKey</strong> type but do have values of the <strong>TKeyBit</strong> type /// </remarks> public ITrieNode <TKeyBit, TValue> FindSuccessor(IEnumerable <TKeyBit> bs) { ITrieNode <TKeyBit, TValue> node = this._root; foreach (TKeyBit b in bs) { //Bail out early if key does not exist if (!node.TryGetChild(b, out node)) { return(null); } } Queue <ITrieNode <TKeyBit, TValue> > depthFirstQueue = new Queue <ITrieNode <TKeyBit, TValue> >(); depthFirstQueue.Enqueue(node); while (depthFirstQueue.Count > 0) { node = depthFirstQueue.Dequeue(); if (node.HasValue) { return(node); } foreach (var child in node.Children.OrderBy(n => n.KeyBit, this.KeyBitComparer)) { depthFirstQueue.Enqueue(child); } } return(null); }
/// <summary> /// Finds and returns a Node for the given sequence of Key Bits /// </summary> /// <param name="bs">Key Bits</param> /// <returns>Null if the Key does not map to a Node</returns> /// <remarks> /// The ability to provide a specific sequence of key bits may be useful for custom lookups where you don't necessarily have a value of the <strong>TKey</strong> type but do have values of the <strong>TKeyBit</strong> type /// </remarks> public ITrieNode <TKeyBit, TValue> Find(IEnumerable <TKeyBit> bs) { ITrieNode <TKeyBit, TValue> node = this._root; foreach (TKeyBit b in bs) { //Bail out early if key does not exist if (!node.TryGetChild(b, out node)) { return(null); } } return(node); }
/// <summary> /// Finds and returns a Node that has the longest prefix match for the given Key using the given Key to Key Bit mapping function /// </summary> /// <param name="bs">Key bits</param> /// <returns>Null if the Key does not map to a Node</returns> /// <remarks> /// The ability to provide a specific sequence of key bits may be useful for custom lookups where you don't necessarily have a value of the <strong>TKey</strong> type but do have values of the <strong>TKeyBit</strong> type /// </remarks> public ITrieNode <TKeyBit, TValue> FindPredecessor(IEnumerable <TKeyBit> bs) { ITrieNode <TKeyBit, TValue> node = this._root; ITrieNode <TKeyBit, TValue> predecessor = null; foreach (TKeyBit b in bs) { //Bail out early if key does not exist if (!node.TryGetChild(b, out node)) { return(predecessor); } if (node.HasValue) { predecessor = node; } } return(predecessor); }
/// <summary> /// Remove the value that a key leads to and any redundant nodes which result from this action /// </summary> /// <param name="key">Key of the value to remove</param> public void Remove(TKey key) { ITrieNode <TKeyBit, TValue> node = this._root; IEnumerable <TKeyBit> bs = this._keyMapper(key); foreach (TKeyBit b in bs) { //Bail out early if the key doesn't go anywhere if (!node.TryGetChild(b, out node)) { return; } } node.Value = null; //Remove all ancestor nodes which don't lead to a value. while (!node.IsRoot && !node.HasValue && node.Count == 0) { TKeyBit prevKey = node.KeyBit; node = node.Parent; node.RemoveChild(prevKey); } }