internal ChildrenContainer Clone() { ChildrenContainer container = new ChildrenContainer(KeyLength); container._children = new Dictionary <string[], Node>(_children, new NodeComparer(KeyLength)); return(container); }
public Node(string[] prefix, string pathToHere, int initialKeySize) { Prefix = prefix; _children = new ChildrenContainer(initialKeySize); Path = pathToHere + "/" + string.Join("/", Prefix); if (Path == "/") { Path = ""; } }
public void Compress() { bool canCompress = true; var children = System.Threading.Volatile.Read(ref _children); if (children.Count == 0) { return; } foreach (var kv in children) { if (kv.Value.Services.Count > 0) { canCompress = false; break; } } if (canCompress) { var newMerged = new ChildrenContainer(children.KeyLength + 1); foreach (var kv in children) { foreach (var childkv in kv.Value.Children) { //This will prune out orphaned trees if (childkv.Value.Services.Count > 0 || childkv.Value.Children.Count > 0) { var mergedKey = Enumerable.Concat(kv.Key, childkv.Key).ToArray(); var newNode = childkv.Value.CloneWithNewPrefix(mergedKey, Path); newMerged[newNode.Prefix] = newNode; } } } System.Threading.Volatile.Write(ref _children, newMerged); Compress(); } else { foreach (var kv in children) { kv.Value.Compress(); } } }
internal bool RemoveServiceFromRoute(string[] route, Service service) { ChildrenContainer container = System.Threading.Volatile.Read(ref _children); if (route.Length == 0) { return(Services.RemoveService(service)); } Node child; if (container.TryGetValue(route, out child)) { return(child.RemoveServiceFromRoute(route.Skip(container.KeyLength).ToArray(), service)); } return(false); }
public ChildrenContainer SplitContainer(int newKeyLength, string currentPath) { ChildrenContainer newContainer = new ChildrenContainer(newKeyLength); foreach (var kv in _children) { var newPrefix = kv.Key.Take(newKeyLength).ToArray(); var newTailPrefix = kv.Key.Skip(newKeyLength).ToArray(); Node newHeadNode; if (!newContainer._children.TryGetValue(newPrefix, out newHeadNode)) { newHeadNode = new Node(newPrefix, currentPath, KeyLength - newKeyLength); newContainer.Add(newPrefix, newHeadNode); } var oldNode = kv.Value.CloneWithNewPrefix(newTailPrefix, newHeadNode.Path); newHeadNode.Children.Add(newTailPrefix, oldNode); } return(newContainer); }
public Service GetService(string[] route, out string matchedPath) { ChildrenContainer container = System.Threading.Volatile.Read(ref _children); if (route.Length == 0) { matchedPath = Path; return(Services.GetService()); } Node child; if (container.TryGetValue(route, out child)) { var returnService = child.GetService(route.Skip(container.KeyLength).ToArray(), out matchedPath); if (returnService != null) { return(returnService); } } matchedPath = Path; return(Services.GetService()); }