0
0

Merge pull request #466 from steveyen/optimize-fieldDict-reader-with-prealloc

Optimize upside-down's field dict reader with preallocated objects
This commit is contained in:
Marty Schoch 2016-10-13 14:09:54 +02:00 committed by GitHub
commit 77b79a2684
2 changed files with 26 additions and 27 deletions

View File

@ -24,6 +24,8 @@ import (
type UpsideDownCouchFieldDict struct {
indexReader *IndexReader
iterator store.KVIterator
dictRow *DictionaryRow
dictEntry *index.DictEntry
field uint16
}
@ -42,6 +44,8 @@ func newUpsideDownCouchFieldDict(indexReader *IndexReader, field uint16, startTe
return &UpsideDownCouchFieldDict{
indexReader: indexReader,
iterator: it,
dictRow: &DictionaryRow{}, // Pre-alloced, reused row.
dictEntry: &index.DictEntry{}, // Pre-alloced, reused entry.
field: field,
}, nil
@ -53,17 +57,19 @@ func (r *UpsideDownCouchFieldDict) Next() (*index.DictEntry, error) {
return nil, nil
}
currRow, err := NewDictionaryRowKV(key, val)
err := r.dictRow.parseDictionaryK(key)
if err != nil {
return nil, fmt.Errorf("unexpected error parsing dictionary row kv: %v", err)
return nil, fmt.Errorf("unexpected error parsing dictionary row key: %v", err)
}
rv := index.DictEntry{
Term: string(currRow.term),
Count: currRow.count,
err = r.dictRow.parseDictionaryV(val)
if err != nil {
return nil, fmt.Errorf("unexpected error parsing dictionary row val: %v", err)
}
r.dictEntry.Term = string(r.dictRow.term)
r.dictEntry.Count = r.dictRow.count
// advance the iterator to the next term
r.iterator.Next()
return &rv, nil
return r.dictEntry, nil
}

View File

@ -242,9 +242,9 @@ func NewFieldRowKV(key, value []byte) (*FieldRow, error) {
const DictionaryRowMaxValueSize = binary.MaxVarintLen64
type DictionaryRow struct {
field uint16
term []byte
count uint64
field uint16
}
func (dr *DictionaryRow) Key() []byte {
@ -306,36 +306,29 @@ func NewDictionaryRowKV(key, value []byte) (*DictionaryRow, error) {
}
func NewDictionaryRowK(key []byte) (*DictionaryRow, error) {
rv := DictionaryRow{}
buf := bytes.NewBuffer(key)
_, err := buf.ReadByte() // type
rv := &DictionaryRow{}
err := rv.parseDictionaryK(key)
if err != nil {
return nil, err
}
return rv, nil
}
err = binary.Read(buf, binary.LittleEndian, &rv.field)
if err != nil {
return nil, err
func (dr *DictionaryRow) parseDictionaryK(key []byte) error {
dr.field = binary.LittleEndian.Uint16(key[1:3])
if dr.term != nil {
dr.term = dr.term[:0]
}
rv.term, err = buf.ReadBytes(ByteSeparator)
// there is no separator expected here, should get EOF
if err != io.EOF {
return nil, err
}
return &rv, nil
dr.term = append(dr.term, key[3:]...)
return nil
}
func (dr *DictionaryRow) parseDictionaryV(value []byte) error {
buf := bytes.NewBuffer(value)
count, err := binary.ReadUvarint(buf)
if err != nil {
return err
count, nread := binary.Uvarint(value)
if nread <= 0 {
return fmt.Errorf("DictionaryRow parse Uvarint error, nread: %d", nread)
}
dr.count = count
return nil
}