aboutsummaryrefslogtreecommitdiffstats
path: root/modules/git/last_commit_cache.go
diff options
context:
space:
mode:
authorzeripath <art27@cantab.net>2022-07-25 16:39:42 +0100
committerGitHub <noreply@github.com>2022-07-25 16:39:42 +0100
commita2cfcdb91a9098381bb1d71ebdf56baed4c0981d (patch)
tree43e1bf303236353fe339e33637764b82c5414954 /modules/git/last_commit_cache.go
parent690272d2e24846390d785a1f053af6c7ba5963a3 (diff)
downloadgitea-a2cfcdb91a9098381bb1d71ebdf56baed4c0981d.tar.gz
gitea-a2cfcdb91a9098381bb1d71ebdf56baed4c0981d.zip
Slightly simplify LastCommitCache (#20444)
The LastCommitCache code is a little complex and there is unnecessary duplication between the gogit and nogogit variants. This PR adds the LastCommitCache as a field to the git.Repository and pre-creates it in the ReferencesGit helpers etc. There has been some simplification and unification of the variant code. Signed-off-by: Andrew Thornton <art27@cantab.net>
Diffstat (limited to 'modules/git/last_commit_cache.go')
-rw-r--r--modules/git/last_commit_cache.go87
1 files changed, 84 insertions, 3 deletions
diff --git a/modules/git/last_commit_cache.go b/modules/git/last_commit_cache.go
index d4ec517b51..2b51d59720 100644
--- a/modules/git/last_commit_cache.go
+++ b/modules/git/last_commit_cache.go
@@ -9,6 +9,7 @@ import (
"fmt"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
)
// Cache represents a caching interface
@@ -19,16 +20,96 @@ type Cache interface {
Get(key string) interface{}
}
-func (c *LastCommitCache) getCacheKey(repoPath, ref, entryPath string) string {
- hashBytes := sha256.Sum256([]byte(fmt.Sprintf("%s:%s:%s", repoPath, ref, entryPath)))
+func getCacheKey(repoPath, commitID, entryPath string) string {
+ hashBytes := sha256.Sum256([]byte(fmt.Sprintf("%s:%s:%s", repoPath, commitID, entryPath)))
return fmt.Sprintf("last_commit:%x", hashBytes)
}
+// LastCommitCache represents a cache to store last commit
+type LastCommitCache struct {
+ repoPath string
+ ttl func() int64
+ repo *Repository
+ commitCache map[string]*Commit
+ cache Cache
+}
+
+// NewLastCommitCache creates a new last commit cache for repo
+func NewLastCommitCache(count int64, repoPath string, gitRepo *Repository, cache Cache) *LastCommitCache {
+ if cache == nil {
+ return nil
+ }
+ if !setting.CacheService.LastCommit.Enabled || count < setting.CacheService.LastCommit.CommitsCount {
+ return nil
+ }
+
+ return &LastCommitCache{
+ repoPath: repoPath,
+ repo: gitRepo,
+ ttl: setting.LastCommitCacheTTLSeconds,
+ cache: cache,
+ }
+}
+
// Put put the last commit id with commit and entry path
func (c *LastCommitCache) Put(ref, entryPath, commitID string) error {
if c == nil || c.cache == nil {
return nil
}
log.Debug("LastCommitCache save: [%s:%s:%s]", ref, entryPath, commitID)
- return c.cache.Put(c.getCacheKey(c.repoPath, ref, entryPath), commitID, c.ttl())
+ return c.cache.Put(getCacheKey(c.repoPath, ref, entryPath), commitID, c.ttl())
+}
+
+// Get gets the last commit information by commit id and entry path
+func (c *LastCommitCache) Get(ref, entryPath string) (*Commit, error) {
+ if c == nil || c.cache == nil {
+ return nil, nil
+ }
+
+ commitID, ok := c.cache.Get(getCacheKey(c.repoPath, ref, entryPath)).(string)
+ if !ok || commitID == "" {
+ return nil, nil
+ }
+
+ log.Debug("LastCommitCache hit level 1: [%s:%s:%s]", ref, entryPath, commitID)
+ if c.commitCache != nil {
+ if commit, ok := c.commitCache[commitID]; ok {
+ log.Debug("LastCommitCache hit level 2: [%s:%s:%s]", ref, entryPath, commitID)
+ return commit, nil
+ }
+ }
+
+ commit, err := c.repo.GetCommit(commitID)
+ if err != nil {
+ return nil, err
+ }
+ if c.commitCache == nil {
+ c.commitCache = make(map[string]*Commit)
+ }
+ c.commitCache[commitID] = commit
+ return commit, nil
+}
+
+// GetCommitByPath gets the last commit for the entry in the provided commit
+func (c *LastCommitCache) GetCommitByPath(commitID, entryPath string) (*Commit, error) {
+ sha1, err := NewIDFromString(commitID)
+ if err != nil {
+ return nil, err
+ }
+
+ lastCommit, err := c.Get(sha1.String(), entryPath)
+ if err != nil || lastCommit != nil {
+ return lastCommit, err
+ }
+
+ lastCommit, err = c.repo.getCommitByPathWithID(sha1, entryPath)
+ if err != nil {
+ return nil, err
+ }
+
+ if err := c.Put(commitID, entryPath, lastCommit.ID.String()); err != nil {
+ log.Error("Unable to cache %s as the last commit for %q in %s %s. Error %v", lastCommit.ID.String(), entryPath, commitID, c.repoPath, err)
+ }
+
+ return lastCommit, nil
}