Esempio n. 1
0
        /// <summary>
        /// Match values in the tree
        /// </summary>
        public IEnumerable <IEnumerable <T> > Match(ITrieMatcher <T> matcher)
        {
            var prefix = new List <T>();
            var stack  = new Stack <KeyValuePair <Node, bool> >();

            if (root != null)
            {
                stack.Push(new KeyValuePair <Node, bool>(root, false));
            }

            while (stack.Count > 0)
            {
                var current = stack.Pop();
                if (current.Key == null)
                {
                    matcher.Pop();
                    prefix.RemoveAt(prefix.Count - 1);
                    continue;
                }

                if (current.Value)
                {
                    matcher.Next(current.Key.Split);
                    prefix.Add(current.Key.Split);

                    if (current.Key.IsFinal && matcher.IsFinal())
                    {
                        yield return(prefix);
                    }
                    continue;
                }

                if (current.Key.Hikid != null)
                {
                    stack.Push(new KeyValuePair <Node, bool>(current.Key.Hikid, false));
                }

                if (matcher.Next(current.Key.Split))
                {
                    matcher.Pop();

                    stack.Push(new KeyValuePair <Node, bool>(null, false));

                    if (current.Key.Eqkid != null)
                    {
                        stack.Push(new KeyValuePair <Node, bool>(current.Key.Eqkid, false));
                    }

                    stack.Push(new KeyValuePair <Node, bool>(current.Key, true));
                }

                if (current.Key.Lokid != null)
                {
                    stack.Push(new KeyValuePair <Node, bool>(current.Key.Lokid, false));
                }
            }
        }
Esempio n. 2
0
        public IEnumerable <TrieMatch <T> > Match(ITrieMatcher <T> matcher, TrieOrder order)
        {
            var stack = new Stack <IEnumerator <ChildLink> >();

            stack.Push(GetChildrenFromNode(root, order).GetEnumerator());

            var result = new List <T>();

            try
            {
                while (stack.Count > 0)
                {
                    var current = stack.Peek();
                    if (!current.MoveNext())
                    {
                        if (result.Count > 0)
                        {
                            matcher.Pop();
                            result.RemoveAt(result.Count - 1);
                        }

                        current.Dispose();
                        stack.Pop();
                        continue;
                    }

                    var key   = current.Current.Label;
                    var match = matcher.Next(key);

                    if (match)
                    {
                        result.Add(key);

                        //TODO: Improve performance by checking only intersection of next characters from matcher and children

                        var matchNode = current.Current.Node;
                        stack.Push(GetChildrenFromNode(matchNode, order).GetEnumerator());

                        if (matchNode.IsFinal && matcher.IsFinal())
                        {
                            yield return(new TrieMatch <T>(result));
                        }
                    }
                }
            }
            finally
            {
                while (stack.Count > 0)
                {
                    var current = stack.Peek();
                    if (result.Count > 0)
                    {
                        matcher.Pop();
                        result.RemoveAt(result.Count - 1);
                    }

                    current.Dispose();
                    stack.Pop();
                }
            }
        }