From cf735091ac163cbaafda8a12ead568bf4ed8abbf Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Sat, 22 Mar 2025 22:04:25 +0800 Subject: [PATCH] Reuse the cache for /tree --- cache.go | 31 +++++++++++++++++++++++++++++++ http_handle_repo_index.go | 29 +++-------------------------- http_handle_repo_tree.go | 121 ++++++++++++++++++++++++++++++++++------------------- diff --git a/cache.go b/cache.go new file mode 100644 index 0000000000000000000000000000000000000000..e74588449c38b4771cc5d9e5907e2b15a8575017 --- /dev/null +++ b/cache.go @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// SPDX-FileContributor: Runxi Yu + +package main + +import ( + "html/template" + + "github.com/dgraph-io/ristretto/v2" + "go.lindenii.runxiyu.org/lindenii-common/clog" +) + +type treeReadmeCacheEntry struct { + DisplayTree []displayTreeEntry + ReadmeFilename string + ReadmeRendered template.HTML +} + +var treeReadmeCache *ristretto.Cache[[]byte, treeReadmeCacheEntry] + +func init() { + var err error + treeReadmeCache, err = ristretto.NewCache(&ristretto.Config[[]byte, treeReadmeCacheEntry]{ + NumCounters: 1e4, + MaxCost: 1 << 30, + BufferItems: 64, + }) + if err != nil { + clog.Fatal(1, "Error initializing indexPageCache: "+err.Error()) + } +} diff --git a/http_handle_repo_index.go b/http_handle_repo_index.go index 44151a0195d173754ec8478c930756756e77b336..9285e6e5e993bd54ee4d01ffedd0b634a50f0f0b 100644 --- a/http_handle_repo_index.go +++ b/http_handle_repo_index.go @@ -4,40 +4,17 @@ package main import ( - "html/template" "iter" "net/http" "strings" "time" - "github.com/dgraph-io/ristretto/v2" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" "github.com/go-git/go-git/v5/plumbing/storer" - "go.lindenii.runxiyu.org/lindenii-common/clog" ) -type indexPageCacheEntry struct { - DisplayTree []displayTreeEntry - ReadmeFilename string - ReadmeRendered template.HTML -} - -var indexPageCache *ristretto.Cache[[]byte, indexPageCacheEntry] - -func init() { - var err error - indexPageCache, err = ristretto.NewCache(&ristretto.Config[[]byte, indexPageCacheEntry]{ - NumCounters: 1e4, - MaxCost: 1 << 30, - BufferItems: 64, - }) - if err != nil { - clog.Fatal(1, "Error initializing indexPageCache: "+err.Error()) - } -} - func httpHandleRepoIndex(writer http.ResponseWriter, _ *http.Request, params map[string]any) { var repo *git.Repository var repoName string @@ -83,7 +60,7 @@ } commitIterSeq, params["commits_err"] = commitIterSeqErr(commitIter) params["commits"] = iterSeqLimit(commitIterSeq, 3) - if value, found := indexPageCache.Get(refHashSlice); found { + if value, found := treeReadmeCache.Get(refHashSlice); found { params["files"] = value.DisplayTree params["readme_filename"] = value.ReadmeFilename params["readme"] = value.ReadmeRendered @@ -104,12 +81,12 @@ params["files"] = displayTree params["readme_filename"] = readmeFilename params["readme"] = readmeRendered - entry := indexPageCacheEntry{ + entry := treeReadmeCacheEntry{ DisplayTree: displayTree, ReadmeFilename: readmeFilename, ReadmeRendered: readmeRendered, } - indexPageCache.Set(refHashSlice, entry, cost) + treeReadmeCache.Set(refHashSlice, entry, cost) } no_ref: diff --git a/http_handle_repo_tree.go b/http_handle_repo_tree.go index 229b029ef0dfa61ccda1f357e30e18fa92d910b6..91d7e68fe5a70391313890b7249f730232f44003 100644 --- a/http_handle_repo_tree.go +++ b/http_handle_repo_tree.go @@ -9,6 +9,7 @@ "html/template" "net/http" "path" "strings" + "time" "github.com/alecthomas/chroma/v2" chromaHTML "github.com/alecthomas/chroma/v2/formatters/html" @@ -23,6 +24,7 @@ func httpHandleRepoTree(writer http.ResponseWriter, request *http.Request, params map[string]any) { var rawPathSpec, pathSpec string var repo *git.Repository var refHash plumbing.Hash + var refHashSlice []byte var commitObject *object.Commit var tree *object.Tree var err error @@ -35,6 +37,45 @@ if refHash, err = getRefHash(repo, params["ref_type"].(string), params["ref_name"].(string)); err != nil { errorPage500(writer, params, "Error getting ref hash: "+err.Error()) return } + refHashSlice = refHash[:] + + var target *object.Tree + if pathSpec == "" { + if value, found := treeReadmeCache.Get(refHashSlice); found { + params["files"] = value.DisplayTree + params["readme_filename"] = value.ReadmeFilename + params["readme"] = value.ReadmeRendered + } else { + if commitObject, err = repo.CommitObject(refHash); err != nil { + errorPage500(writer, params, "Error getting commit object: "+err.Error()) + return + } + if tree, err = commitObject.Tree(); err != nil { + errorPage500(writer, params, "Error getting file tree: "+err.Error()) + return + } + + start := time.Now() + displayTree := makeDisplayTree(tree) + readmeFilename, readmeRendered := renderReadmeAtTree(tree) + cost := time.Since(start).Nanoseconds() + + params["files"] = displayTree + params["readme_filename"] = readmeFilename + params["readme"] = readmeRendered + + entry := treeReadmeCacheEntry{ + DisplayTree: displayTree, + ReadmeFilename: readmeFilename, + ReadmeRendered: readmeRendered, + } + treeReadmeCache.Set(refHashSlice, entry, cost) + } + + renderTemplate(writer, "repo_tree_dir", params) + return + } + if commitObject, err = repo.CommitObject(refHash); err != nil { errorPage500(writer, params, "Error getting commit object: "+err.Error()) return @@ -43,52 +84,46 @@ if tree, err = commitObject.Tree(); err != nil { errorPage500(writer, params, "Error getting file tree: "+err.Error()) return } + if target, err = tree.Tree(pathSpec); err != nil { + var file *object.File + var fileContent string + var lexer chroma.Lexer + var iterator chroma.Iterator + var style *chroma.Style + var formatter *chromaHTML.Formatter + var formattedHTML template.HTML - var target *object.Tree - if pathSpec == "" { - target = tree - } else { - if target, err = tree.Tree(pathSpec); err != nil { - var file *object.File - var fileContent string - var lexer chroma.Lexer - var iterator chroma.Iterator - var style *chroma.Style - var formatter *chromaHTML.Formatter - var formattedHTML template.HTML - - if file, err = tree.File(pathSpec); err != nil { - errorPage500(writer, params, "Error retrieving path: "+err.Error()) - return - } - if redirectNoDir(writer, request) { - return - } - if fileContent, err = file.Contents(); err != nil { - errorPage500(writer, params, "Error reading file: "+err.Error()) - return - } - lexer = chromaLexers.Match(pathSpec) - if lexer == nil { - lexer = chromaLexers.Fallback - } - if iterator, err = lexer.Tokenise(nil, fileContent); err != nil { - errorPage500(writer, params, "Error tokenizing code: "+err.Error()) - return - } - var formattedHTMLStr bytes.Buffer - style = chromaStyles.Get("autumn") - formatter = chromaHTML.New(chromaHTML.WithClasses(true), chromaHTML.TabWidth(8)) - if err = formatter.Format(&formattedHTMLStr, style, iterator); err != nil { - errorPage500(writer, params, "Error formatting code: "+err.Error()) - return - } - formattedHTML = template.HTML(formattedHTMLStr.Bytes()) //#nosec G203 - params["file_contents"] = formattedHTML - - renderTemplate(writer, "repo_tree_file", params) + if file, err = tree.File(pathSpec); err != nil { + errorPage500(writer, params, "Error retrieving path: "+err.Error()) + return + } + if redirectNoDir(writer, request) { + return + } + if fileContent, err = file.Contents(); err != nil { + errorPage500(writer, params, "Error reading file: "+err.Error()) + return + } + lexer = chromaLexers.Match(pathSpec) + if lexer == nil { + lexer = chromaLexers.Fallback + } + if iterator, err = lexer.Tokenise(nil, fileContent); err != nil { + errorPage500(writer, params, "Error tokenizing code: "+err.Error()) return } + var formattedHTMLStr bytes.Buffer + style = chromaStyles.Get("autumn") + formatter = chromaHTML.New(chromaHTML.WithClasses(true), chromaHTML.TabWidth(8)) + if err = formatter.Format(&formattedHTMLStr, style, iterator); err != nil { + errorPage500(writer, params, "Error formatting code: "+err.Error()) + return + } + formattedHTML = template.HTML(formattedHTMLStr.Bytes()) //#nosec G203 + params["file_contents"] = formattedHTML + + renderTemplate(writer, "repo_tree_file", params) + return } if len(rawPathSpec) != 0 && rawPathSpec[len(rawPathSpec)-1] != '/' { -- 2.48.1