0
0
Fork 0

scorch zap optimize when zero hits

Instead of allocating brand-new empty postingsList/Iterator instances,
reuse some empty singletons.
This commit is contained in:
Steve Yen 2018-03-27 13:57:46 -07:00
parent 6c6c1419b5
commit 596d990eb9
3 changed files with 21 additions and 2 deletions

View File

@ -39,6 +39,9 @@ func (d *Dictionary) PostingsList(term string, except *roaring.Bitmap) (segment.
func (d *Dictionary) postingsList(term []byte, except *roaring.Bitmap, rv *PostingsList) (*PostingsList, error) {
if d.fst == nil {
if rv == nil || rv == emptyPostingsList {
return emptyPostingsList, nil
}
return d.postingsListInit(rv, except), nil
}
@ -47,6 +50,9 @@ func (d *Dictionary) postingsList(term []byte, except *roaring.Bitmap, rv *Posti
return nil, fmt.Errorf("vellum err: %v", err)
}
if !exists {
if rv == nil || rv == emptyPostingsList {
return emptyPostingsList, nil
}
return d.postingsListInit(rv, except), nil
}
@ -65,7 +71,7 @@ func (d *Dictionary) postingsListFromOffset(postingsOffset uint64, except *roari
}
func (d *Dictionary) postingsListInit(rv *PostingsList, except *roaring.Bitmap) *PostingsList {
if rv == nil {
if rv == nil || rv == emptyPostingsList {
rv = &PostingsList{}
} else {
postings := rv.postings

View File

@ -109,6 +109,9 @@ type PostingsList struct {
normBits1Hit uint64
}
// represents an immutable, empty postings list
var emptyPostingsList = &PostingsList{}
func (p *PostingsList) Size() int {
sizeInBytes := reflectStaticSizePostingsList + size.SizeOfPtr
@ -132,6 +135,10 @@ func (p *PostingsList) OrInto(receiver *roaring.Bitmap) {
// Iterator returns an iterator for this postings list
func (p *PostingsList) Iterator(includeFreq, includeNorm, includeLocs bool) segment.PostingsIterator {
if p.normBits1Hit == 0 && p.postings == nil {
return emptyPostingsIterator
}
return p.iterator(includeFreq, includeNorm, includeLocs, nil)
}
@ -341,6 +348,8 @@ type PostingsIterator struct {
includeLocs bool
}
var emptyPostingsIterator = &PostingsIterator{}
func (i *PostingsIterator) Size() int {
sizeInBytes := reflectStaticSizePostingsIterator + size.SizeOfPtr +
len(i.currChunkFreqNorm) +
@ -589,6 +598,10 @@ func (i *PostingsIterator) nextBytes() (
}
func (i *PostingsIterator) Advance(docNumber uint64) (segment.Posting, error) {
if i.postings == nil {
return nil, nil
}
// check if we are already there
if i.next.Number() == docNumber {
return &i.next, nil

View File

@ -373,7 +373,7 @@ func (s *SegmentBase) DocNumbers(ids []string) (*roaring.Bitmap, error) {
return nil, err
}
var postingsList *PostingsList
postingsList := emptyPostingsList
for _, id := range ids {
postingsList, err = idDict.postingsList([]byte(id), nil, postingsList)
if err != nil {