Пример #1
0
        /// <summary>
        /// Retrieves a set of values.
        /// </summary>
        /// <param name="query">The query to retrieve.</param>
        /// <param name="position">The position.</param>
        /// <returns></returns>
        public IEnumerable <T> Match(uint[] query)
        {
            // Get the matching stack
            var             matches = new ReverseTrie <T> [8];
            var             matchesCount = 0;
            var             queryLength = query.Length;
            ReverseTrie <T> childNode, current;

            // Push a new match to the stack
            if (matchesCount + 1 >= matches.Length)
            {
                Array.Resize(ref matches, (matches.Length + 1) * 2);
            }
            matches[matchesCount++] = this;

            // While we have matches
            while (matchesCount != 0)
            {
                // Pop the current value from the stack
                current = matches[--matchesCount];
                matches[matchesCount] = default(ReverseTrie <T>);

                if (current.Value != default(T))
                {
                    yield return(current.Value);
                }

                var level = current.Level + 1;
                if (level >= queryLength)
                {
                    continue;
                }

                if (current.ChildTryGet(1815237614, out childNode))
                {
                    if (matchesCount + 1 >= matches.Length)
                    {
                        Array.Resize(ref matches, (matches.Length + 1) * 2);
                    }
                    matches[matchesCount++] = childNode;
                }

                if (current.ChildTryGet(query[level], out childNode))
                {
                    if (matchesCount + 1 >= matches.Length)
                    {
                        Array.Resize(ref matches, (matches.Length + 1) * 2);
                    }
                    matches[matchesCount++] = childNode;
                }
            }
        }
Пример #2
0
        public bool ChildTryGet(uint key, out ReverseTrie <T> value)
        {
            if (this.Children != null)
            {
                return(this.Children.TryGetValue(key, out value));
            }

            var idx = FlatSearch(key);

            if (idx < 0)
            {
                value = null;
                return(false);
            }

            value = this.Flat[idx].Value;
            return(true);
        }
Пример #3
0
        public ReverseTrie <T> FlatGetOrAdd(uint key, ReverseTrie <T> value)
        {
            var idx = FlatSearch(key);

            if (idx < 0)
            {
                lock (this.Flat)
                {
                    // First, we check if we need to promote this node to a dictionary.
                    var length = this.Flat.Length;
                    if (length >= CutoffPoint)
                    {
                        var map = new ConcurrentDictionary <uint, ReverseTrie <T> >(Environment.ProcessorCount, 16);
                        for (int i = 0; i < length; ++i)
                        {
                            var item = this.Flat[i];
                            map.TryAdd(item.Key, item.Value);
                        }

                        // Scrap the old array how that we have a dictionary
                        this.Children = map;
                        this.Flat     = null;
                    }
                    else
                    {
                        // If we still have space, copy and add
                        var target = this.Flat;
                        var result = new Entry[target.Length + 1];
                        target.CopyTo(result, 0);
                        result[target.Length] = new Entry(key, value);
                        this.Flat             = result;
                    }
                }

                return(value);
            }
            else
            {
                return(this.Flat[idx].Value);
            }
        }
Пример #4
0
 public Entry(uint key, ReverseTrie <T> value)
 {
     this.Key   = key;
     this.Value = value;
 }