2020-12-17 17:00:47 +03:00
// Copyright 2020 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2021-08-24 19:47:09 +03:00
//go:build !gogit
2020-12-17 17:00:47 +03:00
// +build !gogit
package git
import (
2021-05-02 04:16:08 +03:00
"bufio"
2021-06-07 02:44:58 +03:00
"context"
2021-06-25 19:54:08 +03:00
"code.gitea.io/gitea/modules/log"
2020-12-17 17:00:47 +03:00
)
// LastCommitCache represents a cache to store last commit
type LastCommitCache struct {
repoPath string
2021-02-10 01:29:03 +03:00
ttl func ( ) int64
2020-12-17 17:00:47 +03:00
repo * Repository
commitCache map [ string ] * Commit
cache Cache
}
// NewLastCommitCache creates a new last commit cache for repo
2021-02-10 01:29:03 +03:00
func NewLastCommitCache ( repoPath string , gitRepo * Repository , ttl func ( ) int64 , cache Cache ) * LastCommitCache {
2020-12-17 17:00:47 +03:00
if cache == nil {
return nil
}
return & LastCommitCache {
repoPath : repoPath ,
repo : gitRepo ,
commitCache : make ( map [ string ] * Commit ) ,
ttl : ttl ,
cache : cache ,
}
}
// Get get the last commit information by commit id and entry path
2021-05-10 04:27:03 +03:00
func ( c * LastCommitCache ) Get ( ref , entryPath string , wr WriteCloserError , rd * bufio . Reader ) ( interface { } , error ) {
2020-12-17 17:00:47 +03:00
v := c . cache . Get ( c . getCacheKey ( c . repoPath , ref , entryPath ) )
if vs , ok := v . ( string ) ; ok {
2021-06-25 19:54:08 +03:00
log . Debug ( "LastCommitCache hit level 1: [%s:%s:%s]" , ref , entryPath , vs )
2020-12-17 17:00:47 +03:00
if commit , ok := c . commitCache [ vs ] ; ok {
2021-06-25 19:54:08 +03:00
log . Debug ( "LastCommitCache hit level 2: [%s:%s:%s]" , ref , entryPath , vs )
2020-12-17 17:00:47 +03:00
return commit , nil
}
id , err := c . repo . ConvertToSHA1 ( vs )
if err != nil {
return nil , err
}
2021-05-02 04:16:08 +03:00
if _ , err := wr . Write ( [ ] byte ( vs + "\n" ) ) ; err != nil {
return nil , err
}
commit , err := c . repo . getCommitFromBatchReader ( rd , id )
2020-12-17 17:00:47 +03:00
if err != nil {
return nil , err
}
c . commitCache [ vs ] = commit
return commit , nil
}
return nil , nil
}
// CacheCommit will cache the commit from the gitRepository
2021-06-07 02:44:58 +03:00
func ( c * LastCommitCache ) CacheCommit ( ctx context . Context , commit * Commit ) error {
return c . recursiveCache ( ctx , commit , & commit . Tree , "" , 1 )
2020-12-17 17:00:47 +03:00
}
2021-06-07 02:44:58 +03:00
func ( c * LastCommitCache ) recursiveCache ( ctx context . Context , commit * Commit , tree * Tree , treePath string , level int ) error {
2020-12-17 17:00:47 +03:00
if level == 0 {
return nil
}
entries , err := tree . ListEntries ( )
if err != nil {
return err
}
entryPaths := make ( [ ] string , len ( entries ) )
for i , entry := range entries {
entryPaths [ i ] = entry . Name ( )
}
2021-10-08 16:08:22 +03:00
_ , err = WalkGitLog ( ctx , c , commit . repo , commit , treePath , entryPaths ... )
2020-12-17 17:00:47 +03:00
if err != nil {
return err
}
2021-10-08 16:08:22 +03:00
for _ , treeEntry := range entries {
2021-06-29 23:12:43 +03:00
// entryMap won't contain "" therefore skip this.
2021-10-08 16:08:22 +03:00
if treeEntry . IsDir ( ) {
subTree , err := tree . SubTree ( treeEntry . Name ( ) )
2020-12-17 17:00:47 +03:00
if err != nil {
return err
}
2021-10-08 16:08:22 +03:00
if err := c . recursiveCache ( ctx , commit , subTree , treeEntry . Name ( ) , level - 1 ) ; err != nil {
2020-12-17 17:00:47 +03:00
return err
}
}
}
return nil
}