improve GetIssuesLatestCommitStatuses

This commit is contained in:
Lunny Xiao 2017-11-28 09:45:44 +08:00
parent 9fec58c67c
commit bb029b1f24
No known key found for this signature in database
GPG Key ID: C3B7C91B632F738A
4 changed files with 73 additions and 155 deletions

View File

@ -60,15 +60,15 @@ type PullRequest struct {
Issue *Issue `xorm:"-"` Issue *Issue `xorm:"-"`
Index int64 Index int64
HeadRepoID int64 `xorm:"INDEX"` HeadRepoID int64 `xorm:"INDEX"`
HeadRepo *Repository `xorm:"-"` HeadRepo *Repository `xorm:"-"`
BaseRepoID int64 `xorm:"INDEX"` BaseRepoID int64 `xorm:"INDEX"`
BaseRepo *Repository `xorm:"-"` BaseRepo *Repository `xorm:"-"`
HeadUserName string HeadUserName string
HeadBranch string HeadBranch string
BaseBranch string BaseBranch string
MergeBase string `xorm:"VARCHAR(40)"` MergeBase string `xorm:"VARCHAR(40)"`
LastCommitID string `xorm:"-"`
HasMerged bool `xorm:"INDEX"` HasMerged bool `xorm:"INDEX"`
MergedCommitID string `xorm:"VARCHAR(40)"` MergedCommitID string `xorm:"VARCHAR(40)"`
MergerID int64 `xorm:"INDEX"` MergerID int64 `xorm:"INDEX"`

View File

@ -158,21 +158,42 @@ func GetLatestCommitStatus(repo *Repository, sha string, page int) ([]*CommitSta
return statuses, x.In("id", ids).Find(&statuses) return statuses, x.In("id", ids).Find(&statuses)
} }
// GetLatestCommitStatuses returns all statuses with given repoIDs and shas // GetIssuesLatestCommitStatuses returns all statuses with given repoIDs and shas
func GetLatestCommitStatuses(repoSHAs []struct { func GetIssuesLatestCommitStatuses(issues []*Issue) ([][]*CommitStatus, error) {
RepoID int64
SHA string
}) ([][]*CommitStatus, error) {
var cond = builder.NewCond() var cond = builder.NewCond()
for i := 0; i < len(repoSHAs); i++ { var repoCache = make(map[int64]*git.Repository)
var err error
for i := 0; i < len(issues); i++ {
var gitRepo *git.Repository
var ok bool
if gitRepo, ok = repoCache[issues[i].PullRequest.HeadRepoID]; !ok {
if err := issues[i].PullRequest.GetHeadRepo(); err != nil {
log.Error(4, "GetHeadRepo[%d, %d]: %v", issues[i].PullRequest.ID, issues[i].PullRequest.HeadRepoID, err)
continue
}
gitRepo, err = git.OpenRepository(issues[i].PullRequest.HeadRepo.RepoPath())
if err != nil {
log.Error(4, "OpenRepository[%d, %s]: %v", issues[i].PullRequest.ID, issues[i].PullRequest.HeadRepo.RepoPath(), err)
continue
}
repoCache[issues[i].PullRequest.HeadRepoID] = gitRepo
}
issues[i].PullRequest.LastCommitID, err = gitRepo.GetBranchCommitID(issues[i].PullRequest.HeadBranch)
if err != nil {
log.Error(4, "GetBranchCommitID[%d, %s]: %v", issues[i].PullRequest.ID, issues[i].PullRequest.HeadBranch, err)
continue
}
cond = cond.Or(builder.Eq{ cond = cond.Or(builder.Eq{
"repo_id": repoSHAs[i].RepoID, "repo_id": issues[i].RepoID,
"sha": repoSHAs[i].SHA, "sha": issues[i].PullRequest.LastCommitID,
}) })
} }
var ids = make([]int64, 0, len(repoSHAs)) var ids = make([]int64, 0, len(issues))
err := x.Table("commit_status"). err = x.Table("commit_status").
Where(cond). Where(cond).
Select("max( id ) as id"). Select("max( id ) as id").
GroupBy("repo_id, sha, context"). GroupBy("repo_id, sha, context").
@ -182,7 +203,7 @@ func GetLatestCommitStatuses(repoSHAs []struct {
return nil, err return nil, err
} }
var returns = make([][]*CommitStatus, len(repoSHAs)) var returns = make([][]*CommitStatus, len(issues))
if len(ids) == 0 { if len(ids) == 0 {
return returns, nil return returns, nil
} }
@ -193,14 +214,15 @@ func GetLatestCommitStatuses(repoSHAs []struct {
return nil, err return nil, err
} }
var repoIDsMap = make(map[string][]int64, len(repoSHAs)) var repoIDsMap = make(map[string][]int64, len(issues))
for _, status := range statuses { for _, status := range statuses {
key := fmt.Sprintf("%d-%s", status.RepoID, status.SHA) key := fmt.Sprintf("%d-%s", status.RepoID, status.SHA)
repoIDsMap[key] = append(repoIDsMap[key], status.ID) repoIDsMap[key] = append(repoIDsMap[key], status.ID)
} }
for i := 0; i < len(repoSHAs); i++ { for i := 0; i < len(issues); i++ {
for _, id := range repoIDsMap[fmt.Sprintf("%d-%s", repoSHAs[i].RepoID, repoSHAs[i].SHA)] { key := fmt.Sprintf("%d-%s", issues[i].RepoID, issues[i].PullRequest.LastCommitID)
for _, id := range repoIDsMap[key] {
returns[i] = append(returns[i], statuses[id]) returns[i] = append(returns[i], statuses[id])
} }
} }

View File

@ -209,83 +209,29 @@ func Issues(ctx *context.Context) {
} }
} }
if !isPullList { // Get posters.
// Get posters. for i := 0; i < len(issues); i++ {
for i := 0; i < len(issues); i++ { // Check read status
// Check read status if !ctx.IsSigned {
if !ctx.IsSigned { issues[i].IsRead = true
issues[i].IsRead = true } else if err = issues[i].GetIsRead(ctx.User.ID); err != nil {
} else if err = issues[i].GetIsRead(ctx.User.ID); err != nil { ctx.ServerError("GetIsRead", err)
ctx.ServerError("GetIsRead", err) return
return
}
} }
} else { }
var repoSHAs = make([]struct {
RepoID int64
SHA string
}, 0, len(issues))
var pullIDs = make([]int64, 0, len(issues))
var repoCache = make(map[int64]*git.Repository)
// Get posters. if isPullList && len(issues) > 0 {
for i, issue := range issues { commitStatuses, err := models.GetIssuesLatestCommitStatuses(issues)
// Check read status if err != nil {
if !ctx.IsSigned { ctx.ServerError("GetIssuesLatestCommitStatuses", err)
issues[i].IsRead = true return
} else if err = issues[i].GetIsRead(ctx.User.ID); err != nil {
ctx.ServerError("GetIsRead", err)
return
}
if err := issue.LoadAttributes(); err != nil {
ctx.ServerError("LoadAttributes", err)
return
}
var gitRepo *git.Repository
var ok bool
if gitRepo, ok = repoCache[issue.PullRequest.HeadRepoID]; !ok {
if err := issue.PullRequest.GetHeadRepo(); err != nil {
ctx.ServerError("GetHeadRepo", err)
return
}
gitRepo, err = git.OpenRepository(issue.PullRequest.HeadRepo.RepoPath())
if err != nil {
ctx.ServerError("OpenRepository", err)
return
}
repoCache[issue.PullRequest.HeadRepoID] = gitRepo
}
sha, err := gitRepo.GetBranchCommitID(issue.PullRequest.HeadBranch)
if err != nil {
log.Error(4, "GetBranchCommitID: %v", err)
} else {
repoSHAs = append(repoSHAs, struct {
RepoID int64
SHA string
}{
RepoID: issue.RepoID,
SHA: sha,
})
pullIDs = append(pullIDs, issue.ID)
}
} }
var issuesStates = make(map[int64]*models.CommitStatus, len(issues)) var issuesStates = make(map[int64]*models.CommitStatus, len(issues))
if len(repoSHAs) > 0 { for i, statuses := range commitStatuses {
commitStatuses, err := models.GetLatestCommitStatuses(repoSHAs) issuesStates[issues[i].PullRequest.ID] = models.CalcCommitStatus(statuses)
if err != nil {
ctx.ServerError("GetLatestCommitStatuses", err)
return
}
for i, statuses := range commitStatuses {
issuesStates[pullIDs[i]] = models.CalcCommitStatus(statuses)
}
} }
ctx.Data["IssuesStates"] = issuesStates ctx.Data["IssuesStates"] = issuesStates
} }

View File

@ -9,11 +9,9 @@ import (
"fmt" "fmt"
"sort" "sort"
"code.gitea.io/git"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
@ -293,69 +291,21 @@ func Issues(ctx *context.Context) {
return return
} }
if !isPullList { for _, issue := range issues {
for _, issue := range issues { issue.Repo = showReposMap[issue.RepoID]
issue.Repo = showReposMap[issue.RepoID] }
} if isPullList && len(issues) > 0 {
} else { commitStatuses, err := models.GetIssuesLatestCommitStatuses(issues)
var repoSHAs = make([]struct { if err != nil {
RepoID int64 ctx.ServerError("GetIssuesLatestCommitStatuses", err)
SHA string return
}, 0, len(issues))
var pullIDs = make([]int64, 0, len(issues))
var repoCache = make(map[int64]*git.Repository)
for _, issue := range issues {
issue.Repo = showReposMap[issue.RepoID]
if err := issue.LoadAttributes(); err != nil {
ctx.ServerError("LoadAttributes", fmt.Errorf("%v", err))
return
}
var gitRepo *git.Repository
var ok bool
if gitRepo, ok = repoCache[issue.PullRequest.HeadRepoID]; !ok {
if err := issue.PullRequest.GetHeadRepo(); err != nil {
ctx.ServerError("GetHeadRepo", err)
return
}
gitRepo, err = git.OpenRepository(issue.PullRequest.HeadRepo.RepoPath())
if err != nil {
ctx.ServerError("OpenRepository", err)
return
}
repoCache[issue.PullRequest.HeadRepoID] = gitRepo
}
sha, err := gitRepo.GetBranchCommitID(issue.PullRequest.HeadBranch)
if err != nil {
log.Error(4, "GetBranchCommitID: %v", err)
} else {
repoSHAs = append(repoSHAs, struct {
RepoID int64
SHA string
}{
RepoID: issue.RepoID,
SHA: sha,
})
pullIDs = append(pullIDs, issue.ID)
}
} }
var issuesStates = make(map[int64]*models.CommitStatus, len(issues)) var issuesStates = make(map[int64]*models.CommitStatus, len(issues))
if len(repoSHAs) > 0 { for i, statuses := range commitStatuses {
commitStatuses, err := models.GetLatestCommitStatuses(repoSHAs) issuesStates[issues[i].PullRequest.ID] = models.CalcCommitStatus(statuses)
if err != nil {
ctx.ServerError("GetLatestCommitStatuses", err)
return
}
for i, statuses := range commitStatuses {
issuesStates[pullIDs[i]] = models.CalcCommitStatus(statuses)
}
} }
ctx.Data["IssuesStates"] = issuesStates ctx.Data["IssuesStates"] = issuesStates
} }