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:"-"`
Index int64
HeadRepoID int64 `xorm:"INDEX"`
HeadRepo *Repository `xorm:"-"`
BaseRepoID int64 `xorm:"INDEX"`
BaseRepo *Repository `xorm:"-"`
HeadUserName string
HeadBranch string
BaseBranch string
MergeBase string `xorm:"VARCHAR(40)"`
HeadRepoID int64 `xorm:"INDEX"`
HeadRepo *Repository `xorm:"-"`
BaseRepoID int64 `xorm:"INDEX"`
BaseRepo *Repository `xorm:"-"`
HeadUserName string
HeadBranch string
BaseBranch string
MergeBase string `xorm:"VARCHAR(40)"`
LastCommitID string `xorm:"-"`
HasMerged bool `xorm:"INDEX"`
MergedCommitID string `xorm:"VARCHAR(40)"`
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)
}
// GetLatestCommitStatuses returns all statuses with given repoIDs and shas
func GetLatestCommitStatuses(repoSHAs []struct {
RepoID int64
SHA string
}) ([][]*CommitStatus, error) {
// GetIssuesLatestCommitStatuses returns all statuses with given repoIDs and shas
func GetIssuesLatestCommitStatuses(issues []*Issue) ([][]*CommitStatus, error) {
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{
"repo_id": repoSHAs[i].RepoID,
"sha": repoSHAs[i].SHA,
"repo_id": issues[i].RepoID,
"sha": issues[i].PullRequest.LastCommitID,
})
}
var ids = make([]int64, 0, len(repoSHAs))
err := x.Table("commit_status").
var ids = make([]int64, 0, len(issues))
err = x.Table("commit_status").
Where(cond).
Select("max( id ) as id").
GroupBy("repo_id, sha, context").
@ -182,7 +203,7 @@ func GetLatestCommitStatuses(repoSHAs []struct {
return nil, err
}
var returns = make([][]*CommitStatus, len(repoSHAs))
var returns = make([][]*CommitStatus, len(issues))
if len(ids) == 0 {
return returns, nil
}
@ -193,14 +214,15 @@ func GetLatestCommitStatuses(repoSHAs []struct {
return nil, err
}
var repoIDsMap = make(map[string][]int64, len(repoSHAs))
var repoIDsMap = make(map[string][]int64, len(issues))
for _, status := range statuses {
key := fmt.Sprintf("%d-%s", status.RepoID, status.SHA)
repoIDsMap[key] = append(repoIDsMap[key], status.ID)
}
for i := 0; i < len(repoSHAs); i++ {
for _, id := range repoIDsMap[fmt.Sprintf("%d-%s", repoSHAs[i].RepoID, repoSHAs[i].SHA)] {
for i := 0; i < len(issues); i++ {
key := fmt.Sprintf("%d-%s", issues[i].RepoID, issues[i].PullRequest.LastCommitID)
for _, id := range repoIDsMap[key] {
returns[i] = append(returns[i], statuses[id])
}
}

View File

@ -209,83 +209,29 @@ func Issues(ctx *context.Context) {
}
}
if !isPullList {
// Get posters.
for i := 0; i < len(issues); i++ {
// Check read status
if !ctx.IsSigned {
issues[i].IsRead = true
} else if err = issues[i].GetIsRead(ctx.User.ID); err != nil {
ctx.ServerError("GetIsRead", err)
return
}
// Get posters.
for i := 0; i < len(issues); i++ {
// Check read status
if !ctx.IsSigned {
issues[i].IsRead = true
} else if err = issues[i].GetIsRead(ctx.User.ID); err != nil {
ctx.ServerError("GetIsRead", err)
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.
for i, issue := range issues {
// Check read status
if !ctx.IsSigned {
issues[i].IsRead = true
} 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)
}
if isPullList && len(issues) > 0 {
commitStatuses, err := models.GetIssuesLatestCommitStatuses(issues)
if err != nil {
ctx.ServerError("GetIssuesLatestCommitStatuses", err)
return
}
var issuesStates = make(map[int64]*models.CommitStatus, len(issues))
if len(repoSHAs) > 0 {
commitStatuses, err := models.GetLatestCommitStatuses(repoSHAs)
if err != nil {
ctx.ServerError("GetLatestCommitStatuses", err)
return
}
for i, statuses := range commitStatuses {
issuesStates[pullIDs[i]] = models.CalcCommitStatus(statuses)
}
for i, statuses := range commitStatuses {
issuesStates[issues[i].PullRequest.ID] = models.CalcCommitStatus(statuses)
}
ctx.Data["IssuesStates"] = issuesStates
}

View File

@ -9,11 +9,9 @@ import (
"fmt"
"sort"
"code.gitea.io/git"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
@ -293,69 +291,21 @@ func Issues(ctx *context.Context) {
return
}
if !isPullList {
for _, issue := range issues {
issue.Repo = showReposMap[issue.RepoID]
}
} 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)
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)
}
for _, issue := range issues {
issue.Repo = showReposMap[issue.RepoID]
}
if isPullList && len(issues) > 0 {
commitStatuses, err := models.GetIssuesLatestCommitStatuses(issues)
if err != nil {
ctx.ServerError("GetIssuesLatestCommitStatuses", err)
return
}
var issuesStates = make(map[int64]*models.CommitStatus, len(issues))
if len(repoSHAs) > 0 {
commitStatuses, err := models.GetLatestCommitStatuses(repoSHAs)
if err != nil {
ctx.ServerError("GetLatestCommitStatuses", err)
return
}
for i, statuses := range commitStatuses {
issuesStates[pullIDs[i]] = models.CalcCommitStatus(statuses)
}
for i, statuses := range commitStatuses {
issuesStates[issues[i].PullRequest.ID] = models.CalcCommitStatus(statuses)
}
ctx.Data["IssuesStates"] = issuesStates
}