Skip to content

Commit

Permalink
refactor numeric keyword detection
Browse files Browse the repository at this point in the history
  • Loading branch information
silkentrance committed Jun 29, 2024
1 parent e546736 commit 488e0db
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 27 deletions.
34 changes: 15 additions & 19 deletions modules/indexer/issues/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,32 +49,28 @@ func (i *Indexer) Search(ctx context.Context, options *internal.SearchOptions) (
// But the two functions are used in modules/notification/indexer, that means we will import services/indexer in modules/notification/indexer.
// So that's the root problem:
// The notification is defined in modules, but it's using lots of things should be in services.

cond := builder.NewCond()
if options.Keyword != "" {
repoCond := builder.In("repo_id", options.RepoIDs)
if len(options.RepoIDs) == 1 {
repoCond = builder.Eq{"repo_id": options.RepoIDs[0]}
}

if options.Index.Has() {
cond = builder.And(
subQuery := builder.Select("id").From("issue").Where(repoCond)
cond = builder.Or(
db.BuildCaseInsensitiveLike("issue.name", options.Keyword),
db.BuildCaseInsensitiveLike("issue.content", options.Keyword),
builder.In("issue.id", builder.Select("issue_id").
From("comment").
Where(builder.And(
builder.Eq{"type": issue_model.CommentTypeComment},
builder.In("issue_id", subQuery),
db.BuildCaseInsensitiveLike("content", options.Keyword),
)),
),
)
if options.IsKeywordNumeric() {
cond = cond.Or(
builder.Eq{"`index`": options.Keyword},
repoCond,
)
} else {
subQuery := builder.Select("id").From("issue").Where(repoCond)
cond = builder.Or(
db.BuildCaseInsensitiveLike("issue.name", options.Keyword),
db.BuildCaseInsensitiveLike("issue.content", options.Keyword),
builder.In("issue.id", builder.Select("issue_id").
From("comment").
Where(builder.And(
builder.Eq{"type": issue_model.CommentTypeComment},
builder.In("issue_id", subQuery),
db.BuildCaseInsensitiveLike("content", options.Keyword),
)),
),
)
}
}
Expand Down
7 changes: 1 addition & 6 deletions modules/indexer/issues/indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"fmt"
"os"
"runtime/pprof"
"strconv"
"sync/atomic"
"time"

Expand Down Expand Up @@ -284,11 +283,7 @@ const (
func SearchIssues(ctx context.Context, opts *SearchOptions) ([]int64, int64, error) {
indexer := *globalIndexer.Load()

issueIndex, err := strconv.Atoi(opts.Keyword)
if err == nil {
opts.Index = optional.Option[int64]{int64(issueIndex)}
}
if opts.Keyword == "" || opts.Index.Has() {
if opts.Keyword == "" || opts.IsKeywordNumeric() {
// This is a conservative shortcut.
// If the keyword is empty or an integer, db has better (at least not worse) performance to filter issues.
// When the keyword is empty, it tends to listing rather than searching issues.
Expand Down
10 changes: 8 additions & 2 deletions modules/indexer/issues/internal/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
package internal

import (
"strconv"

"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/timeutil"
Expand Down Expand Up @@ -89,8 +91,6 @@ type SearchOptions struct {

MilestoneIDs []int64 // milestones the issues have

Index optional.Option[int64] // keyword as potential issue index

ProjectID optional.Option[int64] // project the issues belong to
ProjectColumnID optional.Option[int64] // project column the issues belong to

Expand Down Expand Up @@ -126,6 +126,12 @@ func (o *SearchOptions) Copy(edit ...func(options *SearchOptions)) *SearchOption
return &v
}

// used for optimized issue index based search
func (o *SearchOptions) IsKeywordNumeric() bool {
_, err := strconv.Atoi(o.Keyword)
return err == nil
}

type SortBy string

const (
Expand Down

0 comments on commit 488e0db

Please sign in to comment.