public static void ReverseVisit <T>(this ITreeEnumeratorAdvisor <T> iteratorAdvisor, IEnumerator <T> treeItemsEnumerator, Action <T, AncestorsEnumerator <T> > visitor) where T : class { using var enumerator = TreeEnumerator.GetReverseEnumerator(treeItemsEnumerator, iteratorAdvisor); while (enumerator.MoveNext()) { visitor(enumerator.Current, enumerator.CurrentAncestors); } }
public static void ReverseVisit <T>(this ITreeEnumeratorAdvisor <T> iteratorAdvisor, T root, Action <T> visitor) where T : class { using var enumerator = TreeEnumerator.GetReverseEnumerator(root, iteratorAdvisor); while (enumerator.MoveNext()) { visitor(enumerator.Current); } }
public static void Visit <T>(this ITreeEnumeratorAdvisor <T> iteratorAdvisor, T root, Action <T, AncestorsEnumerator <T> > visitor) where T : class { using var enumerator = TreeEnumerator.GetEnumerator(root, iteratorAdvisor); while (enumerator.MoveNext()) { visitor(enumerator.Current, enumerator.CurrentAncestors); } }
public static void Visit <T>(this ITreeEnumeratorAdvisor <T> iteratorAdvisor, IEnumerator <T> treeItemsEnumerator, Action <T> visitor) where T : class { using var enumerator = TreeEnumerator.GetEnumerator(treeItemsEnumerator, iteratorAdvisor); while (enumerator.MoveNext()) { visitor(enumerator.Current); } }
private bool ResolveDependencies() { var result = true; TreeEnumerator.Visit(Root, SkinDictionary.SkinDictionaryTreeAdvisor, s => { if (s.BasedOnInternal == null || s.BasedOnInternal.Count == 0) { return; } for (var index = 0; index < s.BasedOn.Count; index++) { var basedOn = s.BasedOn[index]; if (basedOn.IsDeferred == false || basedOn.IsAbsoluteKey == false) { continue; } object resolved; if (Root.TryGetValue(basedOn.DeferredKey, out resolved) == false) { result = false; continue; } var resolvedSkin = resolved as SkinDictionary; if (resolvedSkin != null) { s.BasedOn[index] = resolvedSkin; } else { result = false; } } }); return(result); }
internal void Verify() { var treeFlatCountAdvisor = new DelegateTreeEnumeratorAdvisor <TNode>(n => n.Nodes?.GetEnumerator() ?? Enumerable.Empty <TNode>().GetEnumerator()); var treeVisibleFlatCountAdvisor = new DelegateTreeEnumeratorAdvisor <TNode>(n => n.IsExpanded ? n.Nodes.GetEnumerator() : Enumerable.Empty <TNode>().GetEnumerator()); var flatCount = Nodes != null?TreeEnumerator.GetEnumerator(Nodes, treeFlatCountAdvisor).Enumerate().Count() : 0; var visibleCount = IsExpanded ? TreeEnumerator.GetEnumerator(Nodes, treeVisibleFlatCountAdvisor).Enumerate().Count() : 0; if (FlatCount != flatCount) { throw new Exception(nameof(FlatCount)); } if (VisibleFlatCount != visibleCount) { throw new Exception(nameof(VisibleFlatCount)); } }
public void Dispose_MustBeExecuting_Ok() { // Данные для теста var items = TreeItemHelper.Generate_ForDisposeTest(); // Подсчёт вызовов var counter = new Counter(); // Тестовые итераторы var head = new CustomEnumerable(items.Where(a => a.ParentId == 0), counter); // 1 call = 1 disposing IEnumerable <TreeItem> GetChildren(TreeItem item) => new CustomEnumerable(items.Where(a => a.ParentId == item.Id).OrderBy(a => a.Id), counter); // 4 elements = 5 calls = 5 disposing (try get subelements at Id=5) // Шаблон формирования дерева с использованием итератора с контекстом using (var enumerator = new TreeEnumerator <TreeItem>(head, GetChildren)) { while (enumerator.MoveNext()) { } } // total 6 calls Assert.Equal(6, counter.DisposeCount); }
public void Reset_MustNotSupportedException_Ok() { // Данные для теста var items = TreeItemHelper.Generate_ForDisposeTest(); // Подсчёт вызовов var counter = new Counter(); // Тестовые итераторы var head = new CustomEnumerable(items.Where(a => a.ParentId == 0), counter); // 1 call = 1 disposing IEnumerable <TreeItem> GetChildren(TreeItem item) => new CustomEnumerable(items.Where(a => a.ParentId == item.Id).OrderBy(a => a.Id), counter); // 4 elements = 5 calls = 5 disposing (try get subelements at Id=5) // Шаблон формирования дерева с использованием итератора с контекстом using (var enumerator = new TreeEnumerator <TreeItem>(head, GetChildren)) { int i = 0; while (enumerator.MoveNext()) { // i = 0 - current=head // i = 1 - current=sub 1 head 1 // i = 2 - current=sub 1 head 2 // i = 3 - current=sub 1 head 3 // i = 4 - current=sub 1 head 4 if (i == 4) { // enumerator has stack with 5 elements Assert.Throws <NotSupportedException>(() => enumerator.Reset()); break; } i++; } } }
internal IEnumerable <KeyValuePair <string, object> > Flatten() { return(TreeEnumerator.GetEnumerator(this, ResourceTreeAdvisor).Enumerate()); }
public override async Task MatchAsync(HttpContext httpContext, IEndpointFeature feature) { if (httpContext == null) { throw new ArgumentNullException(nameof(httpContext)); } if (feature == null) { throw new ArgumentNullException(nameof(feature)); } var values = new RouteValueDictionary(); feature.Values = values; var cache = _cache.Value; for (var i = 0; i < cache.Length; i++) { var tree = cache[i]; var tokenizer = new PathTokenizer(httpContext.Request.Path); var treenumerator = new TreeEnumerator(tree.Root, tokenizer); while (treenumerator.MoveNext()) { var node = treenumerator.Current; foreach (var item in node.Matches) { var entry = item.Entry; var matcher = item.TemplateMatcher; values.Clear(); if (!matcher.TryMatch(httpContext.Request.Path, values)) { continue; } Log.MatchedTemplate(_logger, httpContext, entry.RouteTemplate); if (!MatchConstraints(httpContext, values, entry.Constraints)) { continue; } await SelectEndpointAsync(httpContext, feature, (MatcherEndpoint[])entry.Tag); if (feature.Endpoint != null) { if (feature.Endpoint is MatcherEndpoint endpoint) { foreach (var kvp in endpoint.Values) { if (!feature.Values.ContainsKey(kvp.Key)) { feature.Values[kvp.Key] = kvp.Value; } } } return; } } } } }
public async Task RouteAsync(RouteContext context) { foreach (var tree in _trees) { var tokenizer = new PathTokenizer(context.HttpContext.Request.Path); var root = tree.Root; var treeEnumerator = new TreeEnumerator(root, tokenizer); // Create a snapshot before processing the route. We'll restore this snapshot before running each // to restore the state. This is likely an "empty" snapshot, which doesn't allocate. var snapshot = context.RouteData.PushState(router: null, values: null, dataTokens: null); while (treeEnumerator.MoveNext()) { var node = treeEnumerator.Current; foreach (var item in node.Matches) { var entry = item.Entry; var matcher = item.TemplateMatcher; try { if (!matcher.TryMatch(context.HttpContext.Request.Path, context.RouteData.Values)) { continue; } if (!RouteConstraintMatcher.Match( entry.Constraints, context.RouteData.Values, context.HttpContext, this, RouteDirection.IncomingRequest, _constraintLogger)) { continue; } Log.RequestMatchedRoute(_logger, entry.RouteName, entry.RouteTemplate.TemplateText); context.RouteData.Routers.Add(entry.Handler); await entry.Handler.RouteAsync(context); if (context.Handler != null) { return; } } finally { if (context.Handler == null) { // Restore the original values to prevent polluting the route data. snapshot.Restore(); } } } } } }
public static ITreeEnumerator <T> GetReverseEnumerator <T>(this ITreeEnumeratorAdvisor <T> advisor, IEnumerator <T> treeItemsEnumerator) where T : class { return(TreeEnumerator.GetReverseEnumerator(treeItemsEnumerator, advisor)); }
public static ITreeEnumerator <T> GetReverseEnumerator <T>(this ITreeEnumeratorAdvisor <T> advisor, T root) where T : class { return(TreeEnumerator.GetReverseEnumerator(root, advisor)); }