diff --git a/index/upsidedown/field_dict.go b/index/upsidedown/field_dict.go index ab906b0d..20d4eb34 100644 --- a/index/upsidedown/field_dict.go +++ b/index/upsidedown/field_dict.go @@ -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 } diff --git a/index/upsidedown/row.go b/index/upsidedown/row.go index 8d06b319..5d9c80ee 100644 --- a/index/upsidedown/row.go +++ b/index/upsidedown/row.go @@ -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 }