Exemplo n.º 1
0
        /// <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);
            }
        }
Exemplo n.º 2
0
        /// <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);
        }
Exemplo n.º 3
0
        /// <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);
        }
Exemplo n.º 4
0
        /// <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);
        }
Exemplo n.º 5
0
        /// <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);
            }
        }