You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

last_commit_cache_nogogit.go 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. //go:build !gogit
  5. // +build !gogit
  6. package git
  7. import (
  8. "bufio"
  9. "context"
  10. "code.gitea.io/gitea/modules/log"
  11. )
  12. // LastCommitCache represents a cache to store last commit
  13. type LastCommitCache struct {
  14. repoPath string
  15. ttl func() int64
  16. repo *Repository
  17. commitCache map[string]*Commit
  18. cache Cache
  19. }
  20. // NewLastCommitCache creates a new last commit cache for repo
  21. func NewLastCommitCache(repoPath string, gitRepo *Repository, ttl func() int64, cache Cache) *LastCommitCache {
  22. if cache == nil {
  23. return nil
  24. }
  25. return &LastCommitCache{
  26. repoPath: repoPath,
  27. repo: gitRepo,
  28. commitCache: make(map[string]*Commit),
  29. ttl: ttl,
  30. cache: cache,
  31. }
  32. }
  33. // Get get the last commit information by commit id and entry path
  34. func (c *LastCommitCache) Get(ref, entryPath string, wr WriteCloserError, rd *bufio.Reader) (interface{}, error) {
  35. v := c.cache.Get(c.getCacheKey(c.repoPath, ref, entryPath))
  36. if vs, ok := v.(string); ok {
  37. log.Debug("LastCommitCache hit level 1: [%s:%s:%s]", ref, entryPath, vs)
  38. if commit, ok := c.commitCache[vs]; ok {
  39. log.Debug("LastCommitCache hit level 2: [%s:%s:%s]", ref, entryPath, vs)
  40. return commit, nil
  41. }
  42. id, err := c.repo.ConvertToSHA1(vs)
  43. if err != nil {
  44. return nil, err
  45. }
  46. if _, err := wr.Write([]byte(vs + "\n")); err != nil {
  47. return nil, err
  48. }
  49. commit, err := c.repo.getCommitFromBatchReader(rd, id)
  50. if err != nil {
  51. return nil, err
  52. }
  53. c.commitCache[vs] = commit
  54. return commit, nil
  55. }
  56. return nil, nil
  57. }
  58. // CacheCommit will cache the commit from the gitRepository
  59. func (c *LastCommitCache) CacheCommit(ctx context.Context, commit *Commit) error {
  60. return c.recursiveCache(ctx, commit, &commit.Tree, "", 1)
  61. }
  62. func (c *LastCommitCache) recursiveCache(ctx context.Context, commit *Commit, tree *Tree, treePath string, level int) error {
  63. if level == 0 {
  64. return nil
  65. }
  66. entries, err := tree.ListEntries()
  67. if err != nil {
  68. return err
  69. }
  70. entryPaths := make([]string, len(entries))
  71. for i, entry := range entries {
  72. entryPaths[i] = entry.Name()
  73. }
  74. _, err = WalkGitLog(ctx, c, commit.repo, commit, treePath, entryPaths...)
  75. if err != nil {
  76. return err
  77. }
  78. for _, treeEntry := range entries {
  79. // entryMap won't contain "" therefore skip this.
  80. if treeEntry.IsDir() {
  81. subTree, err := tree.SubTree(treeEntry.Name())
  82. if err != nil {
  83. return err
  84. }
  85. if err := c.recursiveCache(ctx, commit, subTree, treeEntry.Name(), level-1); err != nil {
  86. return err
  87. }
  88. }
  89. }
  90. return nil
  91. }