aboutsummaryrefslogtreecommitdiff
path: root/models
diff options
context:
space:
mode:
authorzeripath2023-02-27 18:46:00 +0000
committerGitHub2023-02-27 13:46:00 -0500
commitef4fc302468cc8a9fd8f65c4ebdc6f55138450d1 (patch)
treef804073879320d5d0f15d19cbb36d4f7c2a03392 /models
parent0e7bec1849d2d7a87713abe494b4d3ef416180d4 (diff)
Speed up HasUserStopwatch & GetActiveStopwatch (#23051)
GetActiveStopwatch & HasUserStopwatch is a hot piece of code that is repeatedly called and on examination of the cpu profile for TestGit it represents 0.44 seconds of CPU time. This PR reduces this time to 80ms. --------- Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: KN4CK3R <admin@oldschoolhack.me> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: delvh <leon@kske.dev>
Diffstat (limited to 'models')
-rw-r--r--models/issues/stopwatch.go34
-rw-r--r--models/issues/stopwatch_test.go4
2 files changed, 24 insertions, 14 deletions
diff --git a/models/issues/stopwatch.go b/models/issues/stopwatch.go
index 6bf936c5d..c8cd5ad33 100644
--- a/models/issues/stopwatch.go
+++ b/models/issues/stopwatch.go
@@ -9,6 +9,7 @@ import (
"time"
"code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
@@ -132,12 +133,26 @@ func StopwatchExists(userID, issueID int64) bool {
}
// HasUserStopwatch returns true if the user has a stopwatch
-func HasUserStopwatch(ctx context.Context, userID int64) (exists bool, sw *Stopwatch, err error) {
- sw = new(Stopwatch)
+func HasUserStopwatch(ctx context.Context, userID int64) (exists bool, sw *Stopwatch, issue *Issue, err error) {
+ type stopwatchIssueRepo struct {
+ Stopwatch `xorm:"extends"`
+ Issue `xorm:"extends"`
+ repo.Repository `xorm:"extends"`
+ }
+
+ swIR := new(stopwatchIssueRepo)
exists, err = db.GetEngine(ctx).
+ Table("stopwatch").
Where("user_id = ?", userID).
- Get(sw)
- return exists, sw, err
+ Join("INNER", "issue", "issue.id = stopwatch.issue_id").
+ Join("INNER", "repository", "repository.id = issue.repo_id").
+ Get(swIR)
+ if exists {
+ sw = &swIR.Stopwatch
+ issue = &swIR.Issue
+ issue.Repo = &swIR.Repository
+ }
+ return exists, sw, issue, err
}
// FinishIssueStopwatchIfPossible if stopwatch exist then finish it otherwise ignore
@@ -217,23 +232,18 @@ func CreateIssueStopwatch(ctx context.Context, user *user_model.User, issue *Iss
}
// if another stopwatch is running: stop it
- exists, sw, err := HasUserStopwatch(ctx, user.ID)
+ exists, _, otherIssue, err := HasUserStopwatch(ctx, user.ID)
if err != nil {
return err
}
if exists {
- issue, err := GetIssueByID(ctx, sw.IssueID)
- if err != nil {
- return err
- }
-
- if err := FinishIssueStopwatch(ctx, user, issue); err != nil {
+ if err := FinishIssueStopwatch(ctx, user, otherIssue); err != nil {
return err
}
}
// Create stopwatch
- sw = &Stopwatch{
+ sw := &Stopwatch{
UserID: user.ID,
IssueID: issue.ID,
}
diff --git a/models/issues/stopwatch_test.go b/models/issues/stopwatch_test.go
index ec2778aa8..ea3827a1f 100644
--- a/models/issues/stopwatch_test.go
+++ b/models/issues/stopwatch_test.go
@@ -45,12 +45,12 @@ func TestStopwatchExists(t *testing.T) {
func TestHasUserStopwatch(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- exists, sw, err := issues_model.HasUserStopwatch(db.DefaultContext, 1)
+ exists, sw, _, err := issues_model.HasUserStopwatch(db.DefaultContext, 1)
assert.NoError(t, err)
assert.True(t, exists)
assert.Equal(t, int64(1), sw.ID)
- exists, _, err = issues_model.HasUserStopwatch(db.DefaultContext, 3)
+ exists, _, _, err = issues_model.HasUserStopwatch(db.DefaultContext, 3)
assert.NoError(t, err)
assert.False(t, exists)
}