Skip to content

Commit 0c75ff6

Browse files
committed
feat: use lru.Cache and cache trees
* drop objectCache in favor for lru.Cache * cache repo trees
1 parent a2567c6 commit 0c75ff6

File tree

8 files changed

+38
-43
lines changed

8 files changed

+38
-43
lines changed

commit_submodule.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"bufio"
99
"bytes"
1010
"strings"
11+
12+
"github.com/golang/groupcache/lru"
1113
)
1214

1315
// Submodule contains information of a Git submodule.
@@ -21,7 +23,7 @@ type Submodule struct {
2123
}
2224

2325
// Submodules contains information of submodules.
24-
type Submodules = *objectCache
26+
type Submodules = *lru.Cache
2527

2628
// Submodules returns submodules found in this commit.
2729
func (c *Commit) Submodules() (Submodules, error) {
@@ -39,7 +41,7 @@ func (c *Commit) Submodules() (Submodules, error) {
3941
}
4042

4143
scanner := bufio.NewScanner(bytes.NewReader(p))
42-
c.submodules = newObjectCache()
44+
c.submodules = lru.New(0)
4345
var inSection bool
4446
var path string
4547
var url string
@@ -72,7 +74,7 @@ func (c *Commit) Submodules() (Submodules, error) {
7274
return
7375
}
7476

75-
c.submodules.Set(path, mod)
77+
c.submodules.Add(path, mod)
7678
inSection = false
7779
}
7880
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/gogs/git-module
33
go 1.13
44

55
require (
6+
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
67
github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75
78
github.com/stretchr/testify v1.7.2
89
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
22
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3+
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
4+
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
35
github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75 h1:Pijfgr7ZuvX7QIQiEwLdRVr3RoMG+i0SbBO1Qu+7yVk=
46
github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo=
57
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

repo.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,17 @@ import (
1515
"strconv"
1616
"strings"
1717
"time"
18+
19+
"github.com/golang/groupcache/lru"
1820
)
1921

2022
// Repository contains information of a Git repository.
2123
type Repository struct {
2224
path string
2325

24-
cachedCommits *objectCache
25-
cachedTags *objectCache
26+
cachedCommits *lru.Cache
27+
cachedTags *lru.Cache
28+
cachedTrees *lru.Cache
2629
}
2730

2831
// Path returns the path of the repository.
@@ -84,9 +87,18 @@ func Init(path string, opts ...InitOptions) error {
8487
return err
8588
}
8689

90+
// OpenOptions contains optional arguments for opening a repository.
91+
type OpenOptions struct {
92+
MaxCacheEntries int
93+
}
94+
8795
// Open opens the repository at the given path. It returns an os.ErrNotExist if
8896
// the path does not exist.
89-
func Open(repoPath string) (*Repository, error) {
97+
func Open(repoPath string, opts ...OpenOptions) (*Repository, error) {
98+
var opt OpenOptions
99+
if len(opts) > 0 {
100+
opt = opts[0]
101+
}
90102
repoPath, err := filepath.Abs(repoPath)
91103
if err != nil {
92104
return nil, err
@@ -96,8 +108,9 @@ func Open(repoPath string) (*Repository, error) {
96108

97109
return &Repository{
98110
path: repoPath,
99-
cachedCommits: newObjectCache(),
100-
cachedTags: newObjectCache(),
111+
cachedCommits: lru.New(opt.MaxCacheEntries),
112+
cachedTags: lru.New(opt.MaxCacheEntries),
113+
cachedTrees: lru.New(opt.MaxCacheEntries),
101114
}, nil
102115
}
103116

repo_commit.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ func (r *Repository) CatFileCommit(rev string, opts ...CatFileCommitOptions) (*C
112112
c.repo = r
113113
c.ID = MustIDFromString(commitID)
114114

115-
r.cachedCommits.Set(commitID, c)
115+
r.cachedCommits.Add(commitID, c)
116116
return c, nil
117117
}
118118

repo_tag.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func (r *Repository) getTag(timeout time.Duration, id *SHA1) (*Tag, error) {
9494
return nil, fmt.Errorf("unsupported tag type: %s", typ)
9595
}
9696

97-
r.cachedTags.Set(id.String(), tag)
97+
r.cachedTags.Add(id.String(), tag)
9898
return tag, nil
9999
}
100100

repo_tree.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,25 +97,30 @@ type LsTreeOptions struct {
9797
}
9898

9999
// LsTree returns the tree object in the repository by given revision.
100-
func (r *Repository) LsTree(rev string, opts ...LsTreeOptions) (*Tree, error) {
100+
func (r *Repository) LsTree(treeID string, opts ...LsTreeOptions) (*Tree, error) {
101101
var opt LsTreeOptions
102102
if len(opts) > 0 {
103103
opt = opts[0]
104104
}
105105

106+
cache, ok := r.cachedTrees.Get(treeID)
107+
if ok {
108+
log("Cached tree hit: %s", treeID)
109+
return cache.(*Tree), nil
110+
}
106111
var err error
107-
rev, err = r.RevParse(rev, RevParseOptions{Timeout: opt.Timeout}) //nolint
112+
treeID, err = r.RevParse(treeID, RevParseOptions{Timeout: opt.Timeout}) //nolint
108113
if err != nil {
109114
return nil, err
110115
}
111116
t := &Tree{
112-
id: MustIDFromString(rev),
117+
id: MustIDFromString(treeID),
113118
repo: r,
114119
}
115120

116121
stdout, err := NewCommand("ls-tree").
117122
AddOptions(opt.CommandOptions).
118-
AddArgs(rev).
123+
AddArgs(treeID).
119124
RunInDirWithTimeout(opt.Timeout, r.path)
120125
if err != nil {
121126
return nil, err
@@ -126,5 +131,6 @@ func (r *Repository) LsTree(rev string, opts ...LsTreeOptions) (*Tree, error) {
126131
return nil, err
127132
}
128133

134+
r.cachedTrees.Add(treeID, t)
129135
return t, nil
130136
}

utils.go

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,8 @@ import (
88
"fmt"
99
"os"
1010
"strings"
11-
"sync"
1211
)
1312

14-
// objectCache provides thread-safe cache operations. TODO(@unknwon): Use
15-
// sync.Map once requires Go 1.13.
16-
type objectCache struct {
17-
lock sync.RWMutex
18-
cache map[string]interface{}
19-
}
20-
21-
func newObjectCache() *objectCache {
22-
return &objectCache{
23-
cache: make(map[string]interface{}),
24-
}
25-
}
26-
27-
func (oc *objectCache) Set(id string, obj interface{}) {
28-
oc.lock.Lock()
29-
defer oc.lock.Unlock()
30-
31-
oc.cache[id] = obj
32-
}
33-
34-
func (oc *objectCache) Get(id string) (interface{}, bool) {
35-
oc.lock.RLock()
36-
defer oc.lock.RUnlock()
37-
38-
obj, has := oc.cache[id]
39-
return obj, has
40-
}
41-
4213
// isDir returns true if given path is a directory, or returns false when it's a
4314
// file or does not exist.
4415
func isDir(dir string) bool {

0 commit comments

Comments
 (0)