aboutsummaryrefslogtreecommitdiff
path: root/internal/postgres
diff options
context:
space:
mode:
authorJulie Qiu <julie@golang.org>2021-09-03 15:52:16 -0400
committerJulie Qiu <julie@golang.org>2021-09-07 14:32:57 +0000
commit4322f8fca5fef51561125ef77ffacdbf8189e2b3 (patch)
tree8ed5926625ef1551b021b942f50b13908eb83b22 /internal/postgres
parent71290cf8cfc29e4367da3e03b1edc70a1727b702 (diff)
downloadgo-x-pkgsite-4322f8fca5fef51561125ef77ffacdbf8189e2b3.tar.xz
internal/postgres: change searcher signature
The searcher type is changed from the type: func(db *DB, ctx context.Context, q string, limit, offset, maxResultCount int) searchResponse to: func(db *DB, ctx context.Context, q string, limit int, opts SearchOptions) searchResponse More fields will be added to SearchOptions in a later CL. For golang/go#44142 Change-Id: I96e8b81e5fe10fcf3637d420eaf723c061699225 Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/347609 Trust: Julie Qiu <julie@golang.org> Run-TryBot: Julie Qiu <julie@golang.org> TryBot-Result: kokoro <noreply+kokoro@google.com> Reviewed-by: Jonathan Amsterdam <jba@google.com>
Diffstat (limited to 'internal/postgres')
-rw-r--r--internal/postgres/search.go38
-rw-r--r--internal/postgres/search_test.go26
-rw-r--r--internal/postgres/symbolsearch.go2
-rw-r--r--internal/postgres/symbolsearch_test.go6
4 files changed, 48 insertions, 24 deletions
diff --git a/internal/postgres/search.go b/internal/postgres/search.go
index 6cbf43e3..a549304d 100644
--- a/internal/postgres/search.go
+++ b/internal/postgres/search.go
@@ -84,7 +84,7 @@ type searchEvent struct {
}
// A searcher is used to execute a single search request.
-type searcher func(db *DB, ctx context.Context, q string, limit, offset, maxResultCount int) searchResponse
+type searcher func(db *DB, ctx context.Context, q string, limit int, opts SearchOptions) searchResponse
// The pkgSearchers used by Search.
var pkgSearchers = map[string]searcher{
@@ -96,13 +96,17 @@ var symbolSearchers = map[string]searcher{
"symbol": (*DB).symbolSearch,
}
+// SearchOptions provide information used by db.Search.
type SearchOptions struct {
// Maximum number of results to return (page size).
MaxResults int
+
// Offset for DB query.
Offset int
+
// Maximum number to use for total result count.
MaxResultCount int
+
// If true, perform a symbol search.
SearchSymbols bool
}
@@ -213,7 +217,7 @@ func (db *DB) search(ctx context.Context, q string, opts SearchOptions, limit in
} else {
searchers = pkgSearchers
}
- resp, err := db.hedgedSearch(ctx, q, limit, opts.Offset, opts.MaxResultCount, searchers, nil)
+ resp, err := db.hedgedSearch(ctx, q, limit, opts, searchers, nil)
if err != nil {
return nil, err
}
@@ -270,8 +274,8 @@ var scoreExpr = fmt.Sprintf(`
// available result.
// The optional guardTestResult func may be used to allow tests to control the
// order in which search results are returned.
-func (db *DB) hedgedSearch(ctx context.Context, q string, limit, offset, maxResultCount int, searchers map[string]searcher, guardTestResult func(string) func()) (_ *searchResponse, err error) {
- defer derrors.WrapStack(&err, "hedgedSearch(ctx, %q, %d, %d, %d)", q, limit, offset, maxResultCount)
+func (db *DB) hedgedSearch(ctx context.Context, q string, limit int, opts SearchOptions, searchers map[string]searcher, guardTestResult func(string) func()) (_ *searchResponse, err error) {
+ defer derrors.WrapStack(&err, "hedgedSearch(ctx, %q, %d, %+v)", q, limit, opts)
searchStart := time.Now()
responses := make(chan searchResponse, len(searchers))
@@ -285,7 +289,7 @@ func (db *DB) hedgedSearch(ctx context.Context, q string, limit, offset, maxResu
s := s
go func() {
start := time.Now()
- resp := s(db, searchCtx, q, limit, offset, maxResultCount)
+ resp := s(db, searchCtx, q, limit, opts)
log.Debug(ctx, searchEvent{
Type: resp.source,
Latency: time.Since(start),
@@ -329,7 +333,7 @@ const hllRegisterCount = 128
// deepSearch searches all packages for the query. It is slower, but results
// are always valid.
-func (db *DB) deepSearch(ctx context.Context, q string, limit, offset, maxResultCount int) searchResponse {
+func (db *DB) deepSearch(ctx context.Context, q string, limit int, opts SearchOptions) searchResponse {
query := fmt.Sprintf(`
SELECT *, COUNT(*) OVER() AS total
FROM (
@@ -378,7 +382,7 @@ func (db *DB) deepSearch(ctx context.Context, q string, limit, offset, maxResult
return nil
}
const fetchSize = 20 // number of rows to fetch at a time
- err = db.db.RunQueryIncrementally(ctx, query, fetchSize, collect, q, limit, offset)
+ err = db.db.RunQueryIncrementally(ctx, query, fetchSize, collect, q, limit, opts.Offset)
} else {
collect := func(rows *sql.Rows) error {
var r SearchResult
@@ -389,17 +393,17 @@ func (db *DB) deepSearch(ctx context.Context, q string, limit, offset, maxResult
results = append(results, &r)
return nil
}
- err = db.db.RunQuery(ctx, query, collect, q, limit, offset)
+ err = db.db.RunQuery(ctx, query, collect, q, limit, opts.Offset)
}
if err != nil {
results = nil
}
for i, r := range results {
- r.Offset = offset + i
+ r.Offset = opts.Offset + i
}
- if len(results) > 0 && results[0].NumResults > uint64(maxResultCount) {
+ if len(results) > 0 && results[0].NumResults > uint64(opts.MaxResultCount) {
for _, r := range results {
- r.NumResults = uint64(maxResultCount)
+ r.NumResults = uint64(opts.MaxResultCount)
}
}
return searchResponse{
@@ -409,7 +413,7 @@ func (db *DB) deepSearch(ctx context.Context, q string, limit, offset, maxResult
}
}
-func (db *DB) popularSearch(ctx context.Context, searchQuery string, limit, offset, maxResultCount int) searchResponse {
+func (db *DB) popularSearch(ctx context.Context, searchQuery string, limit int, opts SearchOptions) searchResponse {
query := `
SELECT
package_path,
@@ -429,20 +433,20 @@ func (db *DB) popularSearch(ctx context.Context, searchQuery string, limit, offs
results = append(results, &r)
return nil
}
- err := db.db.RunQuery(ctx, query, collect, searchQuery, limit, offset, nonRedistributablePenalty, noGoModPenalty)
+ err := db.db.RunQuery(ctx, query, collect, searchQuery, limit, opts.Offset, nonRedistributablePenalty, noGoModPenalty)
if err != nil {
results = nil
}
- numResults := maxResultCount
- if offset+limit > maxResultCount || len(results) < limit {
+ numResults := opts.MaxResultCount
+ if opts.Offset+limit > opts.MaxResultCount || len(results) < limit {
// It is practically impossible that len(results) < limit, because popular
// search will never linearly scan everything before deep search completes,
// but just to be slightly more theoretically correct, if our search
// results are partial we know that we have exhausted all results.
- numResults = offset + len(results)
+ numResults = opts.Offset + len(results)
}
for i, r := range results {
- r.Offset = offset + i
+ r.Offset = opts.Offset + i
r.NumResults = uint64(numResults)
}
return searchResponse{
diff --git a/internal/postgres/search_test.go b/internal/postgres/search_test.go
index e942b14c..b229ba6d 100644
--- a/internal/postgres/search_test.go
+++ b/internal/postgres/search_test.go
@@ -455,7 +455,11 @@ func testSearch(t *testing.T, ctx context.Context) {
t.Fatal(err)
}
guardTestResult := resultGuard(t, test.resultOrder)
- resp, err := testDB.hedgedSearch(ctx, "foo", 2, 0, 100, pkgSearchers, guardTestResult)
+ opts := SearchOptions{
+ Offset: 0,
+ MaxResultCount: 100,
+ }
+ resp, err := testDB.hedgedSearch(ctx, "foo", 2, opts, pkgSearchers, guardTestResult)
if err != nil {
t.Fatal(err)
}
@@ -492,7 +496,7 @@ func TestSearchErrors(t *testing.T) {
for name, search := range pkgSearchers {
if name == searcherName {
name := name
- newSearchers[name] = func(*DB, context.Context, string, int, int, int) searchResponse {
+ newSearchers[name] = func(*DB, context.Context, string, int, SearchOptions) searchResponse {
return searchResponse{
source: name,
err: errors.New("bad"),
@@ -543,7 +547,11 @@ func TestSearchErrors(t *testing.T) {
t.Fatal(err)
}
guardTestResult := resultGuard(t, test.resultOrder)
- resp, err := testDB.hedgedSearch(ctx, "foo", 2, 0, 100, test.searchers, guardTestResult)
+ opts := SearchOptions{
+ Offset: 0,
+ MaxResultCount: 100,
+ }
+ resp, err := testDB.hedgedSearch(ctx, "foo", 2, opts, test.searchers, guardTestResult)
if (err != nil) != test.wantErr {
t.Fatalf("hedgedSearch(): got error %v, want error: %t", err, test.wantErr)
}
@@ -714,7 +722,11 @@ func TestInsertSearchDocumentAndSearch(t *testing.T) {
test.limit = 10
}
- got := searcher(testDB, ctx, test.searchQuery, test.limit, test.offset, 100)
+ opts := SearchOptions{
+ Offset: test.offset,
+ MaxResultCount: 100,
+ }
+ got := searcher(testDB, ctx, test.searchQuery, test.limit, opts)
if got.err != nil {
t.Fatal(got.err)
}
@@ -768,7 +780,11 @@ func TestSearchPenalties(t *testing.T) {
for method, searcher := range pkgSearchers {
t.Run(method, func(t *testing.T) {
- res := searcher(testDB, ctx, "foo", 10, 0, 100)
+ opts := SearchOptions{
+ Offset: 0,
+ MaxResultCount: 100,
+ }
+ res := searcher(testDB, ctx, "foo", 10, opts)
if res.err != nil {
t.Fatal(res.err)
}
diff --git a/internal/postgres/symbolsearch.go b/internal/postgres/symbolsearch.go
index 9ae9800e..826ac31b 100644
--- a/internal/postgres/symbolsearch.go
+++ b/internal/postgres/symbolsearch.go
@@ -96,7 +96,7 @@ func upsertSymbolSearchDocuments(ctx context.Context, tx *database.DB,
//
// TODO(https://golang.org/issue/44142): factor out common code between
// symbolSearch and deepSearch.
-func (db *DB) symbolSearch(ctx context.Context, q string, limit, offset, maxResultCount int) searchResponse {
+func (db *DB) symbolSearch(ctx context.Context, q string, limit int, opts SearchOptions) searchResponse {
defer middleware.ElapsedStat(ctx, "symbolSearch")()
var (
diff --git a/internal/postgres/symbolsearch_test.go b/internal/postgres/symbolsearch_test.go
index 2b9021f7..5c908b4e 100644
--- a/internal/postgres/symbolsearch_test.go
+++ b/internal/postgres/symbolsearch_test.go
@@ -105,7 +105,11 @@ func TestSymbolSearch(t *testing.T) {
},
} {
t.Run(strings.ReplaceAll(strings.ReplaceAll(test.name, "<", "_"), ">", "_"), func(t *testing.T) {
- resp, err := testDB.hedgedSearch(ctx, test.q, 2, 0, 100, symbolSearchers, nil)
+ opts := SearchOptions{
+ Offset: 0,
+ MaxResultCount: 100,
+ }
+ resp, err := testDB.hedgedSearch(ctx, test.q, 2, opts, symbolSearchers, nil)
if err != nil {
t.Fatal(err)
}