loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Improve loadprojects for issue list (#25468)

authored by

Lunny Xiao and committed by
GitHub
083818cb 5eeddfde

+41 -30
+20 -18
models/issues/issue_list.go
··· 229 229 return nil 230 230 } 231 231 232 - func (issues IssueList) getProjectIDs() []int64 { 233 - ids := make(container.Set[int64], len(issues)) 234 - for _, issue := range issues { 235 - ids.Add(issue.ProjectID()) 236 - } 237 - return ids.Values() 238 - } 232 + func (issues IssueList) LoadProjects(ctx context.Context) error { 233 + issueIDs := issues.getIssueIDs() 234 + projectMaps := make(map[int64]*project_model.Project, len(issues)) 235 + left := len(issueIDs) 239 236 240 - func (issues IssueList) loadProjects(ctx context.Context) error { 241 - projectIDs := issues.getProjectIDs() 242 - if len(projectIDs) == 0 { 243 - return nil 237 + type projectWithIssueID struct { 238 + *project_model.Project `xorm:"extends"` 239 + IssueID int64 244 240 } 245 241 246 - projectMaps := make(map[int64]*project_model.Project, len(projectIDs)) 247 - left := len(projectIDs) 248 242 for left > 0 { 249 243 limit := db.DefaultMaxInSize 250 244 if left < limit { 251 245 limit = left 252 246 } 247 + 248 + projects := make([]*projectWithIssueID, 0, limit) 253 249 err := db.GetEngine(ctx). 254 - In("id", projectIDs[:limit]). 255 - Find(&projectMaps) 250 + Table("project"). 251 + Select("project.*, project_issue.issue_id"). 252 + Join("INNER", "project_issue", "project.id = project_issue.project_id"). 253 + In("project_issue.issue_id", issueIDs[:limit]). 254 + Find(&projects) 256 255 if err != nil { 257 256 return err 257 + } 258 + for _, project := range projects { 259 + projectMaps[project.IssueID] = project.Project 258 260 } 259 261 left -= limit 260 - projectIDs = projectIDs[limit:] 262 + issueIDs = issueIDs[limit:] 261 263 } 262 264 263 265 for _, issue := range issues { 264 - issue.Project = projectMaps[issue.ProjectID()] 266 + issue.Project = projectMaps[issue.ID] 265 267 } 266 268 return nil 267 269 } ··· 541 543 return fmt.Errorf("issue.loadAttributes: loadMilestones: %w", err) 542 544 } 543 545 544 - if err := issues.loadProjects(ctx); err != nil { 546 + if err := issues.LoadProjects(ctx); err != nil { 545 547 return fmt.Errorf("issue.loadAttributes: loadProjects: %w", err) 546 548 } 547 549
+4
models/issues/issue_list_test.go
··· 66 66 } 67 67 if issue.ID == int64(1) { 68 68 assert.Equal(t, int64(400), issue.TotalTrackedTime) 69 + assert.NotNil(t, issue.Project) 69 70 } else if issue.ID == int64(2) { 70 71 assert.Equal(t, int64(3682), issue.TotalTrackedTime) 72 + assert.Nil(t, issue.Project) 73 + } else { 74 + assert.Nil(t, issue.Project) 71 75 } 72 76 } 73 77 }
-5
models/issues/issue_project.go
··· 27 27 return err 28 28 } 29 29 30 - // ProjectID return project id if issue was assigned to one 31 - func (issue *Issue) ProjectID() int64 { 32 - return issue.projectID(db.DefaultContext) 33 - } 34 - 35 30 func (issue *Issue) projectID(ctx context.Context) int64 { 36 31 var ip project_model.ProjectIssue 37 32 has, err := db.GetEngine(ctx).Where("issue_id=?", issue.ID).Get(&ip)
+7 -2
routers/web/org/projects.go
··· 383 383 ctx.HTML(http.StatusOK, tplProjectsView) 384 384 } 385 385 386 - func getActionIssues(ctx *context.Context) []*issues_model.Issue { 386 + func getActionIssues(ctx *context.Context) issues_model.IssueList { 387 387 commaSeparatedIssueIDs := ctx.FormString("issue_ids") 388 388 if len(commaSeparatedIssueIDs) == 0 { 389 389 return nil ··· 429 429 return 430 430 } 431 431 432 + if err := issues.LoadProjects(ctx); err != nil { 433 + ctx.ServerError("LoadProjects", err) 434 + return 435 + } 436 + 432 437 projectID := ctx.FormInt64("id") 433 438 for _, issue := range issues { 434 - oldProjectID := issue.ProjectID() 439 + oldProjectID := issue.Project.ID 435 440 if oldProjectID == projectID { 436 441 continue 437 442 }
+2 -2
routers/web/repo/issue.go
··· 1984 1984 } 1985 1985 } 1986 1986 1987 - func getActionIssues(ctx *context.Context) []*issues_model.Issue { 1987 + func getActionIssues(ctx *context.Context) issues_model.IssueList { 1988 1988 commaSeparatedIssueIDs := ctx.FormString("issue_ids") 1989 1989 if len(commaSeparatedIssueIDs) == 0 { 1990 1990 return nil ··· 2749 2749 log.Warn("Unrecognized action: %s", action) 2750 2750 } 2751 2751 2752 - if _, err := issues_model.IssueList(issues).LoadRepositories(ctx); err != nil { 2752 + if _, err := issues.LoadRepositories(ctx); err != nil { 2753 2753 ctx.ServerError("LoadRepositories", err) 2754 2754 return 2755 2755 }
+6 -1
routers/web/repo/projects.go
··· 378 378 return 379 379 } 380 380 381 + if err := issues.LoadProjects(ctx); err != nil { 382 + ctx.ServerError("LoadProjects", err) 383 + return 384 + } 385 + 381 386 projectID := ctx.FormInt64("id") 382 387 for _, issue := range issues { 383 - oldProjectID := issue.ProjectID() 388 + oldProjectID := issue.Project.ID 384 389 if oldProjectID == projectID { 385 390 continue 386 391 }
+2 -2
templates/repo/issue/view_content/sidebar.tmpl
··· 192 192 </div> 193 193 </div> 194 194 <div class="ui select-project list"> 195 - <span class="no-select item {{if .Issue.ProjectID}}gt-hidden{{end}}">{{.locale.Tr "repo.issues.new.no_projects"}}</span> 195 + <span class="no-select item {{if .Issue.Project}}gt-hidden{{end}}">{{.locale.Tr "repo.issues.new.no_projects"}}</span> 196 196 <div class="selected"> 197 - {{if .Issue.ProjectID}} 197 + {{if .Issue.Project}} 198 198 <a class="item muted sidebar-item-link" href="{{.Issue.Project.Link}}"> 199 199 {{svg .Issue.Project.IconName 18 "gt-mr-3"}}{{.Issue.Project.Title}} 200 200 </a>