0
0
Fork 0

optimize upside_down reader Next() with TermFieldDoc reuse

This optimization changes the index.TermFieldReader.Next() interface
API, adding an optional, pre-allocated *TermFieldDoc parameter, which
can help prevent garbage creation.
This commit is contained in:
Steve Yen 2016-07-20 16:53:30 -07:00
parent 988ca62182
commit 39d3e2f028
5 changed files with 25 additions and 16 deletions

View File

@ -111,8 +111,9 @@ type TermFieldDoc struct {
// lexicographic order over their identifiers.
type TermFieldReader interface {
// Next returns the next document containing the term in this field, or nil
// when it reaches the end of the enumeration.
Next() (*TermFieldDoc, error)
// when it reaches the end of the enumeration. The preAlloced TermFieldDoc
// is optional, and when non-nil, will be used instead of allocating memory.
Next(preAlloced *TermFieldDoc) (*TermFieldDoc, error)
// Advance resets the enumeration at specified document or its immediate
// follower.
@ -199,3 +200,8 @@ func (b *Batch) Reset() {
b.IndexOps = make(map[string]*document.Document)
b.InternalOps = make(map[string][]byte)
}
func (tfd *TermFieldDoc) Reset() *TermFieldDoc {
*tfd = TermFieldDoc{}
return tfd
}

View File

@ -62,7 +62,7 @@ func (r *UpsideDownCouchTermFieldReader) Count() uint64 {
return r.count
}
func (r *UpsideDownCouchTermFieldReader) Next() (*index.TermFieldDoc, error) {
func (r *UpsideDownCouchTermFieldReader) Next(preAlloced *index.TermFieldDoc) (*index.TermFieldDoc, error) {
if r.iterator != nil {
key, val, valid := r.iterator.Current()
if valid {
@ -75,14 +75,16 @@ func (r *UpsideDownCouchTermFieldReader) Next() (*index.TermFieldDoc, error) {
if err != nil {
return nil, err
}
rv := index.TermFieldDoc{
ID: string(tfr.doc),
Freq: tfr.freq,
Norm: float64(tfr.norm),
Vectors: r.indexReader.index.termFieldVectorsFromTermVectors(tfr.vectors),
rv := preAlloced
if rv == nil {
rv = &index.TermFieldDoc{}
}
rv.ID = string(tfr.doc)
rv.Freq = tfr.freq
rv.Norm = float64(tfr.norm)
rv.Vectors = r.indexReader.index.termFieldVectorsFromTermVectors(tfr.vectors)
r.iterator.Next()
return &rv, nil
return rv, nil
}
}
return nil, nil

View File

@ -98,9 +98,9 @@ func TestIndexReader(t *testing.T) {
var match *index.TermFieldDoc
var actualCount uint64
match, err = reader.Next()
match, err = reader.Next(nil)
for err == nil && match != nil {
match, err = reader.Next()
match, err = reader.Next(nil)
if err != nil {
t.Errorf("unexpected error reading next")
}
@ -127,7 +127,7 @@ func TestIndexReader(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
match, err = tfr.Next()
match, err = tfr.Next(nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -176,7 +176,7 @@ func TestIndexReader(t *testing.T) {
if count != 0 {
t.Errorf("expected count 0 for reader of non-existant field")
}
match, err = reader.Next()
match, err = reader.Next(nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}

View File

@ -1124,12 +1124,12 @@ func TestIndexTermReaderCompositeFields(t *testing.T) {
t.Error(err)
}
tfd, err := termFieldReader.Next()
tfd, err := termFieldReader.Next(nil)
for tfd != nil && err == nil {
if tfd.ID != "1" {
t.Errorf("expected to find document id 1")
}
tfd, err = termFieldReader.Next()
tfd, err = termFieldReader.Next(nil)
}
if err != nil {
t.Error(err)

View File

@ -22,6 +22,7 @@ type TermSearcher struct {
explain bool
reader index.TermFieldReader
scorer *scorers.TermQueryScorer
tfd index.TermFieldDoc
}
func NewTermSearcher(indexReader index.IndexReader, term string, field string, boost float64, explain bool) (*TermSearcher, error) {
@ -53,7 +54,7 @@ func (s *TermSearcher) SetQueryNorm(qnorm float64) {
}
func (s *TermSearcher) Next(preAllocated *search.DocumentMatch) (*search.DocumentMatch, error) {
termMatch, err := s.reader.Next()
termMatch, err := s.reader.Next(s.tfd.Reset())
if err != nil {
return nil, err
}