gitea源码

last_commit_cache.go 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package git
  4. import (
  5. "crypto/sha256"
  6. "fmt"
  7. "code.gitea.io/gitea/modules/cache"
  8. "code.gitea.io/gitea/modules/log"
  9. "code.gitea.io/gitea/modules/setting"
  10. )
  11. func getCacheKey(repoPath, commitID, entryPath string) string {
  12. hashBytes := sha256.Sum256(fmt.Appendf(nil, "%s:%s:%s", repoPath, commitID, entryPath))
  13. return fmt.Sprintf("last_commit:%x", hashBytes)
  14. }
  15. // LastCommitCache represents a cache to store last commit
  16. type LastCommitCache struct {
  17. repoPath string
  18. ttl func() int64
  19. repo *Repository
  20. commitCache map[string]*Commit
  21. cache cache.StringCache
  22. }
  23. // NewLastCommitCache creates a new last commit cache for repo
  24. func NewLastCommitCache(count int64, repoPath string, gitRepo *Repository, cache cache.StringCache) *LastCommitCache {
  25. if cache == nil {
  26. return nil
  27. }
  28. if count < setting.CacheService.LastCommit.CommitsCount {
  29. return nil
  30. }
  31. return &LastCommitCache{
  32. repoPath: repoPath,
  33. repo: gitRepo,
  34. ttl: setting.LastCommitCacheTTLSeconds,
  35. cache: cache,
  36. }
  37. }
  38. // Put put the last commit id with commit and entry path
  39. func (c *LastCommitCache) Put(ref, entryPath, commitID string) error {
  40. if c == nil || c.cache == nil {
  41. return nil
  42. }
  43. log.Debug("LastCommitCache save: [%s:%s:%s]", ref, entryPath, commitID)
  44. return c.cache.Put(getCacheKey(c.repoPath, ref, entryPath), commitID, c.ttl())
  45. }
  46. // Get gets the last commit information by commit id and entry path
  47. func (c *LastCommitCache) Get(ref, entryPath string) (*Commit, error) {
  48. if c == nil || c.cache == nil {
  49. return nil, nil
  50. }
  51. commitID, ok := c.cache.Get(getCacheKey(c.repoPath, ref, entryPath))
  52. if !ok || commitID == "" {
  53. return nil, nil
  54. }
  55. log.Debug("LastCommitCache hit level 1: [%s:%s:%s]", ref, entryPath, commitID)
  56. if c.commitCache != nil {
  57. if commit, ok := c.commitCache[commitID]; ok {
  58. log.Debug("LastCommitCache hit level 2: [%s:%s:%s]", ref, entryPath, commitID)
  59. return commit, nil
  60. }
  61. }
  62. commit, err := c.repo.GetCommit(commitID)
  63. if err != nil {
  64. return nil, err
  65. }
  66. if c.commitCache == nil {
  67. c.commitCache = make(map[string]*Commit)
  68. }
  69. c.commitCache[commitID] = commit
  70. return commit, nil
  71. }
  72. // GetCommitByPath gets the last commit for the entry in the provided commit
  73. func (c *LastCommitCache) GetCommitByPath(commitID, entryPath string) (*Commit, error) {
  74. sha, err := NewIDFromString(commitID)
  75. if err != nil {
  76. return nil, err
  77. }
  78. lastCommit, err := c.Get(sha.String(), entryPath)
  79. if err != nil || lastCommit != nil {
  80. return lastCommit, err
  81. }
  82. lastCommit, err = c.repo.getCommitByPathWithID(sha, entryPath)
  83. if err != nil {
  84. return nil, err
  85. }
  86. if err := c.Put(commitID, entryPath, lastCommit.ID.String()); err != nil {
  87. 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)
  88. }
  89. return lastCommit, nil
  90. }