diff --git a/analysis/analyzer/custom/custom.go b/analysis/analyzer/custom/custom.go index 5df940e5e..9040e0283 100644 --- a/analysis/analyzer/custom/custom.go +++ b/analysis/analyzer/custom/custom.go @@ -140,7 +140,7 @@ func convertInterfaceSliceToStringSlice(interfaceSlice []interface{}, objType st if ok { stringSlice[i] = stringObj } else { - return nil, fmt.Errorf(objType + " name must be a string") + return nil, fmt.Errorf("%s name must be a string", objType) } } diff --git a/analysis/datetime/iso/iso.go b/analysis/datetime/iso/iso.go index df947a6c0..7a8186999 100644 --- a/analysis/datetime/iso/iso.go +++ b/analysis/datetime/iso/iso.go @@ -118,7 +118,7 @@ func letterCounter(layout string, idx int) int { } func invalidFormatError(character byte, count int) error { - return fmt.Errorf("invalid format string, unknown format specifier: " + strings.Repeat(string(character), count)) + return fmt.Errorf("invalid format string, unknown format specifier: %s", strings.Repeat(string(character), count)) } func parseISOString(layout string) (string, error) { @@ -146,7 +146,7 @@ func parseISOString(layout string) (string, error) { // second text literal delimiter if idx == len(layout) { // text literal delimiter not found error - return "", fmt.Errorf("invalid format string, expected text literal delimiter: " + string(textLiteralDelimiter)) + return "", fmt.Errorf("invalid format string, expected text literal delimiter: %s", string(textLiteralDelimiter)) } // increment idx to skip the second text literal delimiter idx++ diff --git a/cmd/bleve/cmd/registry.go b/cmd/bleve/cmd/registry.go index 9d5fc3f4e..5c6566b12 100644 --- a/cmd/bleve/cmd/registry.go +++ b/cmd/bleve/cmd/registry.go @@ -71,12 +71,12 @@ var registryCmd = &cobra.Command{ func printType(label string, types, instances []string) { sort.Strings(types) sort.Strings(instances) - fmt.Printf(label + " Types:\n") + fmt.Printf("%s Types:\n", label) for _, name := range types { fmt.Printf("\t%s\n", name) } fmt.Println() - fmt.Printf(label + " Instances:\n") + fmt.Printf("%s Instances:\n", label) for _, name := range instances { fmt.Printf("\t%s\n", name) } diff --git a/go.mod b/go.mod index 682cdd38e..f42060a43 100644 --- a/go.mod +++ b/go.mod @@ -1,20 +1,18 @@ module github.com/blevesearch/bleve/v2 -go 1.23 - -toolchain go1.23.9 +go 1.24 require ( github.com/RoaringBitmap/roaring/v2 v2.4.5 github.com/bits-and-blooms/bitset v1.22.0 - github.com/blevesearch/bleve_index_api v1.2.11 + github.com/blevesearch/bleve_index_api v1.2.12-0.20260109154621-f19a6d6af728 github.com/blevesearch/geo v0.2.4 - github.com/blevesearch/go-faiss v1.0.26 + github.com/blevesearch/go-faiss v1.0.27 github.com/blevesearch/go-metrics v0.0.0-20201227073835-cf1acfcdf475 github.com/blevesearch/go-porterstemmer v1.0.3 github.com/blevesearch/goleveldb v1.0.1 github.com/blevesearch/gtreap v0.1.1 - github.com/blevesearch/scorch_segment_api/v2 v2.3.13 + github.com/blevesearch/scorch_segment_api/v2 v2.3.14-0.20260109154938-b56b54c737df github.com/blevesearch/segment v0.9.1 github.com/blevesearch/snowball v0.6.1 github.com/blevesearch/snowballstem v0.9.0 @@ -27,6 +25,7 @@ require ( github.com/blevesearch/zapx/v14 v14.4.2 github.com/blevesearch/zapx/v15 v15.4.2 github.com/blevesearch/zapx/v16 v16.2.8 + github.com/blevesearch/zapx/v17 v17.0.0-20260112205515-7d8cac80436c github.com/couchbase/moss v0.2.0 github.com/spf13/cobra v1.8.1 go.etcd.io/bbolt v1.4.0 diff --git a/go.sum b/go.sum index 01d5c198e..7fcf2f40f 100644 --- a/go.sum +++ b/go.sum @@ -3,12 +3,12 @@ github.com/RoaringBitmap/roaring/v2 v2.4.5/go.mod h1:FiJcsfkGje/nZBZgCu0ZxCPOKD/ github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bits-and-blooms/bitset v1.22.0 h1:Tquv9S8+SGaS3EhyA+up3FXzmkhxPGjQQCkcs2uw7w4= github.com/bits-and-blooms/bitset v1.22.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/blevesearch/bleve_index_api v1.2.11 h1:bXQ54kVuwP8hdrXUSOnvTQfgK0KI1+f9A0ITJT8tX1s= -github.com/blevesearch/bleve_index_api v1.2.11/go.mod h1:rKQDl4u51uwafZxFrPD1R7xFOwKnzZW7s/LSeK4lgo0= +github.com/blevesearch/bleve_index_api v1.2.12-0.20260109154621-f19a6d6af728 h1:qFnvr+SqVOCbhMl5sVynhuwVkv1yrc7Vhrn8lVdw1nU= +github.com/blevesearch/bleve_index_api v1.2.12-0.20260109154621-f19a6d6af728/go.mod h1:xvd48t5XMeeioWQ5/jZvgLrV98flT2rdvEJ3l/ki4Ko= github.com/blevesearch/geo v0.2.4 h1:ECIGQhw+QALCZaDcogRTNSJYQXRtC8/m8IKiA706cqk= github.com/blevesearch/geo v0.2.4/go.mod h1:K56Q33AzXt2YExVHGObtmRSFYZKYGv0JEN5mdacJJR8= -github.com/blevesearch/go-faiss v1.0.26 h1:4dRLolFgjPyjkaXwff4NfbZFdE/dfywbzDqporeQvXI= -github.com/blevesearch/go-faiss v1.0.26/go.mod h1:OMGQwOaRRYxrmeNdMrXJPvVx8gBnvE5RYrr0BahNnkk= +github.com/blevesearch/go-faiss v1.0.27 h1:7cBImYDDQ82WJd5RUZ1ie6zXztCsC73W94ZzwOjkatk= +github.com/blevesearch/go-faiss v1.0.27/go.mod h1:OMGQwOaRRYxrmeNdMrXJPvVx8gBnvE5RYrr0BahNnkk= github.com/blevesearch/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:kDy+zgJFJJoJYBvdfBSiZYBbdsUL0XcjHYWezpQBGPA= github.com/blevesearch/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:9eJDeqxJ3E7WnLebQUlPD7ZjSce7AnDb9vjGmMCbD0A= github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo= @@ -20,8 +20,8 @@ github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgY github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+7LMvAB5IbSA= github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc= github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs= -github.com/blevesearch/scorch_segment_api/v2 v2.3.13 h1:ZPjv/4VwWvHJZKeMSgScCapOy8+DdmsmRyLmSB88UoY= -github.com/blevesearch/scorch_segment_api/v2 v2.3.13/go.mod h1:ENk2LClTehOuMS8XzN3UxBEErYmtwkE7MAArFTXs9Vc= +github.com/blevesearch/scorch_segment_api/v2 v2.3.14-0.20260109154938-b56b54c737df h1:gBuVkzZLUpGJGnCBRgY0ruZVjppD7WaQLeHZei7QQnU= +github.com/blevesearch/scorch_segment_api/v2 v2.3.14-0.20260109154938-b56b54c737df/go.mod h1:f8fXitmMpzgNziIMqUlpTrfPxVVDN8at9k7POEohvJU= github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU= github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw= github.com/blevesearch/snowball v0.6.1 h1:cDYjn/NCH+wwt2UdehaLpr2e4BwLIjN4V/TdLsL+B5A= @@ -46,6 +46,8 @@ github.com/blevesearch/zapx/v15 v15.4.2 h1:sWxpDE0QQOTjyxYbAVjt3+0ieu8NCE0fDRaFx github.com/blevesearch/zapx/v15 v15.4.2/go.mod h1:1pssev/59FsuWcgSnTa0OeEpOzmhtmr/0/11H0Z8+Nw= github.com/blevesearch/zapx/v16 v16.2.8 h1:SlnzF0YGtSlrsOE3oE7EgEX6BIepGpeqxs1IjMbHLQI= github.com/blevesearch/zapx/v16 v16.2.8/go.mod h1:murSoCJPCk25MqURrcJaBQ1RekuqSCSfMjXH4rHyA14= +github.com/blevesearch/zapx/v17 v17.0.0-20260112205515-7d8cac80436c h1:OfYh0noLbJmt6k2tqYlnSU3zMZEJbFfbSClSGG59A/M= +github.com/blevesearch/zapx/v17 v17.0.0-20260112205515-7d8cac80436c/go.mod h1:ybWwo00MGrNJuFDnl9smEBVUCZmNANf0+E/QVBmfBTs= github.com/couchbase/ghistogram v0.1.0 h1:b95QcQTCzjTUocDXp/uMgSNQi8oj1tGwnJ4bODWZnps= github.com/couchbase/ghistogram v0.1.0/go.mod h1:s1Jhy76zqfEecpNWJfWUiKZookAFaiGOEoyzgHt9i7k= github.com/couchbase/moss v0.2.0 h1:VCYrMzFwEryyhRSeI+/b3tRBSeTpi/8gn5Kf6dxqn+o= diff --git a/index/scorch/optimize.go b/index/scorch/optimize.go index 20a0706ef..658fb08dd 100644 --- a/index/scorch/optimize.go +++ b/index/scorch/optimize.go @@ -395,5 +395,7 @@ func (i *IndexSnapshot) unadornedTermFieldReader( recycle: false, // signal downstream that this is a special unadorned termFieldReader unadorned: true, + // unadorned TFRs do not require bytes read tracking + updateBytesRead: false, } } diff --git a/index/scorch/optimize_knn.go b/index/scorch/optimize_knn.go index affb4ff13..29f80b4cc 100644 --- a/index/scorch/optimize_knn.go +++ b/index/scorch/optimize_knn.go @@ -34,8 +34,6 @@ type OptimizeVR struct { totalCost uint64 // maps field to vector readers vrs map[string][]*IndexSnapshotVectorReader - // if at least one of the vector readers requires filtered kNN. - requiresFiltering bool } // This setting _MUST_ only be changed during init and not after. @@ -85,8 +83,7 @@ func (o *OptimizeVR) Finish() error { continue } - vecIndex, err := segment.InterpretVectorIndex(field, - o.requiresFiltering, origSeg.deleted) + vecIndex, err := segment.InterpretVectorIndex(field, origSeg.deleted) if err != nil { errorsM.Lock() errors = append(errors, err) @@ -109,7 +106,7 @@ func (o *OptimizeVR) Finish() error { // kNN search. if vr.eligibleSelector != nil { pl, err = vecIndex.SearchWithFilter(vr.vector, vr.k, - vr.eligibleSelector.SegmentEligibleDocs(index), vr.searchParams) + vr.eligibleSelector.SegmentEligibleDocuments(index), vr.searchParams) } else { pl, err = vecIndex.Search(vr.vector, vr.k, vr.searchParams) } @@ -163,9 +160,6 @@ func (s *IndexSnapshotVectorReader) VectorOptimize(ctx context.Context, return octx, nil } o.ctx = ctx - if !o.requiresFiltering { - o.requiresFiltering = s.eligibleSelector != nil - } if o.snapshot != s.snapshot { o.invokeSearcherEndCallback() diff --git a/index/scorch/segment_plugin.go b/index/scorch/segment_plugin.go index 790a8008a..c44f9cf7b 100644 --- a/index/scorch/segment_plugin.go +++ b/index/scorch/segment_plugin.go @@ -28,6 +28,7 @@ import ( zapv14 "github.com/blevesearch/zapx/v14" zapv15 "github.com/blevesearch/zapx/v15" zapv16 "github.com/blevesearch/zapx/v16" + zapv17 "github.com/blevesearch/zapx/v17" ) // SegmentPlugin represents the essential functions required by a package to plug in @@ -73,7 +74,8 @@ var defaultSegmentPlugin SegmentPlugin func init() { ResetSegmentPlugins() - RegisterSegmentPlugin(&zapv16.ZapPlugin{}, true) + RegisterSegmentPlugin(&zapv17.ZapPlugin{}, true) + RegisterSegmentPlugin(&zapv16.ZapPlugin{}, false) RegisterSegmentPlugin(&zapv15.ZapPlugin{}, false) RegisterSegmentPlugin(&zapv14.ZapPlugin{}, false) RegisterSegmentPlugin(&zapv13.ZapPlugin{}, false) diff --git a/index/scorch/snapshot_index.go b/index/scorch/snapshot_index.go index 3f2a330c5..e6bdaf8d8 100644 --- a/index/scorch/snapshot_index.go +++ b/index/scorch/snapshot_index.go @@ -700,6 +700,8 @@ func (is *IndexSnapshot) TermFieldReader(ctx context.Context, term []byte, field rv.incrementBytesRead(bytesRead - prevBytesReadItr) } } + // ONLY update the bytes read value beyond this point for this TFR if scoring is enabled + rv.updateBytesRead = rv.includeFreq || rv.includeNorm || rv.includeTermVectors atomic.AddUint64(&is.parent.stats.TotTermSearchersStarted, uint64(1)) return rv, nil } diff --git a/index/scorch/snapshot_index_tfr.go b/index/scorch/snapshot_index_tfr.go index cd4d82dce..8804a6cb5 100644 --- a/index/scorch/snapshot_index_tfr.go +++ b/index/scorch/snapshot_index_tfr.go @@ -51,6 +51,10 @@ type IndexSnapshotTermFieldReader struct { bytesRead uint64 ctx context.Context unadorned bool + // flag to indicate whether to increment our bytesRead + // value after creation of the TFR while iterating our postings + // lists + updateBytesRead bool } func (i *IndexSnapshotTermFieldReader) incrementBytesRead(val uint64) { @@ -83,10 +87,15 @@ func (i *IndexSnapshotTermFieldReader) Next(preAlloced *index.TermFieldDoc) (*in if rv == nil { rv = &index.TermFieldDoc{} } + var prevBytesRead uint64 // find the next hit for i.segmentOffset < len(i.iterators) { - prevBytesRead := i.iterators[i.segmentOffset].BytesRead() - next, err := i.iterators[i.segmentOffset].Next() + // get our current postings iterator + curItr := i.iterators[i.segmentOffset] + if i.updateBytesRead { + prevBytesRead = curItr.BytesRead() + } + next, err := curItr.Next() if err != nil { return nil, err } @@ -99,13 +108,15 @@ func (i *IndexSnapshotTermFieldReader) Next(preAlloced *index.TermFieldDoc) (*in i.currID = rv.ID i.currPosting = next - // postingsIterators is maintain the bytesRead stat in a cumulative fashion. - // this is because there are chances of having a series of loadChunk calls, - // and they have to be added together before sending the bytesRead at this point - // upstream. - bytesRead := i.iterators[i.segmentOffset].BytesRead() - if bytesRead > prevBytesRead { - i.incrementBytesRead(bytesRead - prevBytesRead) + if i.updateBytesRead { + // postingsIterators maintains the bytesRead stat in a cumulative fashion. + // this is because there are chances of having a series of loadChunk calls, + // and they have to be added together before sending the bytesRead at this point + // upstream. + bytesRead := curItr.BytesRead() + if bytesRead > prevBytesRead { + i.incrementBytesRead(bytesRead - prevBytesRead) + } } return rv, nil } diff --git a/index/scorch/snapshot_index_vr.go b/index/scorch/snapshot_index_vr.go index bd57ad3e0..f96599b64 100644 --- a/index/scorch/snapshot_index_vr.go +++ b/index/scorch/snapshot_index_vr.go @@ -183,8 +183,7 @@ func (i *IndexSnapshot) CentroidCardinalities(field string, limit int, descendin for _, segment := range i.segment { if sv, ok := segment.segment.(segment_api.VectorSegment); ok { - vecIndex, err := sv.InterpretVectorIndex(field, - false /* does not require filtering */, segment.deleted) + vecIndex, err := sv.InterpretVectorIndex(field, segment.deleted) if err != nil { return nil, fmt.Errorf("failed to interpret vector index for field %s in segment: %v", field, err) } diff --git a/index/scorch/snapshot_vector_index.go b/index/scorch/snapshot_vector_index.go index 4fbb8441e..1d0c03b94 100644 --- a/index/scorch/snapshot_vector_index.go +++ b/index/scorch/snapshot_vector_index.go @@ -22,6 +22,7 @@ import ( "encoding/json" "fmt" + "github.com/bits-and-blooms/bitset" index "github.com/blevesearch/bleve_index_api" segment_api "github.com/blevesearch/scorch_segment_api/v2" ) @@ -45,17 +46,82 @@ func (is *IndexSnapshot) VectorReader(ctx context.Context, vector []float32, return rv, nil } +// eligibleDocumentList represents the list of eligible documents within a segment. +type eligibleDocumentList struct { + bs *bitset.BitSet +} + +// Iterator returns an iterator for the eligible document IDs. +func (edl *eligibleDocumentList) Iterator() index.EligibleDocumentIterator { + if edl.bs == nil { + // no eligible documents + return emptyEligibleIterator + } + // return the iterator + return &eligibleDocumentIterator{ + bs: edl.bs, + } +} + +// Count returns the number of eligible document IDs. +func (edl *eligibleDocumentList) Count() uint64 { + if edl.bs == nil { + return 0 + } + return uint64(edl.bs.Count()) +} + +// emptyEligibleDocumentList is a reusable empty eligible document list. +var emptyEligibleDocumentList = &eligibleDocumentList{} + +// eligibleDocumentIterator iterates over eligible document IDs within a segment. +type eligibleDocumentIterator struct { + bs *bitset.BitSet + current uint +} + +// Next returns the next eligible document ID and whether it exists. +func (it *eligibleDocumentIterator) Next() (id uint64, ok bool) { + next, found := it.bs.NextSet(it.current) + if !found { + return 0, false + } + it.current = next + 1 + return uint64(next), true +} + +// emptyEligibleIterator is a reusable empty eligible document iterator. +var emptyEligibleIterator = &emptyEligibleDocumentIterator{} + +// emptyEligibleDocumentIterator is an iterator that always returns no documents. +type emptyEligibleDocumentIterator struct{} + +// Next always returns false for empty iterator. +func (it *emptyEligibleDocumentIterator) Next() (id uint64, ok bool) { + return 0, false +} + // eligibleDocumentSelector is used to filter out documents that are eligible for // the KNN search from a pre-filter query. type eligibleDocumentSelector struct { - // segment ID -> segment local doc nums - eligibleDocNums map[int][]uint64 + // segment ID -> segment local doc nums in a bitset + eligibleDocNums []*bitset.BitSet is *IndexSnapshot } -// SegmentEligibleDocs returns the list of eligible local doc numbers for the given segment. -func (eds *eligibleDocumentSelector) SegmentEligibleDocs(segmentID int) []uint64 { - return eds.eligibleDocNums[segmentID] +// SegmentEligibleDocuments returns an EligibleDocumentList for the specified segment ID. +func (eds *eligibleDocumentSelector) SegmentEligibleDocuments(segmentID int) index.EligibleDocumentList { + if eds.eligibleDocNums == nil || segmentID < 0 || segmentID >= len(eds.eligibleDocNums) { + return emptyEligibleDocumentList + } + bs := eds.eligibleDocNums[segmentID] + if bs == nil { + // no eligible documents for this segment + return emptyEligibleDocumentList + } + return &eligibleDocumentList{ + bs: bs, + } } // AddEligibleDocumentMatch adds a document match to the list of eligible documents. @@ -68,14 +134,19 @@ func (eds *eligibleDocumentSelector) AddEligibleDocumentMatch(id index.IndexInte if err != nil { return err } + // allocate a bitset for this segment if needed + if eds.eligibleDocNums[segIdx] == nil { + // the size of the bitset is the full size of the segment (which is the max local doc num + 1) + eds.eligibleDocNums[segIdx] = bitset.New(uint(eds.is.segment[segIdx].FullSize())) + } // Add the local doc number to the list of eligible doc numbers for this segment. - eds.eligibleDocNums[segIdx] = append(eds.eligibleDocNums[segIdx], docNum) + eds.eligibleDocNums[segIdx].Set(uint(docNum)) return nil } func (is *IndexSnapshot) NewEligibleDocumentSelector() index.EligibleDocumentSelector { return &eligibleDocumentSelector{ - eligibleDocNums: map[int][]uint64{}, + eligibleDocNums: make([]*bitset.BitSet, len(is.segment)), is: is, } } diff --git a/index/scorch/unadorned.go b/index/scorch/unadorned.go index 18ce1c582..a37fb37ff 100644 --- a/index/scorch/unadorned.go +++ b/index/scorch/unadorned.go @@ -38,6 +38,7 @@ func init() { type unadornedPostingsIteratorBitmap struct { actual roaring.IntPeekable actualBM *roaring.Bitmap + next UnadornedPosting // reused across Next() calls } func (i *unadornedPostingsIteratorBitmap) Next() (segment.Posting, error) { @@ -53,7 +54,10 @@ func (i *unadornedPostingsIteratorBitmap) nextAtOrAfter(atOrAfter uint64) (segme if !exists { return nil, nil } - return UnadornedPosting(docNum), nil + i.next = UnadornedPosting{} // clear the struct + rv := &i.next + rv.docNum = docNum + return rv, nil } func (i *unadornedPostingsIteratorBitmap) nextDocNumAtOrAfter(atOrAfter uint64) (uint64, bool) { @@ -112,8 +116,9 @@ func newUnadornedPostingsIteratorFromBitmap(bm *roaring.Bitmap) segment.Postings const docNum1HitFinished = math.MaxUint64 type unadornedPostingsIterator1Hit struct { - docNumOrig uint64 // original 1-hit docNum used to create this iterator - docNum uint64 // current docNum + docNumOrig uint64 // original 1-hit docNum used to create this iterator + docNum uint64 // current docNum + next UnadornedPosting // reused across Next() calls } func (i *unadornedPostingsIterator1Hit) Next() (segment.Posting, error) { @@ -129,7 +134,10 @@ func (i *unadornedPostingsIterator1Hit) nextAtOrAfter(atOrAfter uint64) (segment if !exists { return nil, nil } - return UnadornedPosting(docNum), nil + i.next = UnadornedPosting{} // clear the struct + rv := &i.next + rv.docNum = docNum + return rv, nil } func (i *unadornedPostingsIterator1Hit) nextDocNumAtOrAfter(atOrAfter uint64) (uint64, bool) { @@ -176,24 +184,26 @@ type ResetablePostingsIterator interface { ResetIterator() } -type UnadornedPosting uint64 +type UnadornedPosting struct { + docNum uint64 +} -func (p UnadornedPosting) Number() uint64 { - return uint64(p) +func (p *UnadornedPosting) Number() uint64 { + return p.docNum } -func (p UnadornedPosting) Frequency() uint64 { +func (p *UnadornedPosting) Frequency() uint64 { return 0 } -func (p UnadornedPosting) Norm() float64 { +func (p *UnadornedPosting) Norm() float64 { return 0 } -func (p UnadornedPosting) Locations() []segment.Location { +func (p *UnadornedPosting) Locations() []segment.Location { return nil } -func (p UnadornedPosting) Size() int { +func (p *UnadornedPosting) Size() int { return reflectStaticSizeUnadornedPosting } diff --git a/index_test.go b/index_test.go index 7ed27ff86..2022b7387 100644 --- a/index_test.go +++ b/index_test.go @@ -612,9 +612,9 @@ func TestBytesRead(t *testing.T) { stats, _ := idx.StatsMap()["index"].(map[string]interface{}) prevBytesRead, _ := stats["num_bytes_read_at_query_time"].(uint64) - expectedBytesRead := uint64(22049) + expectedBytesRead := uint64(21164) if supportForVectorSearch { - expectedBytesRead = 22459 + expectedBytesRead = 21574 } if prevBytesRead != expectedBytesRead && res.Cost == prevBytesRead { @@ -770,9 +770,9 @@ func TestBytesReadStored(t *testing.T) { stats, _ := idx.StatsMap()["index"].(map[string]interface{}) bytesRead, _ := stats["num_bytes_read_at_query_time"].(uint64) - expectedBytesRead := uint64(11911) + expectedBytesRead := uint64(11025) if supportForVectorSearch { - expectedBytesRead = 12321 + expectedBytesRead = 11435 } if bytesRead != expectedBytesRead && bytesRead == res.Cost { @@ -847,9 +847,9 @@ func TestBytesReadStored(t *testing.T) { stats, _ = idx1.StatsMap()["index"].(map[string]interface{}) bytesRead, _ = stats["num_bytes_read_at_query_time"].(uint64) - expectedBytesRead = uint64(4097) + expectedBytesRead = uint64(3212) if supportForVectorSearch { - expectedBytesRead = 4507 + expectedBytesRead = 3622 } if bytesRead != expectedBytesRead && bytesRead == res.Cost { diff --git a/search/query/query_string_parser.go b/search/query/query_string_parser.go index 3fb7731b8..8aebedd41 100644 --- a/search/query/query_string_parser.go +++ b/search/query/query_string_parser.go @@ -41,7 +41,7 @@ func parseQuerySyntax(query string) (rq Query, err error) { doParse(lex) if len(lex.errs) > 0 { - return nil, fmt.Errorf(strings.Join(lex.errs, "\n")) + return nil, fmt.Errorf("%s", strings.Join(lex.errs, "\n")) } return lex.query, nil }