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

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