mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	Performance improvement for last commit cache and show-ref (#15455)
* Improve performance when there are multiple commits in the last commit cache * read refs directly if we can Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
		| @@ -102,10 +102,13 @@ func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache *LastCo | ||||
| } | ||||
|  | ||||
| func getLastCommitForPathsByCache(commitID, treePath string, paths []string, cache *LastCommitCache) (map[string]*Commit, []string, error) { | ||||
| 	wr, rd, cancel := CatFileBatch(cache.repo.Path) | ||||
| 	defer cancel() | ||||
|  | ||||
| 	var unHitEntryPaths []string | ||||
| 	var results = make(map[string]*Commit) | ||||
| 	for _, p := range paths { | ||||
| 		lastCommit, err := cache.Get(commitID, path.Join(treePath, p)) | ||||
| 		lastCommit, err := cache.Get(commitID, path.Join(treePath, p), wr, rd) | ||||
| 		if err != nil { | ||||
| 			return nil, nil, err | ||||
| 		} | ||||
|   | ||||
| @@ -7,6 +7,8 @@ | ||||
| package git | ||||
|  | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"io" | ||||
| 	"path" | ||||
| ) | ||||
|  | ||||
| @@ -34,7 +36,7 @@ func NewLastCommitCache(repoPath string, gitRepo *Repository, ttl func() int64, | ||||
| } | ||||
|  | ||||
| // Get get the last commit information by commit id and entry path | ||||
| func (c *LastCommitCache) Get(ref, entryPath string) (interface{}, error) { | ||||
| func (c *LastCommitCache) Get(ref, entryPath string, wr *io.PipeWriter, rd *bufio.Reader) (interface{}, error) { | ||||
| 	v := c.cache.Get(c.getCacheKey(c.repoPath, ref, entryPath)) | ||||
| 	if vs, ok := v.(string); ok { | ||||
| 		log("LastCommitCache hit level 1: [%s:%s:%s]", ref, entryPath, vs) | ||||
| @@ -46,7 +48,10 @@ func (c *LastCommitCache) Get(ref, entryPath string) (interface{}, error) { | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		commit, err := c.repo.getCommit(id) | ||||
| 		if _, err := wr.Write([]byte(vs + "\n")); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		commit, err := c.repo.getCommitFromBatchReader(rd, id) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|   | ||||
| @@ -9,9 +9,10 @@ package git | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| @@ -34,6 +35,18 @@ func (repo *Repository) ResolveReference(name string) (string, error) { | ||||
|  | ||||
| // GetRefCommitID returns the last commit ID string of given reference (branch or tag). | ||||
| func (repo *Repository) GetRefCommitID(name string) (string, error) { | ||||
| 	if strings.HasPrefix(name, "refs/") { | ||||
| 		// We're gonna try just reading the ref file as this is likely to be quicker than other options | ||||
| 		fileInfo, err := os.Lstat(filepath.Join(repo.Path, name)) | ||||
| 		if err == nil && fileInfo.Mode().IsRegular() && fileInfo.Size() == 41 { | ||||
| 			ref, err := ioutil.ReadFile(filepath.Join(repo.Path, name)) | ||||
|  | ||||
| 			if err == nil && SHAPattern.Match(ref[:40]) && ref[40] == '\n' { | ||||
| 				return string(ref[:40]), nil | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	stdout, err := NewCommand("show-ref", "--verify", "--hash", name).RunInDir(repo.Path) | ||||
| 	if err != nil { | ||||
| 		if strings.Contains(err.Error(), "not a valid ref") { | ||||
| @@ -69,6 +82,11 @@ func (repo *Repository) getCommit(id SHA1) (*Commit, error) { | ||||
| 	}() | ||||
|  | ||||
| 	bufReader := bufio.NewReader(stdoutReader) | ||||
|  | ||||
| 	return repo.getCommitFromBatchReader(bufReader, id) | ||||
| } | ||||
|  | ||||
| func (repo *Repository) getCommitFromBatchReader(bufReader *bufio.Reader, id SHA1) (*Commit, error) { | ||||
| 	_, typ, size, err := ReadBatchLine(bufReader) | ||||
| 	if err != nil { | ||||
| 		if errors.Is(err, io.EOF) { | ||||
| @@ -106,7 +124,6 @@ func (repo *Repository) getCommit(id SHA1) (*Commit, error) { | ||||
| 	case "commit": | ||||
| 		return CommitFromReader(repo, id, io.LimitReader(bufReader, size)) | ||||
| 	default: | ||||
| 		_ = stdoutReader.CloseWithError(fmt.Errorf("unknown typ: %s", typ)) | ||||
| 		log("Unknown typ: %s", typ) | ||||
| 		return nil, ErrNotExist{ | ||||
| 			ID: id.String(), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 zeripath
					zeripath