private static T Deserialize <T>(FactGraph graph, FactReference reference) { var emitter = new Emitter(graph, DeserializerCache.Empty); var runtimeFact = emitter.Deserialize <T>(reference); return(runtimeFact); }
public Task <ImmutableList <Fact> > Save(FactGraph graph, CancellationToken cancellationToken) { var newFacts = graph.FactReferences .Where(reference => !factsByReference.ContainsKey(reference)) .Select(reference => graph.GetFact(reference)) .ToImmutableList(); factsByReference = factsByReference.AddRange(newFacts .Select(fact => new KeyValuePair <FactReference, Fact>(fact.Reference, fact)) ); var newPredecessors = newFacts .Select(fact => ( factReference: fact.Reference, edges: fact.Predecessors .SelectMany(predecessor => CreateEdges(fact, predecessor)) .ToImmutableList() )) .ToImmutableList(); edges = edges.AddRange(newPredecessors .SelectMany(pair => pair.edges) ); foreach (var(factReference, edges) in newPredecessors) { ancestors = ancestors.Add( factReference, edges .SelectMany(edge => ancestors[edge.Predecessor]) .Append(factReference) .Distinct() .ToImmutableList() ); } return(Task.FromResult(newFacts)); }
public TFact Deserialize <TFact>(FactGraph graph, FactReference reference) { lock (this) { var emitter = new Emitter(graph, deserializerCache); var fact = emitter.Deserialize <TFact>(reference); deserializerCache = emitter.DeserializerCache; return(fact); } }
public ImmutableList <Product> Execute(ImmutableList <Product> products, FactGraph graph) { var results = products .SelectMany(product => ExecuteSteps(product.GetElement(Start.Name), graph) .Select(factReference => product.With(Target.Name, new SimpleElement(factReference)))) .ToImmutableList(); return(results); }
public async Task <ImmutableList <Fact> > Save(FactGraph graph, CancellationToken cancellationToken) { var added = await store.Save(graph, cancellationToken); foreach (var observer in observers) { await observer.FactsAdded(added, graph, cancellationToken); } return(added); }
private ImmutableList <FactReference> ExecuteSteps(Element element, FactGraph graph) { if (element is SimpleElement simple) { var startingFactReference = simple.FactReference; var startingSet = new FactReference[] { startingFactReference }.ToImmutableList(); var afterPredecessors = PredecessorSteps .Aggregate(startingSet, (set, predecessorStep) => ExecutePredecessorStep( set, predecessorStep.Role, predecessorStep.TargetType, graph )); return(afterPredecessors); } else { throw new NotImplementedException(); } }
public TFact Deserialize <TFact>(FactGraph graph, Element element) { if (element is SimpleElement simple) { lock (this) { var emitter = new Emitter(graph, deserializerCache); var fact = emitter.Deserialize <TFact>(simple.FactReference); deserializerCache = emitter.DeserializerCache; return(fact); } } else { throw new NotImplementedException(); } }
public ImmutableList <ProductAnchorProjection> DeserializeProductsFromGraph( FactGraph graph, Projection projection, ImmutableList <Product> products, Type type, Product anchor, string collectionName, IWatchContext?watchContext) { lock (this) { var emitter = new Emitter(graph, deserializerCache, watchContext); ImmutableList <ProductAnchorProjection> results = Deserializer.Deserialize(emitter, projection, type, products, anchor, collectionName); deserializerCache = emitter.DeserializerCache; return(results); } }
public async Task FactsAdded(ImmutableList <Fact> added, FactGraph graph, CancellationToken cancellationToken) { if (initialize == null) { return; } await initialize; var productsAdded = ImmutableList <(Product product, Inverse inverse)> .Empty; var productsRemoved = ImmutableList <Product> .Empty; var startReferences = added.Select(a => a.Reference).ToImmutableList(); foreach (var inverse in inverses) { var inversePipeline = inverse.InversePipeline; var matchingReferences = startReferences .Where(r => inversePipeline.Starts.Any(start => r.Type == start.Type)) .ToImmutableList(); if (matchingReferences.Any()) { var products = inversePipeline.CanRunOnGraph ? inversePipeline.Execute(startReferences, graph) : await factManager.Query( startReferences, new Specification(inversePipeline, specification.Projection), cancellationToken); foreach (var product in products) { var initialProduct = inverse.InitialSubset.Of(product); var identifyingProduct = inverse.FinalSubset.Of(product); if (initialProduct.Equals(this.initialAnchor)) { if (inverse.Operation == Operation.Add) { productsAdded = productsAdded.Add((identifyingProduct, inverse)); } else if (inverse.Operation == Operation.Remove) { productsRemoved = productsRemoved.Add(identifyingProduct); } } } } } if (productsAdded.Any()) { var products = productsAdded.Select(p => p.product).ToImmutableList(); var addedGraph = await factManager.LoadProducts(products, cancellationToken); var productAnchorProjections = DeserializeAllProducts(graph, productsAdded); var removals = await observation.NotifyAdded(productAnchorProjections); lock (this) { removalsByProduct = removalsByProduct.AddRange(removals); } } if (productsRemoved.Any()) { var removals = productsRemoved .Select(product => removalsByProduct.GetValueOrDefault(product) !) .Where(identity => identity != null) .ToImmutableList(); foreach (var removal in removals) { await removal(); } lock (this) { removalsByProduct = removalsByProduct.RemoveRange(productsRemoved); } } }
private ImmutableList <ProductAnchorProjection> DeserializeAllProducts(FactGraph graph, ImmutableList <(Product product, Inverse inverse)> productsAdded)
public Emitter(FactGraph graph, DeserializerCache deserializerCache, IWatchContext?watchContext = null) { this.graph = graph; DeserializerCache = deserializerCache; WatchContext = watchContext; }
private static ImmutableList <FactReference> ExecutePredecessorStep(ImmutableList <FactReference> set, string role, string targetType, FactGraph graph) { var results = set.SelectMany( factReference => graph .GetFact(factReference) .GetPredecessors(role) .Where(r => r.Type == targetType) ) .ToImmutableList(); return(results); }
public ImmutableList <Product> Execute(ImmutableList <FactReference> startReferences, FactGraph graph) { var start = starts.Single(); var initialTag = start.Name; var initialType = start.Type; var startingProducts = startReferences .Where(startReference => startReference.Type == initialType) .Select(startReference => Product.Empty.With(initialTag, new SimpleElement(startReference))) .ToImmutableList(); return(paths.Aggregate( startingProducts, (products, path) => path.Execute(products, graph) )); }
public ImmutableList <Product> Execute(FactReference startReference, FactGraph graph) { return(Execute(ImmutableList <FactReference> .Empty.Add(startReference), graph)); }