diff options
author | Alan Pearce | 2025-03-21 21:55:00 +0100 |
---|---|---|
committer | Alan Pearce | 2025-03-21 21:55:00 +0100 |
commit | 9c9aa6b408812248c9f8c29ecc3546ef64947ea8 (patch) | |
tree | b99f6e9f62f232db8fff7499a6ddab0b287b5ea3 /internal | |
parent | e8fbdf3bd12c8920a6e9bd84b34e787764b11eaf (diff) | |
download | searchix-9c9aa6b408812248c9f8c29ecc3546ef64947ea8.tar.lz searchix-9c9aa6b408812248c9f8c29ecc3546ef64947ea8.tar.zst searchix-9c9aa6b408812248c9f8c29ecc3546ef64947ea8.zip |
perf: iterate over results without keeping the set in memory
Diffstat (limited to 'internal')
-rw-r--r-- | internal/components/combined.go | 2 | ||||
-rw-r--r-- | internal/components/options.go | 2 | ||||
-rw-r--r-- | internal/components/packages.go | 2 | ||||
-rw-r--r-- | internal/index/search.go | 45 |
4 files changed, 33 insertions, 18 deletions
diff --git a/internal/components/combined.go b/internal/components/combined.go index d8c6fea..fe97e14 100644 --- a/internal/components/combined.go +++ b/internal/components/combined.go @@ -36,7 +36,7 @@ func Combined(result *index.Result) g.Node { ), ), TBody( - g.Map(result.Hits, func(hit index.DocumentMatch) g.Node { + g.MapIter(result.Hits, func(hit index.DocumentMatch) g.Node { return Tr( Td( openCombinedDialogLink(nix.GetKey(hit.Data)), diff --git a/internal/components/options.go b/internal/components/options.go index af6c73f..1d01784 100644 --- a/internal/components/options.go +++ b/internal/components/options.go @@ -21,7 +21,7 @@ func Options(result *index.Result) g.Node { ), ), TBody( - g.Map(result.Hits, func(hit index.DocumentMatch) g.Node { + g.MapIter(result.Hits, func(hit index.DocumentMatch) g.Node { if m := convertMatch[nix.Option](hit.Data); m != nil { return optionRow(hit, *m) } diff --git a/internal/components/packages.go b/internal/components/packages.go index 9bc3f99..db45302 100644 --- a/internal/components/packages.go +++ b/internal/components/packages.go @@ -22,7 +22,7 @@ func Packages(result *index.Result) g.Node { ), ), TBody( - g.Map(result.Hits, func(hit index.DocumentMatch) g.Node { + g.MapIter(result.Hits, func(hit index.DocumentMatch) g.Node { if m := convertMatch[nix.Package](hit.Data); m != nil { return packageRow(hit, *m) } diff --git a/internal/index/search.go b/internal/index/search.go index 3f24799..292661e 100644 --- a/internal/index/search.go +++ b/internal/index/search.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/gob" + "iter" "time" "go.alanpearce.eu/searchix/internal/config" @@ -25,7 +26,7 @@ type DocumentMatch struct { type Result struct { *bleve.SearchResult - Hits []DocumentMatch + Hits iter.Seq[DocumentMatch] } type ReadIndex struct { @@ -87,24 +88,31 @@ func (index *ReadIndex) search( return nil, errors.WithMessage(err, "failed to execute search query") } - results := make([]DocumentMatch, bleveResult.Hits.Len()) - var buf bytes.Buffer - for i, result := range bleveResult.Hits { - results[i].DocumentMatch = bleveResult.Hits[i] - _, err = buf.WriteString(result.Fields["_data"].(string)) - if err != nil { - return nil, errors.WithMessage(err, "error fetching result data") + hits := func(yield func(DocumentMatch) bool) { + var buf bytes.Buffer + for _, match := range bleveResult.Hits { + hit := DocumentMatch{ + DocumentMatch: match, + Data: nil, + } + _, err := buf.WriteString(match.Fields["_data"].(string)) + if err != nil { + index.log.Warn("error fetching result data", "error", err) + } + err = gob.NewDecoder(&buf).Decode(&hit.Data) + if err != nil { + index.log.Warn("error decoding gob data", "error", err, "data", buf.String()) + } + buf.Reset() + if !yield(hit) { + return + } } - err = gob.NewDecoder(&buf).Decode(&results[i].Data) - if err != nil { - return nil, errors.WithMessagef(err, "error decoding gob data: %s", buf.String()) - } - buf.Reset() } return &Result{ SearchResult: bleveResult, - Hits: results, + Hits: hits, }, nil } } @@ -188,6 +196,7 @@ func (index *ReadIndex) GetDocument( key := nix.MakeKey(source, id) query := bleve.NewDocIDQuery([]string{key}) search := bleve.NewSearchRequest(query) + search.Size = 1 result, err := index.search(ctx, search) if err != nil { @@ -198,5 +207,11 @@ func (index *ReadIndex) GetDocument( return nil, nil } - return &result.Hits[0].Data, err + for hit := range result.Hits { + if hit.ID == key { + return &hit.Data, err + } + } + + return nil, err } |