mirror of
https://github.com/go-gitea/gitea
synced 2025-12-05 12:28:26 +00:00
Upgrade blevesearch dependency to v2.0.1 (#14346)
* Upgrade blevesearch dependency to v2.0.1 * Update rupture to v1.0.0 * Fix test
This commit is contained in:
95
vendor/github.com/blevesearch/bleve/v2/search/collector/heap.go
generated
vendored
Normal file
95
vendor/github.com/blevesearch/bleve/v2/search/collector/heap.go
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"container/heap"
|
||||
|
||||
"github.com/blevesearch/bleve/v2/search"
|
||||
)
|
||||
|
||||
type collectStoreHeap struct {
|
||||
heap search.DocumentMatchCollection
|
||||
compare collectorCompare
|
||||
}
|
||||
|
||||
func newStoreHeap(capacity int, compare collectorCompare) *collectStoreHeap {
|
||||
rv := &collectStoreHeap{
|
||||
heap: make(search.DocumentMatchCollection, 0, capacity),
|
||||
compare: compare,
|
||||
}
|
||||
heap.Init(rv)
|
||||
return rv
|
||||
}
|
||||
|
||||
func (c *collectStoreHeap) AddNotExceedingSize(doc *search.DocumentMatch,
|
||||
size int) *search.DocumentMatch {
|
||||
c.add(doc)
|
||||
if c.Len() > size {
|
||||
return c.removeLast()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *collectStoreHeap) add(doc *search.DocumentMatch) {
|
||||
heap.Push(c, doc)
|
||||
}
|
||||
|
||||
func (c *collectStoreHeap) removeLast() *search.DocumentMatch {
|
||||
return heap.Pop(c).(*search.DocumentMatch)
|
||||
}
|
||||
|
||||
func (c *collectStoreHeap) Final(skip int, fixup collectorFixup) (search.DocumentMatchCollection, error) {
|
||||
count := c.Len()
|
||||
size := count - skip
|
||||
if size <= 0 {
|
||||
return make(search.DocumentMatchCollection, 0), nil
|
||||
}
|
||||
rv := make(search.DocumentMatchCollection, size)
|
||||
for i := size - 1; i >= 0; i-- {
|
||||
doc := heap.Pop(c).(*search.DocumentMatch)
|
||||
rv[i] = doc
|
||||
err := fixup(doc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return rv, nil
|
||||
}
|
||||
|
||||
// heap interface implementation
|
||||
|
||||
func (c *collectStoreHeap) Len() int {
|
||||
return len(c.heap)
|
||||
}
|
||||
|
||||
func (c *collectStoreHeap) Less(i, j int) bool {
|
||||
so := c.compare(c.heap[i], c.heap[j])
|
||||
return -so < 0
|
||||
}
|
||||
|
||||
func (c *collectStoreHeap) Swap(i, j int) {
|
||||
c.heap[i], c.heap[j] = c.heap[j], c.heap[i]
|
||||
}
|
||||
|
||||
func (c *collectStoreHeap) Push(x interface{}) {
|
||||
c.heap = append(c.heap, x.(*search.DocumentMatch))
|
||||
}
|
||||
|
||||
func (c *collectStoreHeap) Pop() interface{} {
|
||||
var rv *search.DocumentMatch
|
||||
rv, c.heap = c.heap[len(c.heap)-1], c.heap[:len(c.heap)-1]
|
||||
return rv
|
||||
}
|
||||
86
vendor/github.com/blevesearch/bleve/v2/search/collector/list.go
generated
vendored
Normal file
86
vendor/github.com/blevesearch/bleve/v2/search/collector/list.go
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
|
||||
"github.com/blevesearch/bleve/v2/search"
|
||||
)
|
||||
|
||||
type collectStoreList struct {
|
||||
results *list.List
|
||||
compare collectorCompare
|
||||
}
|
||||
|
||||
func newStoreList(capacity int, compare collectorCompare) *collectStoreList {
|
||||
rv := &collectStoreList{
|
||||
results: list.New(),
|
||||
compare: compare,
|
||||
}
|
||||
|
||||
return rv
|
||||
}
|
||||
|
||||
func (c *collectStoreList) AddNotExceedingSize(doc *search.DocumentMatch, size int) *search.DocumentMatch {
|
||||
c.add(doc)
|
||||
if c.len() > size {
|
||||
return c.removeLast()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *collectStoreList) add(doc *search.DocumentMatch) {
|
||||
for e := c.results.Front(); e != nil; e = e.Next() {
|
||||
curr := e.Value.(*search.DocumentMatch)
|
||||
if c.compare(doc, curr) >= 0 {
|
||||
c.results.InsertBefore(doc, e)
|
||||
return
|
||||
}
|
||||
}
|
||||
// if we got to the end, we still have to add it
|
||||
c.results.PushBack(doc)
|
||||
}
|
||||
|
||||
func (c *collectStoreList) removeLast() *search.DocumentMatch {
|
||||
return c.results.Remove(c.results.Front()).(*search.DocumentMatch)
|
||||
}
|
||||
|
||||
func (c *collectStoreList) Final(skip int, fixup collectorFixup) (search.DocumentMatchCollection, error) {
|
||||
if c.results.Len()-skip > 0 {
|
||||
rv := make(search.DocumentMatchCollection, c.results.Len()-skip)
|
||||
i := 0
|
||||
skipped := 0
|
||||
for e := c.results.Back(); e != nil; e = e.Prev() {
|
||||
if skipped < skip {
|
||||
skipped++
|
||||
continue
|
||||
}
|
||||
|
||||
rv[i] = e.Value.(*search.DocumentMatch)
|
||||
err := fixup(rv[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
i++
|
||||
}
|
||||
return rv, nil
|
||||
}
|
||||
return search.DocumentMatchCollection{}, nil
|
||||
}
|
||||
|
||||
func (c *collectStoreList) len() int {
|
||||
return c.results.Len()
|
||||
}
|
||||
77
vendor/github.com/blevesearch/bleve/v2/search/collector/slice.go
generated
vendored
Normal file
77
vendor/github.com/blevesearch/bleve/v2/search/collector/slice.go
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package collector
|
||||
|
||||
import "github.com/blevesearch/bleve/v2/search"
|
||||
|
||||
type collectStoreSlice struct {
|
||||
slice search.DocumentMatchCollection
|
||||
compare collectorCompare
|
||||
}
|
||||
|
||||
func newStoreSlice(capacity int, compare collectorCompare) *collectStoreSlice {
|
||||
rv := &collectStoreSlice{
|
||||
slice: make(search.DocumentMatchCollection, 0, capacity),
|
||||
compare: compare,
|
||||
}
|
||||
return rv
|
||||
}
|
||||
|
||||
func (c *collectStoreSlice) AddNotExceedingSize(doc *search.DocumentMatch,
|
||||
size int) *search.DocumentMatch {
|
||||
c.add(doc)
|
||||
if c.len() > size {
|
||||
return c.removeLast()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *collectStoreSlice) add(doc *search.DocumentMatch) {
|
||||
// find where to insert, starting at end (lowest)
|
||||
i := len(c.slice)
|
||||
for ; i > 0; i-- {
|
||||
cmp := c.compare(doc, c.slice[i-1])
|
||||
if cmp >= 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
// insert at i
|
||||
c.slice = append(c.slice, nil)
|
||||
copy(c.slice[i+1:], c.slice[i:])
|
||||
c.slice[i] = doc
|
||||
}
|
||||
|
||||
func (c *collectStoreSlice) removeLast() *search.DocumentMatch {
|
||||
var rv *search.DocumentMatch
|
||||
rv, c.slice = c.slice[len(c.slice)-1], c.slice[:len(c.slice)-1]
|
||||
return rv
|
||||
}
|
||||
|
||||
func (c *collectStoreSlice) Final(skip int, fixup collectorFixup) (search.DocumentMatchCollection, error) {
|
||||
for i := skip; i < len(c.slice); i++ {
|
||||
err := fixup(c.slice[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if skip <= len(c.slice) {
|
||||
return c.slice[skip:], nil
|
||||
}
|
||||
return search.DocumentMatchCollection{}, nil
|
||||
}
|
||||
|
||||
func (c *collectStoreSlice) len() int {
|
||||
return len(c.slice)
|
||||
}
|
||||
412
vendor/github.com/blevesearch/bleve/v2/search/collector/topn.go
generated
vendored
Normal file
412
vendor/github.com/blevesearch/bleve/v2/search/collector/topn.go
generated
vendored
Normal file
@@ -0,0 +1,412 @@
|
||||
// Copyright (c) 2014 Couchbase, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/blevesearch/bleve/v2/search"
|
||||
"github.com/blevesearch/bleve/v2/size"
|
||||
index "github.com/blevesearch/bleve_index_api"
|
||||
)
|
||||
|
||||
var reflectStaticSizeTopNCollector int
|
||||
|
||||
func init() {
|
||||
var coll TopNCollector
|
||||
reflectStaticSizeTopNCollector = int(reflect.TypeOf(coll).Size())
|
||||
}
|
||||
|
||||
type collectorStore interface {
|
||||
// Add the document, and if the new store size exceeds the provided size
|
||||
// the last element is removed and returned. If the size has not been
|
||||
// exceeded, nil is returned.
|
||||
AddNotExceedingSize(doc *search.DocumentMatch, size int) *search.DocumentMatch
|
||||
|
||||
Final(skip int, fixup collectorFixup) (search.DocumentMatchCollection, error)
|
||||
}
|
||||
|
||||
// PreAllocSizeSkipCap will cap preallocation to this amount when
|
||||
// size+skip exceeds this value
|
||||
var PreAllocSizeSkipCap = 1000
|
||||
|
||||
type collectorCompare func(i, j *search.DocumentMatch) int
|
||||
|
||||
type collectorFixup func(d *search.DocumentMatch) error
|
||||
|
||||
// TopNCollector collects the top N hits, optionally skipping some results
|
||||
type TopNCollector struct {
|
||||
size int
|
||||
skip int
|
||||
total uint64
|
||||
maxScore float64
|
||||
took time.Duration
|
||||
sort search.SortOrder
|
||||
results search.DocumentMatchCollection
|
||||
facetsBuilder *search.FacetsBuilder
|
||||
|
||||
store collectorStore
|
||||
|
||||
needDocIds bool
|
||||
neededFields []string
|
||||
cachedScoring []bool
|
||||
cachedDesc []bool
|
||||
|
||||
lowestMatchOutsideResults *search.DocumentMatch
|
||||
updateFieldVisitor index.DocValueVisitor
|
||||
dvReader index.DocValueReader
|
||||
searchAfter *search.DocumentMatch
|
||||
}
|
||||
|
||||
// CheckDoneEvery controls how frequently we check the context deadline
|
||||
const CheckDoneEvery = uint64(1024)
|
||||
|
||||
// NewTopNCollector builds a collector to find the top 'size' hits
|
||||
// skipping over the first 'skip' hits
|
||||
// ordering hits by the provided sort order
|
||||
func NewTopNCollector(size int, skip int, sort search.SortOrder) *TopNCollector {
|
||||
return newTopNCollector(size, skip, sort)
|
||||
}
|
||||
|
||||
// NewTopNCollector builds a collector to find the top 'size' hits
|
||||
// skipping over the first 'skip' hits
|
||||
// ordering hits by the provided sort order
|
||||
func NewTopNCollectorAfter(size int, sort search.SortOrder, after []string) *TopNCollector {
|
||||
rv := newTopNCollector(size, 0, sort)
|
||||
rv.searchAfter = &search.DocumentMatch{
|
||||
Sort: after,
|
||||
}
|
||||
|
||||
for pos, ss := range sort {
|
||||
if ss.RequiresDocID() {
|
||||
rv.searchAfter.ID = after[pos]
|
||||
}
|
||||
if ss.RequiresScoring() {
|
||||
if score, err := strconv.ParseFloat(after[pos], 64); err == nil {
|
||||
rv.searchAfter.Score = score
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv
|
||||
}
|
||||
|
||||
func newTopNCollector(size int, skip int, sort search.SortOrder) *TopNCollector {
|
||||
hc := &TopNCollector{size: size, skip: skip, sort: sort}
|
||||
|
||||
// pre-allocate space on the store to avoid reslicing
|
||||
// unless the size + skip is too large, then cap it
|
||||
// everything should still work, just reslices as necessary
|
||||
backingSize := size + skip + 1
|
||||
if size+skip > PreAllocSizeSkipCap {
|
||||
backingSize = PreAllocSizeSkipCap + 1
|
||||
}
|
||||
|
||||
if size+skip > 10 {
|
||||
hc.store = newStoreHeap(backingSize, func(i, j *search.DocumentMatch) int {
|
||||
return hc.sort.Compare(hc.cachedScoring, hc.cachedDesc, i, j)
|
||||
})
|
||||
} else {
|
||||
hc.store = newStoreSlice(backingSize, func(i, j *search.DocumentMatch) int {
|
||||
return hc.sort.Compare(hc.cachedScoring, hc.cachedDesc, i, j)
|
||||
})
|
||||
}
|
||||
|
||||
// these lookups traverse an interface, so do once up-front
|
||||
if sort.RequiresDocID() {
|
||||
hc.needDocIds = true
|
||||
}
|
||||
hc.neededFields = sort.RequiredFields()
|
||||
hc.cachedScoring = sort.CacheIsScore()
|
||||
hc.cachedDesc = sort.CacheDescending()
|
||||
|
||||
return hc
|
||||
}
|
||||
|
||||
func (hc *TopNCollector) Size() int {
|
||||
sizeInBytes := reflectStaticSizeTopNCollector + size.SizeOfPtr
|
||||
|
||||
if hc.facetsBuilder != nil {
|
||||
sizeInBytes += hc.facetsBuilder.Size()
|
||||
}
|
||||
|
||||
for _, entry := range hc.neededFields {
|
||||
sizeInBytes += len(entry) + size.SizeOfString
|
||||
}
|
||||
|
||||
sizeInBytes += len(hc.cachedScoring) + len(hc.cachedDesc)
|
||||
|
||||
return sizeInBytes
|
||||
}
|
||||
|
||||
// Collect goes to the index to find the matching documents
|
||||
func (hc *TopNCollector) Collect(ctx context.Context, searcher search.Searcher, reader index.IndexReader) error {
|
||||
startTime := time.Now()
|
||||
var err error
|
||||
var next *search.DocumentMatch
|
||||
|
||||
// pre-allocate enough space in the DocumentMatchPool
|
||||
// unless the size + skip is too large, then cap it
|
||||
// everything should still work, just allocates DocumentMatches on demand
|
||||
backingSize := hc.size + hc.skip + 1
|
||||
if hc.size+hc.skip > PreAllocSizeSkipCap {
|
||||
backingSize = PreAllocSizeSkipCap + 1
|
||||
}
|
||||
searchContext := &search.SearchContext{
|
||||
DocumentMatchPool: search.NewDocumentMatchPool(backingSize+searcher.DocumentMatchPoolSize(), len(hc.sort)),
|
||||
Collector: hc,
|
||||
IndexReader: reader,
|
||||
}
|
||||
|
||||
hc.dvReader, err = reader.DocValueReader(hc.neededFields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hc.updateFieldVisitor = func(field string, term []byte) {
|
||||
if hc.facetsBuilder != nil {
|
||||
hc.facetsBuilder.UpdateVisitor(field, term)
|
||||
}
|
||||
hc.sort.UpdateVisitor(field, term)
|
||||
}
|
||||
|
||||
dmHandlerMaker := MakeTopNDocumentMatchHandler
|
||||
if cv := ctx.Value(search.MakeDocumentMatchHandlerKey); cv != nil {
|
||||
dmHandlerMaker = cv.(search.MakeDocumentMatchHandler)
|
||||
}
|
||||
// use the application given builder for making the custom document match
|
||||
// handler and perform callbacks/invocations on the newly made handler.
|
||||
dmHandler, loadID, err := dmHandlerMaker(searchContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hc.needDocIds = hc.needDocIds || loadID
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
next, err = searcher.Next(searchContext)
|
||||
}
|
||||
for err == nil && next != nil {
|
||||
if hc.total%CheckDoneEvery == 0 {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
err = hc.prepareDocumentMatch(searchContext, reader, next)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
err = dmHandler(next)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
next, err = searcher.Next(searchContext)
|
||||
}
|
||||
|
||||
// help finalize/flush the results in case
|
||||
// of custom document match handlers.
|
||||
err = dmHandler(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// compute search duration
|
||||
hc.took = time.Since(startTime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// finalize actual results
|
||||
err = hc.finalizeResults(reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var sortByScoreOpt = []string{"_score"}
|
||||
|
||||
func (hc *TopNCollector) prepareDocumentMatch(ctx *search.SearchContext,
|
||||
reader index.IndexReader, d *search.DocumentMatch) (err error) {
|
||||
|
||||
// visit field terms for features that require it (sort, facets)
|
||||
if len(hc.neededFields) > 0 {
|
||||
err = hc.visitFieldTerms(reader, d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// increment total hits
|
||||
hc.total++
|
||||
d.HitNumber = hc.total
|
||||
|
||||
// update max score
|
||||
if d.Score > hc.maxScore {
|
||||
hc.maxScore = d.Score
|
||||
}
|
||||
|
||||
// see if we need to load ID (at this early stage, for example to sort on it)
|
||||
if hc.needDocIds {
|
||||
d.ID, err = reader.ExternalID(d.IndexInternalID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// compute this hits sort value
|
||||
if len(hc.sort) == 1 && hc.cachedScoring[0] {
|
||||
d.Sort = sortByScoreOpt
|
||||
} else {
|
||||
hc.sort.Value(d)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func MakeTopNDocumentMatchHandler(
|
||||
ctx *search.SearchContext) (search.DocumentMatchHandler, bool, error) {
|
||||
var hc *TopNCollector
|
||||
var ok bool
|
||||
if hc, ok = ctx.Collector.(*TopNCollector); ok {
|
||||
return func(d *search.DocumentMatch) error {
|
||||
if d == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// support search after based pagination,
|
||||
// if this hit is <= the search after sort key
|
||||
// we should skip it
|
||||
if hc.searchAfter != nil {
|
||||
// exact sort order matches use hit number to break tie
|
||||
// but we want to allow for exact match, so we pretend
|
||||
hc.searchAfter.HitNumber = d.HitNumber
|
||||
if hc.sort.Compare(hc.cachedScoring, hc.cachedDesc, d, hc.searchAfter) <= 0 {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// optimization, we track lowest sorting hit already removed from heap
|
||||
// with this one comparison, we can avoid all heap operations if
|
||||
// this hit would have been added and then immediately removed
|
||||
if hc.lowestMatchOutsideResults != nil {
|
||||
cmp := hc.sort.Compare(hc.cachedScoring, hc.cachedDesc, d,
|
||||
hc.lowestMatchOutsideResults)
|
||||
if cmp >= 0 {
|
||||
// this hit can't possibly be in the result set, so avoid heap ops
|
||||
ctx.DocumentMatchPool.Put(d)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
removed := hc.store.AddNotExceedingSize(d, hc.size+hc.skip)
|
||||
if removed != nil {
|
||||
if hc.lowestMatchOutsideResults == nil {
|
||||
hc.lowestMatchOutsideResults = removed
|
||||
} else {
|
||||
cmp := hc.sort.Compare(hc.cachedScoring, hc.cachedDesc,
|
||||
removed, hc.lowestMatchOutsideResults)
|
||||
if cmp < 0 {
|
||||
tmp := hc.lowestMatchOutsideResults
|
||||
hc.lowestMatchOutsideResults = removed
|
||||
ctx.DocumentMatchPool.Put(tmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}, false, nil
|
||||
}
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
// visitFieldTerms is responsible for visiting the field terms of the
|
||||
// search hit, and passing visited terms to the sort and facet builder
|
||||
func (hc *TopNCollector) visitFieldTerms(reader index.IndexReader, d *search.DocumentMatch) error {
|
||||
if hc.facetsBuilder != nil {
|
||||
hc.facetsBuilder.StartDoc()
|
||||
}
|
||||
|
||||
err := hc.dvReader.VisitDocValues(d.IndexInternalID, hc.updateFieldVisitor)
|
||||
if hc.facetsBuilder != nil {
|
||||
hc.facetsBuilder.EndDoc()
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// SetFacetsBuilder registers a facet builder for this collector
|
||||
func (hc *TopNCollector) SetFacetsBuilder(facetsBuilder *search.FacetsBuilder) {
|
||||
hc.facetsBuilder = facetsBuilder
|
||||
hc.neededFields = append(hc.neededFields, hc.facetsBuilder.RequiredFields()...)
|
||||
}
|
||||
|
||||
// finalizeResults starts with the heap containing the final top size+skip
|
||||
// it now throws away the results to be skipped
|
||||
// and does final doc id lookup (if necessary)
|
||||
func (hc *TopNCollector) finalizeResults(r index.IndexReader) error {
|
||||
var err error
|
||||
hc.results, err = hc.store.Final(hc.skip, func(doc *search.DocumentMatch) error {
|
||||
if doc.ID == "" {
|
||||
// look up the id since we need it for lookup
|
||||
var err error
|
||||
doc.ID, err = r.ExternalID(doc.IndexInternalID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
doc.Complete(nil)
|
||||
return nil
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Results returns the collected hits
|
||||
func (hc *TopNCollector) Results() search.DocumentMatchCollection {
|
||||
return hc.results
|
||||
}
|
||||
|
||||
// Total returns the total number of hits
|
||||
func (hc *TopNCollector) Total() uint64 {
|
||||
return hc.total
|
||||
}
|
||||
|
||||
// MaxScore returns the maximum score seen across all the hits
|
||||
func (hc *TopNCollector) MaxScore() float64 {
|
||||
return hc.maxScore
|
||||
}
|
||||
|
||||
// Took returns the time spent collecting hits
|
||||
func (hc *TopNCollector) Took() time.Duration {
|
||||
return hc.took
|
||||
}
|
||||
|
||||
// FacetResults returns the computed facets results
|
||||
func (hc *TopNCollector) FacetResults() search.FacetResults {
|
||||
if hc.facetsBuilder != nil {
|
||||
return hc.facetsBuilder.Results()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user