From 2fa2b63334ce7c6efc35b52ffafd8e2d27cb49f9 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 12 Feb 2019 19:00:42 +0800 Subject: [PATCH] add last commit cache interface (#144) * add last commit cache interface * fix tests --- cache.go | 11 +++++++++++ commit_info.go | 20 +++++++++++++++----- commit_info_test.go | 4 ++-- 3 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 cache.go diff --git a/cache.go b/cache.go new file mode 100644 index 0000000..dbbbafa --- /dev/null +++ b/cache.go @@ -0,0 +1,11 @@ +// Copyright 2019 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. + +package git + +// LastCommitCache cache +type LastCommitCache interface { + Get(repoPath, ref, entryPath string) (*Commit, error) + Put(repoPath, ref, entryPath string, commit *Commit) error +} diff --git a/commit_info.go b/commit_info.go index 6b42b57..971082b 100644 --- a/commit_info.go +++ b/commit_info.go @@ -72,13 +72,20 @@ func (state *getCommitsInfoState) getTargetedEntryPath() string { } // repeatedly perform targeted searches for unpopulated entries -func targetedSearch(state *getCommitsInfoState, done chan error) { +func targetedSearch(state *getCommitsInfoState, done chan error, cache LastCommitCache) { for { entryPath := state.getTargetedEntryPath() if len(entryPath) == 0 { done <- nil return } + if cache != nil { + commit, err := cache.Get(state.headCommit.repo.Path, state.headCommit.ID.String(), entryPath) + if err == nil && commit != nil { + state.update(entryPath, commit) + continue + } + } command := NewCommand("rev-list", "-1", state.headCommit.ID.String(), "--", entryPath) output, err := command.RunInDir(state.headCommit.repo.Path) if err != nil { @@ -96,6 +103,9 @@ func targetedSearch(state *getCommitsInfoState, done chan error) { return } state.update(entryPath, commit) + if cache != nil { + cache.Put(state.headCommit.repo.Path, state.headCommit.ID.String(), entryPath, commit) + } } } @@ -118,9 +128,9 @@ func initGetCommitInfoState(entries Entries, headCommit *Commit, treePath string } // GetCommitsInfo gets information of all commits that are corresponding to these entries -func (tes Entries) GetCommitsInfo(commit *Commit, treePath string) ([][]interface{}, error) { +func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache LastCommitCache) ([][]interface{}, error) { state := initGetCommitInfoState(tes, commit, treePath) - if err := getCommitsInfo(state); err != nil { + if err := getCommitsInfo(state, cache); err != nil { return nil, err } if len(state.commits) < len(state.entryPaths) { @@ -188,7 +198,7 @@ func (state *getCommitsInfoState) update(entryPath string, commit *Commit) bool const getCommitsInfoPretty = "--pretty=format:%H %ct %s" -func getCommitsInfo(state *getCommitsInfoState) error { +func getCommitsInfo(state *getCommitsInfoState, cache LastCommitCache) error { ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) defer cancel() @@ -215,7 +225,7 @@ func getCommitsInfo(state *getCommitsInfoState) error { numThreads := runtime.NumCPU() done := make(chan error, numThreads) for i := 0; i < numThreads; i++ { - go targetedSearch(state, done) + go targetedSearch(state, done, cache) } scanner := bufio.NewScanner(readCloser) diff --git a/commit_info_test.go b/commit_info_test.go index 8dc2616..f3f7289 100644 --- a/commit_info_test.go +++ b/commit_info_test.go @@ -51,7 +51,7 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) { assert.NoError(t, err) entries, err := tree.ListEntries() assert.NoError(t, err) - commitsInfo, err := entries.GetCommitsInfo(commit, testCase.Path) + commitsInfo, err := entries.GetCommitsInfo(commit, testCase.Path, nil) assert.NoError(t, err) assert.Len(t, commitsInfo, len(testCase.ExpectedIDs)) for _, commitInfo := range commitsInfo { @@ -106,7 +106,7 @@ func BenchmarkEntries_GetCommitsInfo(b *testing.B) { b.ResetTimer() b.Run(benchmark.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - _, err := entries.GetCommitsInfo(commit, "") + _, err := entries.GetCommitsInfo(commit, "", nil) if err != nil { b.Fatal(err) }