Skip to content

Commit

Permalink
Add cache for branch divergence on branch list page (#29577)
Browse files Browse the repository at this point in the history
The branch page for blender project will take 6s because calculating
divergence is very slow.
This PR will add a cache for the branch divergence calculation. So when
the second visit the branch list, it will take only less 200ms.
  • Loading branch information
lunny authored Mar 8, 2024
1 parent f219ea8 commit 930bae2
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 6 deletions.
55 changes: 49 additions & 6 deletions services/repository/branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/queue"
Expand Down Expand Up @@ -99,7 +101,6 @@ func LoadBranches(ctx context.Context, repo *repo_model.Repository, gitRepo *git
if err != nil {
return nil, nil, 0, fmt.Errorf("loadOneBranch: %v", err)
}

branches = append(branches, branch)
}

Expand All @@ -109,10 +110,44 @@ func LoadBranches(ctx context.Context, repo *repo_model.Repository, gitRepo *git
if err != nil {
return nil, nil, 0, fmt.Errorf("loadOneBranch: %v", err)
}

return defaultBranch, branches, totalNumOfBranches, nil
}

func getDivergenceCacheKey(repoID int64, branchName string) string {
return fmt.Sprintf("%d-%s", repoID, branchName)
}

// getDivergenceFromCache gets the divergence from cache
func getDivergenceFromCache(repoID int64, branchName string) (*git.DivergeObject, bool) {
data := cache.GetCache().Get(getDivergenceCacheKey(repoID, branchName))
res := git.DivergeObject{
Ahead: -1,
Behind: -1,
}
s, ok := data.([]byte)
if !ok || len(s) == 0 {
return &res, false
}

if err := json.Unmarshal(s, &res); err != nil {
log.Error("json.UnMarshal failed: %v", err)
return &res, false
}
return &res, true
}

func putDivergenceFromCache(repoID int64, branchName string, divergence *git.DivergeObject) error {
bs, err := json.Marshal(divergence)
if err != nil {
return err
}
return cache.GetCache().Put(getDivergenceCacheKey(repoID, branchName), bs, 30*24*60*60)
}

func DelDivergenceFromCache(repoID int64, branchName string) error {
return cache.GetCache().Delete(getDivergenceCacheKey(repoID, branchName))
}

func loadOneBranch(ctx context.Context, repo *repo_model.Repository, dbBranch *git_model.Branch, protectedBranches *git_model.ProtectedBranchRules,
repoIDToRepo map[int64]*repo_model.Repository,
repoIDToGitRepo map[int64]*git.Repository,
Expand All @@ -130,10 +165,18 @@ func loadOneBranch(ctx context.Context, repo *repo_model.Repository, dbBranch *g

// it's not default branch
if repo.DefaultBranch != dbBranch.Name && !dbBranch.IsDeleted {
var err error
divergence, err = files_service.CountDivergingCommits(ctx, repo, git.BranchPrefix+branchName)
if err != nil {
log.Error("CountDivergingCommits: %v", err)
var cached bool
divergence, cached = getDivergenceFromCache(repo.ID, dbBranch.Name)
if !cached {
var err error
divergence, err = files_service.CountDivergingCommits(ctx, repo, git.BranchPrefix+branchName)
if err != nil {
log.Error("CountDivergingCommits: %v", err)
} else {
if err = putDivergenceFromCache(repo.ID, dbBranch.Name, divergence); err != nil {
log.Error("putDivergenceFromCache: %v", err)
}
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions services/repository/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
}
}

// delete cache for divergence
if err := DelDivergenceFromCache(repo.ID, branch); err != nil {
log.Error("DelDivergenceFromCache: %v", err)
}

commits := repo_module.GitToPushCommits(l)
commits.HeadCommit = repo_module.CommitToPushCommit(newCommit)

Expand Down

0 comments on commit 930bae2

Please sign in to comment.