public void BfsFrom(T start, Func <T, VisitPath, bool> visit) { Dictionary <T, T> visited = new Dictionary <T, T>(); Dictionary <T, T> frontier = new Dictionary <T, T>(); frontier.Add(start, start); int depth = 0; bool earlyExitRequested = false; while (frontier.Any() && !earlyExitRequested) { Dictionary <T, T> newFrontier = new Dictionary <T, T>(); foreach ((T node, T predecessor) in frontier) { if (visited.ContainsKey(node)) { // How does this happen? continue; } visited.Add(node, predecessor); VisitPath path = new VisitPath(node, start, depth, visited); earlyExitRequested = visit(node, path) || earlyExitRequested; foreach (T neighbour in GetNeighbours(node)) { if (!visited.ContainsKey(neighbour) && !newFrontier.ContainsKey(neighbour)) { newFrontier.Add(neighbour, node); } } } frontier = newFrontier; depth += 1; } }
protected override void Visit(VisitPath path, NotionPropertyConfiguration obj) { if (!path.Previous.HasValue) { return; } var optionalDatabaseObject = path.FindPrevious <DatabaseObject>(); if (!optionalDatabaseObject.HasValue) { _logger.LogWarning( "Unexpected path for property configuration. Did not find database that contains the property following path: {Path}", path.ToString()); return; } if (!obj.Container.HasValue) { obj.Container = optionalDatabaseObject.Value; } if (obj is RelationPropertyConfiguration relationPropertyConfiguration) { _notionCache.RegisterPropertyConfiguration( relationPropertyConfiguration.Configuration.DatabaseId, obj, relationPropertyConfiguration.Configuration.SyncedPropertyId); } _notionCache.RegisterPropertyConfiguration(optionalDatabaseObject.Value.Id, obj); }
private void UpdatePageContainer(VisitPath path, PageObject page, ParentPageReference pageReference) { var parentPage = _notionCache.GetPage(pageReference.PageId); if (!parentPage.HasValue) { _logger.LogTrace("Could not find page with id: {PageId} for page: {Path}", pageReference.PageId, path.ToString()); return; } page.Container = parentPage.Value; }
protected override void Visit(VisitPath path, NotionObject obj) { switch (obj) { case PageObject page: UpdatePageContainer(path, page); break; case DatabaseObject database: UpdateDatabaseContainer(path, database); break; } }
protected override void Visit(VisitPath path, NotionPropertyValue propertyValue) { propertyValue.Configuration = Option.None; if (!path.Previous.HasValue || !propertyValue.Id.HasValue) { return; } var optionalPageObject = path.FindPrevious <PageObject>(); if (!optionalPageObject.HasValue) { _logger.LogWarning( "Parent for property value with id: {PropertyId} is not a page, this is not expected. Path: {Path}", propertyValue.Id.Value, path.ToString()); return; } var pageObject = optionalPageObject.Value; propertyValue.Container = pageObject; if (!pageObject.Container.HasValue) { _logger.LogWarning("Container for page: {PageId} is not set", pageObject.Id); return; } if (!(pageObject.Container.Value is DatabaseObject parentDatabase)) { _logger.LogWarning( "Container for page: {PageId} is not a database, yet it has properties. This is not expected", pageObject.Id); return; } var propertyConfigurationId = propertyValue.Id.Value; var propertyConfiguration = _notionCache.GetPropertyConfiguration(parentDatabase.Id, propertyConfigurationId); if (!propertyConfiguration.HasValue) { _logger.LogTrace( "Could not find property configuration for id: {PropertyConfigurationId}, in database: {DatabaseId} for page: {PageId}", propertyConfigurationId, parentDatabase.Id, pageObject.Id); return; } propertyValue.Configuration = propertyConfiguration.Value; }
protected override void Visit(VisitPath path, NotionObject obj) { switch (obj) { case PageObject page: _notionCache.RegisterPage(page); break; case DatabaseObject database: _notionCache.RegisterDatabase(database); break; default: break; } }
private void UpdatePageContainer(VisitPath path, PageObject page) { page.Container = Option.None; var parent = page.Parent; switch (parent) { case ParentPageReference pageReference: UpdatePageContainer(path, page, pageReference); break; case ParentDatabaseReference databaseReference: UpdatePageContainer(path, page, databaseReference); break; } }
internal void VisitorThreadMain() { // Wait until all other threads have started int threadNumber; lock (this) { threadNumber = startedCount++; } while (startedCount != this.threadCount) { Yield(); } Random rng = new Random(threadNumber); VisitPath path = new VisitPath(this.nodes.Length); path.Initialize(); while (path.Cycles != this.maxCycles) { // Select a node previously unvisited in this cycle Node /*!*/ n = /*^(!)^*/ nodes[path.Pick(rng.Next())]; n.BeginVisit(); // Yield up to number of threads to give other // threads a chance to run int yieldCount = rng.Next(this.threadCount); while (yieldCount-- > 0) { Yield(); } n.EndVisit(); // Console.Write("[{0}]", threadNumber); this.generation++; } lock (this) { this.finishedCount++; if (this.finishedCount == this.threadCount) { this.finishedEvent.Set(); } } }
public VisitPath ShortestPathTo(T start, Func <T, bool> predicate) { VisitPath pathToGoal = null; BfsFrom(start, (node, path) => { if (predicate(node)) { pathToGoal = path; return(true); } else { return(false); } }); return(pathToGoal); }
private void UpdateDatabaseContainer(VisitPath path, DatabaseObject database) { database.Container = Option.None; var parent = database.Parent; if (!(parent is ParentPageReference pageReference)) { return; } var parentPage = _notionCache.GetPage(pageReference.PageId); if (!parentPage.HasValue) { _logger.LogTrace("Could not find page with id: {PageId} for database: {Path}", pageReference.PageId, path.ToString()); return; } database.Container = parentPage.Value; }