diff --git a/models/repo.go b/models/repo.go index 31d2f5f96..5b527e3cd 100755 --- a/models/repo.go +++ b/models/repo.go @@ -296,7 +296,6 @@ func (repo *Repository) ToCardFormat() *Repository4Card { } type ContributorInfo struct { - UserInfo *User // nil for contributor who is not a registered user RelAvatarLink string UserName string Email string diff --git a/modules/redis/redis_key/repo_redis_key.go b/modules/redis/redis_key/repo_redis_key.go new file mode 100644 index 000000000..b2b7ccd0a --- /dev/null +++ b/modules/redis/redis_key/repo_redis_key.go @@ -0,0 +1,9 @@ +package redis_key + +import "fmt" + +const REPO_PREFIX = "repo" + +func RepoTopNContributors(repoId int64, N int) string { + return KeyJoin(REPO_PREFIX, fmt.Sprint(repoId), fmt.Sprint(N), "top_n_contributor") +} diff --git a/services/repository/contributor.go b/services/repository/contributor.go index 896bc682d..817b4b086 100644 --- a/services/repository/contributor.go +++ b/services/repository/contributor.go @@ -3,14 +3,47 @@ package repository import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/redis/redis_client" + "code.gitea.io/gitea/modules/redis/redis_key" + "encoding/json" + "github.com/patrickmn/go-cache" + "time" ) +var repoContributorCache = cache.New(5*time.Minute, 1*time.Minute) + +type ContributorCacheVal struct { + Contributors []*models.ContributorInfo + Total int +} + func GetRepoTopNContributors(repo *models.Repository, N int) ([]*models.ContributorInfo, int) { - var contributorInfos []*models.ContributorInfo + val, _ := redis_client.Get(redis_key.RepoTopNContributors(repo.ID, N)) + if val != "" { + log.Debug("Get RepoTopNContributors from redis,repo.ID = %d value = %v", repo.ID, val) + temp := &ContributorCacheVal{} + json.Unmarshal([]byte(val), temp) + return temp.Contributors, temp.Total + } + + contributorInfos, total := getRepoTopNContributorsFromDisk(repo, N) + log.Debug("Get RepoTopNContributors from disk,repo.ID = %d ", repo.ID) + jsonVal, err := json.Marshal(&ContributorCacheVal{Contributors: contributorInfos, Total: total}) + if err == nil { + redis_client.Setex(redis_key.RepoTopNContributors(repo.ID, N), string(jsonVal), 5*time.Minute) + } + return contributorInfos, total +} + +func getRepoTopNContributorsFromDisk(repo *models.Repository, N int) ([]*models.ContributorInfo, int) { + contributorInfos := make([]*models.ContributorInfo, 0) + branchName := GetDefaultBranchName(repo) if branchName == "" { return contributorInfos, 0 } + contributors, err := git.GetContributors(repo.RepoPath(), branchName) if err == nil && contributors != nil { contributorInfoHash := make(map[string]*models.ContributorInfo) @@ -31,7 +64,7 @@ func GetRepoTopNContributors(repo *models.Repository, N int) ([]*models.Contribu } else { // new committer info var newContributor = &models.ContributorInfo{ - user, user.RelAvatarLink(), user.Name, user.Email, c.CommitCnt, + user.RelAvatarLink(), user.Name, user.Email, c.CommitCnt, } contributorInfos = append(contributorInfos, newContributor) contributorInfoHash[user.Email] = newContributor @@ -43,7 +76,7 @@ func GetRepoTopNContributors(repo *models.Repository, N int) ([]*models.Contribu existedContributorInfo.CommitCnt += c.CommitCnt } else { var newContributor = &models.ContributorInfo{ - user, "", "", c.Email, c.CommitCnt, + "", "", c.Email, c.CommitCnt, } contributorInfos = append(contributorInfos, newContributor) contributorInfoHash[c.Email] = newContributor