/// <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; } } }
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); }
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); } }
public Entry(uint key, ReverseTrie <T> value) { this.Key = key; this.Value = value; }