Author | Jakob Wakeling <[email protected]> |
Date | 2023-12-23 11:08:13 |
Commit | 313c62bc5978a59e200ebe216fff830fa3b74d18 |
Parent | 2e13a8c43874e4e8cf38cf75da5a31ec8d7f170f |
Cache file and directory sizes
Diffstat
M | src/goit/git.go | | | 3 | +++ |
M | src/repo/tree.go | | | 76 | +++++++++++++++++++++++++++++++++++++++++++++++++--------------------------- |
2 files changed, 52 insertions, 27 deletions
diff --git a/src/goit/git.go b/src/goit/git.go index 6172fe9..e75fd0e 100644 --- a/src/goit/git.go +++ b/src/goit/git.go @@ -231,6 +231,9 @@ type DiffStat struct { var diffs = map[plumbing.Hash][]DiffStat{} var diffsLock sync.RWMutex +var Sizes = map[plumbing.Hash]uint64{} +var SizesLock sync.RWMutex + func DiffStats(c *object.Commit) ([]DiffStat, error) { diffsLock.RLock() if stats, ok := diffs[c.Hash]; ok { diff --git a/src/repo/tree.go b/src/repo/tree.go index ea735ef..08ef072 100644 --- a/src/repo/tree.go +++ b/src/repo/tree.go @@ -132,44 +132,66 @@ func HandleTree(w http.ResponseWriter, r *http.Request) { var isFile bool if v.Mode&0o40000 == 0 { - file, err := tree.File(v.Name) - if err != nil { - log.Println("[/repo/tree]", err.Error()) - goit.HttpError(w, http.StatusInternalServerError) - return - } - fpath = path.Join("file", tpath, v.Name) rpath = path.Join(tpath, v.Name) - size = humanize.IBytes(uint64(file.Size)) - isFile = true - totalSize += uint64(file.Size) - } else { - var dirSize uint64 + goit.SizesLock.RLock() + sz, ok := goit.Sizes[v.Hash] + goit.SizesLock.RUnlock() - dirt, err := tree.Tree(v.Name) - if err != nil { - log.Println("[/repo/tree]", err.Error()) - goit.HttpError(w, http.StatusInternalServerError) - return - } + if !ok { + file, err := tree.File(v.Name) + if err != nil { + log.Println("[/repo/tree]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } - if err := dirt.Files().ForEach(func(f *object.File) error { - dirSize += uint64(f.Size) - return nil - }); err != nil { - log.Println("[/repo/tree]", err.Error()) - goit.HttpError(w, http.StatusInternalServerError) - return + sz = uint64(file.Size) + + goit.SizesLock.Lock() + goit.Sizes[v.Hash] = sz + goit.SizesLock.Unlock() } + size = humanize.IBytes(sz) + totalSize += sz + } else { fpath = path.Join("tree", tpath, v.Name) rpath = path.Join(tpath, v.Name) - size = humanize.IBytes(dirSize) - totalSize += dirSize + goit.SizesLock.RLock() + sz, ok := goit.Sizes[v.Hash] + goit.SizesLock.RUnlock() + + if !ok { + dirt, err := tree.Tree(v.Name) + if err != nil { + log.Println("[/repo/tree]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } + + var dirSize uint64 + if err := dirt.Files().ForEach(func(f *object.File) error { + dirSize += uint64(f.Size) + return nil + }); err != nil { + log.Println("[/repo/tree]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } + + sz = dirSize + + goit.SizesLock.Lock() + goit.Sizes[v.Hash] = sz + goit.SizesLock.Unlock() + } + + size = humanize.IBytes(sz) + totalSize += sz } data.Files = append(data.Files, row{