@@ -73,16 +73,7 @@ func (s *searcher) Init(idx *Index, idxCtx *Context, searchSet *SearchSet) {
73
73
func (s * searcher ) Next (ctx context.Context ) (ok bool , err error ) {
74
74
if len (s .levels ) == 0 {
75
75
root := & s .levelStorage [0 ]
76
- root .Init (s .idx , s .idxCtx , nil /* parent */ , & s .searchSet .Stats )
77
-
78
- // Return enough search results to ensure that:
79
- // 1. The number of results requested by the caller is respected.
80
- // 2. There are enough samples for calculating stats.
81
- // 3. There are enough results for adaptive querying to dynamically expand
82
- // the beam size (up to 2x the base beam size).
83
- root .SearchSet ().MaxResults = max (
84
- s .searchSet .MaxResults , s .idx .options .QualitySamples , s .idxCtx .options .BaseBeamSize * 2 )
85
- root .SearchSet ().MaxExtraResults = s .searchSet .MaxExtraResults
76
+ root .Init (s .idx , s .idxCtx , nil /* parent */ , s .searchSet )
86
77
87
78
// Search the root patition in order to discover its level.
88
79
err = root .SearchRoot (ctx )
@@ -110,39 +101,7 @@ func (s *searcher) Next(ctx context.Context) (ok bool, err error) {
110
101
s .levels = utils .EnsureSliceLen (s .levels , n )
111
102
s .levels [0 ] = * root
112
103
for i := 1 ; i < n ; i ++ {
113
- var maxResults , maxExtraResults int
114
- var matchKey KeyBytes
115
- if i == n - 1 {
116
- // This is the last level to be searched, so ensure that:
117
- // 1. The number of results requested by the caller is respected.
118
- // 2. There are enough samples for re-ranking to work well, even if
119
- // there are deleted vectors.
120
- // 3. There are enough samples for calculating stats.
121
- maxResults = s .searchSet .MaxResults
122
- maxExtraResults = s .searchSet .MaxExtraResults
123
- if ! s .idxCtx .options .SkipRerank {
124
- maxResults , maxExtraResults = IncreaseRerankResults (maxResults )
125
- if s .searchSet .MaxExtraResults > maxExtraResults {
126
- maxExtraResults = s .searchSet .MaxExtraResults
127
- }
128
- }
129
- if s .idxCtx .level != LeafLevel && s .idxCtx .options .UpdateStats {
130
- maxResults = max (maxResults , s .idx .options .QualitySamples )
131
- }
132
- matchKey = s .searchSet .MatchKey
133
- } else {
134
- // This is an interior level, so ensure that:
135
- // 1. There are enough samples for calculating stats.
136
- // 2. There are enough results for adaptive querying to dynamically
137
- // expand the beam size (up to 2x the base beam size).
138
- maxResults = max (s .idx .options .QualitySamples , s .idxCtx .options .BaseBeamSize * 2 )
139
- }
140
-
141
- s .levels [i ].Init (s .idx , s .idxCtx , & s .levels [i - 1 ], & s .searchSet .Stats )
142
- searchSet := s .levels [i ].SearchSet ()
143
- searchSet .MaxResults = maxResults
144
- searchSet .MaxExtraResults = maxExtraResults
145
- searchSet .MatchKey = matchKey
104
+ s .levels [i ].Init (s .idx , s .idxCtx , & s .levels [i - 1 ], s .searchSet )
146
105
}
147
106
}
148
107
@@ -234,23 +193,60 @@ type levelSearcher struct {
234
193
// Init sets up the level searcher for iteration. It reuses memory where
235
194
// possible.
236
195
func (s * levelSearcher ) Init (
237
- idx * Index , idxCtx * Context , parent * levelSearcher , stats * SearchStats ,
196
+ idx * Index , idxCtx * Context , parent * levelSearcher , searchSet * SearchSet ,
238
197
) {
239
198
* s = levelSearcher {
240
- idx : idx ,
241
- idxCtx : idxCtx ,
242
- parent : parent ,
243
- stats : stats ,
244
- searchSet : s .searchSet , // Preserve existing searchSet memory.
199
+ idx : idx ,
200
+ idxCtx : idxCtx ,
201
+ parent : parent ,
202
+ stats : & searchSet .Stats ,
245
203
}
246
- if parent != nil {
204
+
205
+ s .searchSet .Init ()
206
+ if parent == nil {
207
+ // This is the root, so its level is not yet known. Return enough search
208
+ // results to ensure that:
209
+ // 1. The number of results requested by the caller is respected.
210
+ // 2. There are enough samples for calculating stats.
211
+ // 3. There are enough results for adaptive querying to dynamically expand
212
+ // the beam size (up to 2x the base beam size).
213
+ s .searchSet .MaxResults = max (
214
+ s .searchSet .MaxResults , idx .options .QualitySamples , idxCtx .options .BaseBeamSize * 2 )
215
+ s .searchSet .MaxExtraResults = searchSet .MaxExtraResults
216
+ } else {
247
217
if parent .Level () == InvalidLevel {
248
218
panic (errors .AssertionFailedf ("parent level cannot be InvalidLevel" ))
249
219
}
250
220
s .level = parent .Level () - 1
221
+ if s .level > idxCtx .level {
222
+ // This is an interior level, so ensure that:
223
+ // 1. There are enough samples for calculating stats.
224
+ // 2. There are enough results for adaptive querying to dynamically
225
+ // expand the beam size (up to 2x the base beam size).
226
+ s .searchSet .MaxResults =
227
+ max (idx .options .QualitySamples , idxCtx .options .BaseBeamSize * 2 )
228
+ } else {
229
+ // This is the last level to be searched, so ensure that:
230
+ // 1. The number of results requested by the caller is respected.
231
+ // 2. There are enough samples for re-ranking to work well, even if
232
+ // there are deleted vectors.
233
+ // 3. There are enough samples for calculating stats.
234
+ maxResults := searchSet .MaxResults
235
+ maxExtraResults := searchSet .MaxExtraResults
236
+ if ! idxCtx .options .SkipRerank {
237
+ maxResults , maxExtraResults = IncreaseRerankResults (maxResults )
238
+ if searchSet .MaxExtraResults > maxExtraResults {
239
+ maxExtraResults = searchSet .MaxExtraResults
240
+ }
241
+ }
242
+ if idxCtx .level != LeafLevel && idxCtx .options .UpdateStats {
243
+ maxResults = max (maxResults , idx .options .QualitySamples )
244
+ }
245
+ s .searchSet .MaxResults = maxResults
246
+ s .searchSet .MaxExtraResults = maxExtraResults
247
+ s .searchSet .MatchKey = searchSet .MatchKey
248
+ }
251
249
}
252
-
253
- s .searchSet .Clear ()
254
250
}
255
251
256
252
// SearchSet returns the target search set to which results are copied for each
0 commit comments