~ubuntu-branches/debian/sid/golang-github-blevesearch-bleve/sid

« back to all changes in this revision

Viewing changes to index/upsidedown/row.go

  • Committer: Package Import Robot
  • Author(s): Michael Lustfield
  • Date: 2017-03-30 16:06:03 UTC
  • Revision ID: package-import@ubuntu.com-20170330160603-0oogmb960l7918jx
Tags: upstream-0.5.0+git20170324.202.4702785f
ImportĀ upstreamĀ versionĀ 0.5.0+git20170324.202.4702785f

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//  Copyright (c) 2014 Couchbase, Inc.
 
2
//
 
3
// Licensed under the Apache License, Version 2.0 (the "License");
 
4
// you may not use this file except in compliance with the License.
 
5
// You may obtain a copy of the License at
 
6
//
 
7
//              http://www.apache.org/licenses/LICENSE-2.0
 
8
//
 
9
// Unless required by applicable law or agreed to in writing, software
 
10
// distributed under the License is distributed on an "AS IS" BASIS,
 
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
12
// See the License for the specific language governing permissions and
 
13
// limitations under the License.
 
14
 
 
15
package upsidedown
 
16
 
 
17
import (
 
18
        "bytes"
 
19
        "encoding/binary"
 
20
        "fmt"
 
21
        "io"
 
22
        "math"
 
23
 
 
24
        "github.com/golang/protobuf/proto"
 
25
)
 
26
 
 
27
const ByteSeparator byte = 0xff
 
28
 
 
29
type UpsideDownCouchRowStream chan UpsideDownCouchRow
 
30
 
 
31
type UpsideDownCouchRow interface {
 
32
        KeySize() int
 
33
        KeyTo([]byte) (int, error)
 
34
        Key() []byte
 
35
        Value() []byte
 
36
        ValueSize() int
 
37
        ValueTo([]byte) (int, error)
 
38
}
 
39
 
 
40
func ParseFromKeyValue(key, value []byte) (UpsideDownCouchRow, error) {
 
41
        if len(key) > 0 {
 
42
                switch key[0] {
 
43
                case 'v':
 
44
                        return NewVersionRowKV(key, value)
 
45
                case 'f':
 
46
                        return NewFieldRowKV(key, value)
 
47
                case 'd':
 
48
                        return NewDictionaryRowKV(key, value)
 
49
                case 't':
 
50
                        return NewTermFrequencyRowKV(key, value)
 
51
                case 'b':
 
52
                        return NewBackIndexRowKV(key, value)
 
53
                case 's':
 
54
                        return NewStoredRowKV(key, value)
 
55
                case 'i':
 
56
                        return NewInternalRowKV(key, value)
 
57
                }
 
58
                return nil, fmt.Errorf("Unknown field type '%s'", string(key[0]))
 
59
        }
 
60
        return nil, fmt.Errorf("Invalid empty key")
 
61
}
 
62
 
 
63
// VERSION
 
64
 
 
65
type VersionRow struct {
 
66
        version uint8
 
67
}
 
68
 
 
69
func (v *VersionRow) Key() []byte {
 
70
        return []byte{'v'}
 
71
}
 
72
 
 
73
func (v *VersionRow) KeySize() int {
 
74
        return 1
 
75
}
 
76
 
 
77
func (v *VersionRow) KeyTo(buf []byte) (int, error) {
 
78
        buf[0] = 'v'
 
79
        return 1, nil
 
80
}
 
81
 
 
82
func (v *VersionRow) Value() []byte {
 
83
        return []byte{byte(v.version)}
 
84
}
 
85
 
 
86
func (v *VersionRow) ValueSize() int {
 
87
        return 1
 
88
}
 
89
 
 
90
func (v *VersionRow) ValueTo(buf []byte) (int, error) {
 
91
        buf[0] = v.version
 
92
        return 1, nil
 
93
}
 
94
 
 
95
func (v *VersionRow) String() string {
 
96
        return fmt.Sprintf("Version: %d", v.version)
 
97
}
 
98
 
 
99
func NewVersionRow(version uint8) *VersionRow {
 
100
        return &VersionRow{
 
101
                version: version,
 
102
        }
 
103
}
 
104
 
 
105
func NewVersionRowKV(key, value []byte) (*VersionRow, error) {
 
106
        rv := VersionRow{}
 
107
        buf := bytes.NewBuffer(value)
 
108
        err := binary.Read(buf, binary.LittleEndian, &rv.version)
 
109
        if err != nil {
 
110
                return nil, err
 
111
        }
 
112
        return &rv, nil
 
113
}
 
114
 
 
115
// INTERNAL STORAGE
 
116
 
 
117
type InternalRow struct {
 
118
        key []byte
 
119
        val []byte
 
120
}
 
121
 
 
122
func (i *InternalRow) Key() []byte {
 
123
        buf := make([]byte, i.KeySize())
 
124
        size, _ := i.KeyTo(buf)
 
125
        return buf[:size]
 
126
}
 
127
 
 
128
func (i *InternalRow) KeySize() int {
 
129
        return len(i.key) + 1
 
130
}
 
131
 
 
132
func (i *InternalRow) KeyTo(buf []byte) (int, error) {
 
133
        buf[0] = 'i'
 
134
        actual := copy(buf[1:], i.key)
 
135
        return 1 + actual, nil
 
136
}
 
137
 
 
138
func (i *InternalRow) Value() []byte {
 
139
        return i.val
 
140
}
 
141
 
 
142
func (i *InternalRow) ValueSize() int {
 
143
        return len(i.val)
 
144
}
 
145
 
 
146
func (i *InternalRow) ValueTo(buf []byte) (int, error) {
 
147
        actual := copy(buf, i.val)
 
148
        return actual, nil
 
149
}
 
150
 
 
151
func (i *InternalRow) String() string {
 
152
        return fmt.Sprintf("InternalStore - Key: %s (% x) Val: %s (% x)", i.key, i.key, i.val, i.val)
 
153
}
 
154
 
 
155
func NewInternalRow(key, val []byte) *InternalRow {
 
156
        return &InternalRow{
 
157
                key: key,
 
158
                val: val,
 
159
        }
 
160
}
 
161
 
 
162
func NewInternalRowKV(key, value []byte) (*InternalRow, error) {
 
163
        rv := InternalRow{}
 
164
        rv.key = key[1:]
 
165
        rv.val = value
 
166
        return &rv, nil
 
167
}
 
168
 
 
169
// FIELD definition
 
170
 
 
171
type FieldRow struct {
 
172
        index uint16
 
173
        name  string
 
174
}
 
175
 
 
176
func (f *FieldRow) Key() []byte {
 
177
        buf := make([]byte, f.KeySize())
 
178
        size, _ := f.KeyTo(buf)
 
179
        return buf[:size]
 
180
}
 
181
 
 
182
func (f *FieldRow) KeySize() int {
 
183
        return 3
 
184
}
 
185
 
 
186
func (f *FieldRow) KeyTo(buf []byte) (int, error) {
 
187
        buf[0] = 'f'
 
188
        binary.LittleEndian.PutUint16(buf[1:3], f.index)
 
189
        return 3, nil
 
190
}
 
191
 
 
192
func (f *FieldRow) Value() []byte {
 
193
        return append([]byte(f.name), ByteSeparator)
 
194
}
 
195
 
 
196
func (f *FieldRow) ValueSize() int {
 
197
        return len(f.name) + 1
 
198
}
 
199
 
 
200
func (f *FieldRow) ValueTo(buf []byte) (int, error) {
 
201
        size := copy(buf, f.name)
 
202
        buf[size] = ByteSeparator
 
203
        return size + 1, nil
 
204
}
 
205
 
 
206
func (f *FieldRow) String() string {
 
207
        return fmt.Sprintf("Field: %d Name: %s", f.index, f.name)
 
208
}
 
209
 
 
210
func NewFieldRow(index uint16, name string) *FieldRow {
 
211
        return &FieldRow{
 
212
                index: index,
 
213
                name:  name,
 
214
        }
 
215
}
 
216
 
 
217
func NewFieldRowKV(key, value []byte) (*FieldRow, error) {
 
218
        rv := FieldRow{}
 
219
 
 
220
        buf := bytes.NewBuffer(key)
 
221
        _, err := buf.ReadByte() // type
 
222
        if err != nil {
 
223
                return nil, err
 
224
        }
 
225
        err = binary.Read(buf, binary.LittleEndian, &rv.index)
 
226
        if err != nil {
 
227
                return nil, err
 
228
        }
 
229
 
 
230
        buf = bytes.NewBuffer(value)
 
231
        rv.name, err = buf.ReadString(ByteSeparator)
 
232
        if err != nil {
 
233
                return nil, err
 
234
        }
 
235
        rv.name = rv.name[:len(rv.name)-1] // trim off separator byte
 
236
 
 
237
        return &rv, nil
 
238
}
 
239
 
 
240
// DICTIONARY
 
241
 
 
242
const DictionaryRowMaxValueSize = binary.MaxVarintLen64
 
243
 
 
244
type DictionaryRow struct {
 
245
        term  []byte
 
246
        count uint64
 
247
        field uint16
 
248
}
 
249
 
 
250
func (dr *DictionaryRow) Key() []byte {
 
251
        buf := make([]byte, dr.KeySize())
 
252
        size, _ := dr.KeyTo(buf)
 
253
        return buf[:size]
 
254
}
 
255
 
 
256
func (dr *DictionaryRow) KeySize() int {
 
257
        return dictionaryRowKeySize(dr.term)
 
258
}
 
259
 
 
260
func dictionaryRowKeySize(term []byte) int {
 
261
        return len(term) + 3
 
262
}
 
263
 
 
264
func (dr *DictionaryRow) KeyTo(buf []byte) (int, error) {
 
265
        return dictionaryRowKeyTo(buf, dr.field, dr.term), nil
 
266
}
 
267
 
 
268
func dictionaryRowKeyTo(buf []byte, field uint16, term []byte) int {
 
269
        buf[0] = 'd'
 
270
        binary.LittleEndian.PutUint16(buf[1:3], field)
 
271
        size := copy(buf[3:], term)
 
272
        return size + 3
 
273
}
 
274
 
 
275
func (dr *DictionaryRow) Value() []byte {
 
276
        buf := make([]byte, dr.ValueSize())
 
277
        size, _ := dr.ValueTo(buf)
 
278
        return buf[:size]
 
279
}
 
280
 
 
281
func (dr *DictionaryRow) ValueSize() int {
 
282
        return DictionaryRowMaxValueSize
 
283
}
 
284
 
 
285
func (dr *DictionaryRow) ValueTo(buf []byte) (int, error) {
 
286
        used := binary.PutUvarint(buf, dr.count)
 
287
        return used, nil
 
288
}
 
289
 
 
290
func (dr *DictionaryRow) String() string {
 
291
        return fmt.Sprintf("Dictionary Term: `%s` Field: %d Count: %d ", string(dr.term), dr.field, dr.count)
 
292
}
 
293
 
 
294
func NewDictionaryRow(term []byte, field uint16, count uint64) *DictionaryRow {
 
295
        return &DictionaryRow{
 
296
                term:  term,
 
297
                field: field,
 
298
                count: count,
 
299
        }
 
300
}
 
301
 
 
302
func NewDictionaryRowKV(key, value []byte) (*DictionaryRow, error) {
 
303
        rv, err := NewDictionaryRowK(key)
 
304
        if err != nil {
 
305
                return nil, err
 
306
        }
 
307
 
 
308
        err = rv.parseDictionaryV(value)
 
309
        if err != nil {
 
310
                return nil, err
 
311
        }
 
312
        return rv, nil
 
313
 
 
314
}
 
315
 
 
316
func NewDictionaryRowK(key []byte) (*DictionaryRow, error) {
 
317
        rv := &DictionaryRow{}
 
318
        err := rv.parseDictionaryK(key)
 
319
        if err != nil {
 
320
                return nil, err
 
321
        }
 
322
        return rv, nil
 
323
}
 
324
 
 
325
func (dr *DictionaryRow) parseDictionaryK(key []byte) error {
 
326
        dr.field = binary.LittleEndian.Uint16(key[1:3])
 
327
        if dr.term != nil {
 
328
                dr.term = dr.term[:0]
 
329
        }
 
330
        dr.term = append(dr.term, key[3:]...)
 
331
        return nil
 
332
}
 
333
 
 
334
func (dr *DictionaryRow) parseDictionaryV(value []byte) error {
 
335
        count, err := dictionaryRowParseV(value)
 
336
        if err != nil {
 
337
                return err
 
338
        }
 
339
        dr.count = count
 
340
        return nil
 
341
}
 
342
 
 
343
func dictionaryRowParseV(value []byte) (uint64, error) {
 
344
        count, nread := binary.Uvarint(value)
 
345
        if nread <= 0 {
 
346
                return 0, fmt.Errorf("DictionaryRow parse Uvarint error, nread: %d", nread)
 
347
        }
 
348
        return count, nil
 
349
}
 
350
 
 
351
// TERM FIELD FREQUENCY
 
352
 
 
353
type TermVector struct {
 
354
        field          uint16
 
355
        arrayPositions []uint64
 
356
        pos            uint64
 
357
        start          uint64
 
358
        end            uint64
 
359
}
 
360
 
 
361
func (tv *TermVector) String() string {
 
362
        return fmt.Sprintf("Field: %d Pos: %d Start: %d End %d ArrayPositions: %#v", tv.field, tv.pos, tv.start, tv.end, tv.arrayPositions)
 
363
}
 
364
 
 
365
type TermFrequencyRow struct {
 
366
        term    []byte
 
367
        doc     []byte
 
368
        freq    uint64
 
369
        vectors []*TermVector
 
370
        norm    float32
 
371
        field   uint16
 
372
}
 
373
 
 
374
func (tfr *TermFrequencyRow) Term() []byte {
 
375
        return tfr.term
 
376
}
 
377
 
 
378
func (tfr *TermFrequencyRow) Freq() uint64 {
 
379
        return tfr.freq
 
380
}
 
381
 
 
382
func (tfr *TermFrequencyRow) ScanPrefixForField() []byte {
 
383
        buf := make([]byte, 3)
 
384
        buf[0] = 't'
 
385
        binary.LittleEndian.PutUint16(buf[1:3], tfr.field)
 
386
        return buf
 
387
}
 
388
 
 
389
func (tfr *TermFrequencyRow) ScanPrefixForFieldTermPrefix() []byte {
 
390
        buf := make([]byte, 3+len(tfr.term))
 
391
        buf[0] = 't'
 
392
        binary.LittleEndian.PutUint16(buf[1:3], tfr.field)
 
393
        copy(buf[3:], tfr.term)
 
394
        return buf
 
395
}
 
396
 
 
397
func (tfr *TermFrequencyRow) ScanPrefixForFieldTerm() []byte {
 
398
        buf := make([]byte, 3+len(tfr.term)+1)
 
399
        buf[0] = 't'
 
400
        binary.LittleEndian.PutUint16(buf[1:3], tfr.field)
 
401
        termLen := copy(buf[3:], tfr.term)
 
402
        buf[3+termLen] = ByteSeparator
 
403
        return buf
 
404
}
 
405
 
 
406
func (tfr *TermFrequencyRow) Key() []byte {
 
407
        buf := make([]byte, tfr.KeySize())
 
408
        size, _ := tfr.KeyTo(buf)
 
409
        return buf[:size]
 
410
}
 
411
 
 
412
func (tfr *TermFrequencyRow) KeySize() int {
 
413
        return termFrequencyRowKeySize(tfr.term, tfr.doc)
 
414
}
 
415
 
 
416
func termFrequencyRowKeySize(term, doc []byte) int {
 
417
        return 3 + len(term) + 1 + len(doc)
 
418
}
 
419
 
 
420
func (tfr *TermFrequencyRow) KeyTo(buf []byte) (int, error) {
 
421
        return termFrequencyRowKeyTo(buf, tfr.field, tfr.term, tfr.doc), nil
 
422
}
 
423
 
 
424
func termFrequencyRowKeyTo(buf []byte, field uint16, term, doc []byte) int {
 
425
        buf[0] = 't'
 
426
        binary.LittleEndian.PutUint16(buf[1:3], field)
 
427
        termLen := copy(buf[3:], term)
 
428
        buf[3+termLen] = ByteSeparator
 
429
        docLen := copy(buf[3+termLen+1:], doc)
 
430
        return 3 + termLen + 1 + docLen
 
431
}
 
432
 
 
433
func (tfr *TermFrequencyRow) KeyAppendTo(buf []byte) ([]byte, error) {
 
434
        keySize := tfr.KeySize()
 
435
        if cap(buf) < keySize {
 
436
                buf = make([]byte, keySize)
 
437
        }
 
438
        actualSize, err := tfr.KeyTo(buf[0:keySize])
 
439
        return buf[0:actualSize], err
 
440
}
 
441
 
 
442
func (tfr *TermFrequencyRow) DictionaryRowKey() []byte {
 
443
        dr := NewDictionaryRow(tfr.term, tfr.field, 0)
 
444
        return dr.Key()
 
445
}
 
446
 
 
447
func (tfr *TermFrequencyRow) DictionaryRowKeySize() int {
 
448
        dr := NewDictionaryRow(tfr.term, tfr.field, 0)
 
449
        return dr.KeySize()
 
450
}
 
451
 
 
452
func (tfr *TermFrequencyRow) DictionaryRowKeyTo(buf []byte) (int, error) {
 
453
        dr := NewDictionaryRow(tfr.term, tfr.field, 0)
 
454
        return dr.KeyTo(buf)
 
455
}
 
456
 
 
457
func (tfr *TermFrequencyRow) Value() []byte {
 
458
        buf := make([]byte, tfr.ValueSize())
 
459
        size, _ := tfr.ValueTo(buf)
 
460
        return buf[:size]
 
461
}
 
462
 
 
463
func (tfr *TermFrequencyRow) ValueSize() int {
 
464
        bufLen := binary.MaxVarintLen64 + binary.MaxVarintLen64
 
465
        for _, vector := range tfr.vectors {
 
466
                bufLen += (binary.MaxVarintLen64 * 4) + (1+len(vector.arrayPositions))*binary.MaxVarintLen64
 
467
        }
 
468
        return bufLen
 
469
}
 
470
 
 
471
func (tfr *TermFrequencyRow) ValueTo(buf []byte) (int, error) {
 
472
        used := binary.PutUvarint(buf[:binary.MaxVarintLen64], tfr.freq)
 
473
 
 
474
        normuint32 := math.Float32bits(tfr.norm)
 
475
        newbuf := buf[used : used+binary.MaxVarintLen64]
 
476
        used += binary.PutUvarint(newbuf, uint64(normuint32))
 
477
 
 
478
        for _, vector := range tfr.vectors {
 
479
                used += binary.PutUvarint(buf[used:used+binary.MaxVarintLen64], uint64(vector.field))
 
480
                used += binary.PutUvarint(buf[used:used+binary.MaxVarintLen64], vector.pos)
 
481
                used += binary.PutUvarint(buf[used:used+binary.MaxVarintLen64], vector.start)
 
482
                used += binary.PutUvarint(buf[used:used+binary.MaxVarintLen64], vector.end)
 
483
                used += binary.PutUvarint(buf[used:used+binary.MaxVarintLen64], uint64(len(vector.arrayPositions)))
 
484
                for _, arrayPosition := range vector.arrayPositions {
 
485
                        used += binary.PutUvarint(buf[used:used+binary.MaxVarintLen64], arrayPosition)
 
486
                }
 
487
        }
 
488
        return used, nil
 
489
}
 
490
 
 
491
func (tfr *TermFrequencyRow) String() string {
 
492
        return fmt.Sprintf("Term: `%s` Field: %d DocId: `%s` Frequency: %d Norm: %f Vectors: %v", string(tfr.term), tfr.field, string(tfr.doc), tfr.freq, tfr.norm, tfr.vectors)
 
493
}
 
494
 
 
495
func InitTermFrequencyRow(tfr *TermFrequencyRow, term []byte, field uint16, docID []byte, freq uint64, norm float32) *TermFrequencyRow {
 
496
        tfr.term = term
 
497
        tfr.field = field
 
498
        tfr.doc = docID
 
499
        tfr.freq = freq
 
500
        tfr.norm = norm
 
501
        return tfr
 
502
}
 
503
 
 
504
func NewTermFrequencyRow(term []byte, field uint16, docID []byte, freq uint64, norm float32) *TermFrequencyRow {
 
505
        return &TermFrequencyRow{
 
506
                term:  term,
 
507
                field: field,
 
508
                doc:   docID,
 
509
                freq:  freq,
 
510
                norm:  norm,
 
511
        }
 
512
}
 
513
 
 
514
func NewTermFrequencyRowWithTermVectors(term []byte, field uint16, docID []byte, freq uint64, norm float32, vectors []*TermVector) *TermFrequencyRow {
 
515
        return &TermFrequencyRow{
 
516
                term:    term,
 
517
                field:   field,
 
518
                doc:     docID,
 
519
                freq:    freq,
 
520
                norm:    norm,
 
521
                vectors: vectors,
 
522
        }
 
523
}
 
524
 
 
525
func NewTermFrequencyRowK(key []byte) (*TermFrequencyRow, error) {
 
526
        rv := &TermFrequencyRow{}
 
527
        err := rv.parseK(key)
 
528
        if err != nil {
 
529
                return nil, err
 
530
        }
 
531
        return rv, nil
 
532
}
 
533
 
 
534
func (tfr *TermFrequencyRow) parseK(key []byte) error {
 
535
        keyLen := len(key)
 
536
        if keyLen < 3 {
 
537
                return fmt.Errorf("invalid term frequency key, no valid field")
 
538
        }
 
539
        tfr.field = binary.LittleEndian.Uint16(key[1:3])
 
540
 
 
541
        termEndPos := bytes.IndexByte(key[3:], ByteSeparator)
 
542
        if termEndPos < 0 {
 
543
                return fmt.Errorf("invalid term frequency key, no byte separator terminating term")
 
544
        }
 
545
        tfr.term = key[3 : 3+termEndPos]
 
546
 
 
547
        docLen := keyLen - (3 + termEndPos + 1)
 
548
        if docLen < 1 {
 
549
                return fmt.Errorf("invalid term frequency key, empty docid")
 
550
        }
 
551
        tfr.doc = key[3+termEndPos+1:]
 
552
 
 
553
        return nil
 
554
}
 
555
 
 
556
func (tfr *TermFrequencyRow) parseKDoc(key []byte, term []byte) error {
 
557
        tfr.doc = key[3+len(term)+1:]
 
558
        if len(tfr.doc) <= 0 {
 
559
                return fmt.Errorf("invalid term frequency key, empty docid")
 
560
        }
 
561
 
 
562
        return nil
 
563
}
 
564
 
 
565
func (tfr *TermFrequencyRow) parseV(value []byte, includeTermVectors bool) error {
 
566
        var bytesRead int
 
567
        tfr.freq, bytesRead = binary.Uvarint(value)
 
568
        if bytesRead <= 0 {
 
569
                return fmt.Errorf("invalid term frequency value, invalid frequency")
 
570
        }
 
571
        currOffset := bytesRead
 
572
 
 
573
        var norm uint64
 
574
        norm, bytesRead = binary.Uvarint(value[currOffset:])
 
575
        if bytesRead <= 0 {
 
576
                return fmt.Errorf("invalid term frequency value, no norm")
 
577
        }
 
578
        currOffset += bytesRead
 
579
 
 
580
        tfr.norm = math.Float32frombits(uint32(norm))
 
581
 
 
582
        tfr.vectors = nil
 
583
        if !includeTermVectors {
 
584
                return nil
 
585
        }
 
586
 
 
587
        var field uint64
 
588
        field, bytesRead = binary.Uvarint(value[currOffset:])
 
589
        for bytesRead > 0 {
 
590
                currOffset += bytesRead
 
591
                tv := TermVector{}
 
592
                tv.field = uint16(field)
 
593
                // at this point we expect at least one term vector
 
594
                if tfr.vectors == nil {
 
595
                        tfr.vectors = make([]*TermVector, 0)
 
596
                }
 
597
 
 
598
                tv.pos, bytesRead = binary.Uvarint(value[currOffset:])
 
599
                if bytesRead <= 0 {
 
600
                        return fmt.Errorf("invalid term frequency value, vector contains no position")
 
601
                }
 
602
                currOffset += bytesRead
 
603
 
 
604
                tv.start, bytesRead = binary.Uvarint(value[currOffset:])
 
605
                if bytesRead <= 0 {
 
606
                        return fmt.Errorf("invalid term frequency value, vector contains no start")
 
607
                }
 
608
                currOffset += bytesRead
 
609
 
 
610
                tv.end, bytesRead = binary.Uvarint(value[currOffset:])
 
611
                if bytesRead <= 0 {
 
612
                        return fmt.Errorf("invalid term frequency value, vector contains no end")
 
613
                }
 
614
                currOffset += bytesRead
 
615
 
 
616
                var arrayPositionsLen uint64 = 0
 
617
                arrayPositionsLen, bytesRead = binary.Uvarint(value[currOffset:])
 
618
                if bytesRead <= 0 {
 
619
                        return fmt.Errorf("invalid term frequency value, vector contains no arrayPositionLen")
 
620
                }
 
621
                currOffset += bytesRead
 
622
 
 
623
                if arrayPositionsLen > 0 {
 
624
                        tv.arrayPositions = make([]uint64, arrayPositionsLen)
 
625
                        for i := 0; uint64(i) < arrayPositionsLen; i++ {
 
626
                                tv.arrayPositions[i], bytesRead = binary.Uvarint(value[currOffset:])
 
627
                                if bytesRead <= 0 {
 
628
                                        return fmt.Errorf("invalid term frequency value, vector contains no arrayPosition of index %d", i)
 
629
                                }
 
630
                                currOffset += bytesRead
 
631
                        }
 
632
                }
 
633
 
 
634
                tfr.vectors = append(tfr.vectors, &tv)
 
635
                // try to read next record (may not exist)
 
636
                field, bytesRead = binary.Uvarint(value[currOffset:])
 
637
        }
 
638
        if len(value[currOffset:]) > 0 && bytesRead <= 0 {
 
639
                return fmt.Errorf("invalid term frequency value, vector field invalid")
 
640
        }
 
641
 
 
642
        return nil
 
643
}
 
644
 
 
645
func NewTermFrequencyRowKV(key, value []byte) (*TermFrequencyRow, error) {
 
646
        rv, err := NewTermFrequencyRowK(key)
 
647
        if err != nil {
 
648
                return nil, err
 
649
        }
 
650
 
 
651
        err = rv.parseV(value, true)
 
652
        if err != nil {
 
653
                return nil, err
 
654
        }
 
655
        return rv, nil
 
656
 
 
657
}
 
658
 
 
659
type BackIndexRow struct {
 
660
        doc           []byte
 
661
        termsEntries  []*BackIndexTermsEntry
 
662
        storedEntries []*BackIndexStoreEntry
 
663
}
 
664
 
 
665
func (br *BackIndexRow) AllTermKeys() [][]byte {
 
666
        if br == nil {
 
667
                return nil
 
668
        }
 
669
        rv := make([][]byte, 0, len(br.termsEntries)) // FIXME this underestimates severely
 
670
        for _, termsEntry := range br.termsEntries {
 
671
                for i := range termsEntry.Terms {
 
672
                        termRow := NewTermFrequencyRow([]byte(termsEntry.Terms[i]), uint16(termsEntry.GetField()), br.doc, 0, 0)
 
673
                        rv = append(rv, termRow.Key())
 
674
                }
 
675
        }
 
676
        return rv
 
677
}
 
678
 
 
679
func (br *BackIndexRow) AllStoredKeys() [][]byte {
 
680
        if br == nil {
 
681
                return nil
 
682
        }
 
683
        rv := make([][]byte, len(br.storedEntries))
 
684
        for i, storedEntry := range br.storedEntries {
 
685
                storedRow := NewStoredRow(br.doc, uint16(storedEntry.GetField()), storedEntry.GetArrayPositions(), 'x', []byte{})
 
686
                rv[i] = storedRow.Key()
 
687
        }
 
688
        return rv
 
689
}
 
690
 
 
691
func (br *BackIndexRow) Key() []byte {
 
692
        buf := make([]byte, br.KeySize())
 
693
        size, _ := br.KeyTo(buf)
 
694
        return buf[:size]
 
695
}
 
696
 
 
697
func (br *BackIndexRow) KeySize() int {
 
698
        return len(br.doc) + 1
 
699
}
 
700
 
 
701
func (br *BackIndexRow) KeyTo(buf []byte) (int, error) {
 
702
        buf[0] = 'b'
 
703
        used := copy(buf[1:], br.doc)
 
704
        return used + 1, nil
 
705
}
 
706
 
 
707
func (br *BackIndexRow) Value() []byte {
 
708
        buf := make([]byte, br.ValueSize())
 
709
        size, _ := br.ValueTo(buf)
 
710
        return buf[:size]
 
711
}
 
712
 
 
713
func (br *BackIndexRow) ValueSize() int {
 
714
        birv := &BackIndexRowValue{
 
715
                TermsEntries:  br.termsEntries,
 
716
                StoredEntries: br.storedEntries,
 
717
        }
 
718
        return birv.Size()
 
719
}
 
720
 
 
721
func (br *BackIndexRow) ValueTo(buf []byte) (int, error) {
 
722
        birv := &BackIndexRowValue{
 
723
                TermsEntries:  br.termsEntries,
 
724
                StoredEntries: br.storedEntries,
 
725
        }
 
726
        return birv.MarshalTo(buf)
 
727
}
 
728
 
 
729
func (br *BackIndexRow) String() string {
 
730
        return fmt.Sprintf("Backindex DocId: `%s` Terms Entries: %v, Stored Entries: %v", string(br.doc), br.termsEntries, br.storedEntries)
 
731
}
 
732
 
 
733
func NewBackIndexRow(docID []byte, entries []*BackIndexTermsEntry, storedFields []*BackIndexStoreEntry) *BackIndexRow {
 
734
        return &BackIndexRow{
 
735
                doc:           docID,
 
736
                termsEntries:  entries,
 
737
                storedEntries: storedFields,
 
738
        }
 
739
}
 
740
 
 
741
func NewBackIndexRowKV(key, value []byte) (*BackIndexRow, error) {
 
742
        rv := BackIndexRow{}
 
743
 
 
744
        buf := bytes.NewBuffer(key)
 
745
        _, err := buf.ReadByte() // type
 
746
        if err != nil {
 
747
                return nil, err
 
748
        }
 
749
 
 
750
        rv.doc, err = buf.ReadBytes(ByteSeparator)
 
751
        if err == io.EOF && len(rv.doc) < 1 {
 
752
                err = fmt.Errorf("invalid doc length 0 - % x", key)
 
753
        }
 
754
        if err != nil && err != io.EOF {
 
755
                return nil, err
 
756
        } else if err == nil {
 
757
                rv.doc = rv.doc[:len(rv.doc)-1] // trim off separator byte
 
758
        }
 
759
 
 
760
        var birv BackIndexRowValue
 
761
        err = proto.Unmarshal(value, &birv)
 
762
        if err != nil {
 
763
                return nil, err
 
764
        }
 
765
        rv.termsEntries = birv.TermsEntries
 
766
        rv.storedEntries = birv.StoredEntries
 
767
 
 
768
        return &rv, nil
 
769
}
 
770
 
 
771
// STORED
 
772
 
 
773
type StoredRow struct {
 
774
        doc            []byte
 
775
        field          uint16
 
776
        arrayPositions []uint64
 
777
        typ            byte
 
778
        value          []byte
 
779
}
 
780
 
 
781
func (s *StoredRow) Key() []byte {
 
782
        buf := make([]byte, s.KeySize())
 
783
        size, _ := s.KeyTo(buf)
 
784
        return buf[0:size]
 
785
}
 
786
 
 
787
func (s *StoredRow) KeySize() int {
 
788
        return 1 + len(s.doc) + 1 + 2 + (binary.MaxVarintLen64 * len(s.arrayPositions))
 
789
}
 
790
 
 
791
func (s *StoredRow) KeyTo(buf []byte) (int, error) {
 
792
        docLen := len(s.doc)
 
793
        buf[0] = 's'
 
794
        copy(buf[1:], s.doc)
 
795
        buf[1+docLen] = ByteSeparator
 
796
        binary.LittleEndian.PutUint16(buf[1+docLen+1:], s.field)
 
797
        bytesUsed := 1 + docLen + 1 + 2
 
798
        for _, arrayPosition := range s.arrayPositions {
 
799
                varbytes := binary.PutUvarint(buf[bytesUsed:], arrayPosition)
 
800
                bytesUsed += varbytes
 
801
        }
 
802
        return bytesUsed, nil
 
803
}
 
804
 
 
805
func (s *StoredRow) Value() []byte {
 
806
        buf := make([]byte, s.ValueSize())
 
807
        size, _ := s.ValueTo(buf)
 
808
        return buf[:size]
 
809
}
 
810
 
 
811
func (s *StoredRow) ValueSize() int {
 
812
        return len(s.value) + 1
 
813
}
 
814
 
 
815
func (s *StoredRow) ValueTo(buf []byte) (int, error) {
 
816
        buf[0] = s.typ
 
817
        used := copy(buf[1:], s.value)
 
818
        return used + 1, nil
 
819
}
 
820
 
 
821
func (s *StoredRow) String() string {
 
822
        return fmt.Sprintf("Document: %s Field %d, Array Positions: %v, Type: %s Value: %s", s.doc, s.field, s.arrayPositions, string(s.typ), s.value)
 
823
}
 
824
 
 
825
func (s *StoredRow) ScanPrefixForDoc() []byte {
 
826
        docLen := len(s.doc)
 
827
        buf := make([]byte, 1+docLen+1)
 
828
        buf[0] = 's'
 
829
        copy(buf[1:], s.doc)
 
830
        buf[1+docLen] = ByteSeparator
 
831
        return buf
 
832
}
 
833
 
 
834
func NewStoredRow(docID []byte, field uint16, arrayPositions []uint64, typ byte, value []byte) *StoredRow {
 
835
        return &StoredRow{
 
836
                doc:            docID,
 
837
                field:          field,
 
838
                arrayPositions: arrayPositions,
 
839
                typ:            typ,
 
840
                value:          value,
 
841
        }
 
842
}
 
843
 
 
844
func NewStoredRowK(key []byte) (*StoredRow, error) {
 
845
        rv := StoredRow{}
 
846
 
 
847
        buf := bytes.NewBuffer(key)
 
848
        _, err := buf.ReadByte() // type
 
849
        if err != nil {
 
850
                return nil, err
 
851
        }
 
852
 
 
853
        rv.doc, err = buf.ReadBytes(ByteSeparator)
 
854
        if len(rv.doc) < 2 { // 1 for min doc id length, 1 for separator
 
855
                err = fmt.Errorf("invalid doc length 0")
 
856
                return nil, err
 
857
        }
 
858
 
 
859
        rv.doc = rv.doc[:len(rv.doc)-1] // trim off separator byte
 
860
 
 
861
        err = binary.Read(buf, binary.LittleEndian, &rv.field)
 
862
        if err != nil {
 
863
                return nil, err
 
864
        }
 
865
 
 
866
        rv.arrayPositions = make([]uint64, 0)
 
867
        nextArrayPos, err := binary.ReadUvarint(buf)
 
868
        for err == nil {
 
869
                rv.arrayPositions = append(rv.arrayPositions, nextArrayPos)
 
870
                nextArrayPos, err = binary.ReadUvarint(buf)
 
871
        }
 
872
        return &rv, nil
 
873
}
 
874
 
 
875
func NewStoredRowKV(key, value []byte) (*StoredRow, error) {
 
876
        rv, err := NewStoredRowK(key)
 
877
        if err != nil {
 
878
                return nil, err
 
879
        }
 
880
        rv.typ = value[0]
 
881
        rv.value = value[1:]
 
882
        return rv, nil
 
883
}
 
884
 
 
885
type backIndexFieldTermVisitor func(field uint32, term []byte)
 
886
 
 
887
// visitBackIndexRow is designed to process a protobuf encoded
 
888
// value, without creating unnecessary garbage.  Instead values are passed
 
889
// to a callback, inspected first, and only copied if necessary.
 
890
// Due to the fact that this borrows from generated code, it must be marnually
 
891
// updated if the protobuf definition changes.
 
892
//
 
893
// This code originates from:
 
894
// func (m *BackIndexRowValue) Unmarshal(data []byte) error
 
895
// the sections which create garbage or parse unintersting sections
 
896
// have been commented out.  This was done by design to allow for easier
 
897
// merging in the future if that original function is regenerated
 
898
func visitBackIndexRow(data []byte, callback backIndexFieldTermVisitor) error {
 
899
        l := len(data)
 
900
        iNdEx := 0
 
901
        for iNdEx < l {
 
902
                var wire uint64
 
903
                for shift := uint(0); ; shift += 7 {
 
904
                        if iNdEx >= l {
 
905
                                return io.ErrUnexpectedEOF
 
906
                        }
 
907
                        b := data[iNdEx]
 
908
                        iNdEx++
 
909
                        wire |= (uint64(b) & 0x7F) << shift
 
910
                        if b < 0x80 {
 
911
                                break
 
912
                        }
 
913
                }
 
914
                fieldNum := int32(wire >> 3)
 
915
                wireType := int(wire & 0x7)
 
916
                switch fieldNum {
 
917
                case 1:
 
918
                        if wireType != 2 {
 
919
                                return fmt.Errorf("proto: wrong wireType = %d for field TermsEntries", wireType)
 
920
                        }
 
921
                        var msglen int
 
922
                        for shift := uint(0); ; shift += 7 {
 
923
                                if iNdEx >= l {
 
924
                                        return io.ErrUnexpectedEOF
 
925
                                }
 
926
                                b := data[iNdEx]
 
927
                                iNdEx++
 
928
                                msglen |= (int(b) & 0x7F) << shift
 
929
                                if b < 0x80 {
 
930
                                        break
 
931
                                }
 
932
                        }
 
933
                        postIndex := iNdEx + msglen
 
934
                        if msglen < 0 {
 
935
                                return ErrInvalidLengthUpsidedown
 
936
                        }
 
937
                        if postIndex > l {
 
938
                                return io.ErrUnexpectedEOF
 
939
                        }
 
940
                        // dont parse term entries
 
941
                        // m.TermsEntries = append(m.TermsEntries, &BackIndexTermsEntry{})
 
942
                        // if err := m.TermsEntries[len(m.TermsEntries)-1].Unmarshal(data[iNdEx:postIndex]); err != nil {
 
943
                        //      return err
 
944
                        // }
 
945
                        // instead, inspect them
 
946
                        if err := visitBackIndexRowFieldTerms(data[iNdEx:postIndex], callback); err != nil {
 
947
                                return err
 
948
                        }
 
949
                        iNdEx = postIndex
 
950
                case 2:
 
951
                        if wireType != 2 {
 
952
                                return fmt.Errorf("proto: wrong wireType = %d for field StoredEntries", wireType)
 
953
                        }
 
954
                        var msglen int
 
955
                        for shift := uint(0); ; shift += 7 {
 
956
                                if iNdEx >= l {
 
957
                                        return io.ErrUnexpectedEOF
 
958
                                }
 
959
                                b := data[iNdEx]
 
960
                                iNdEx++
 
961
                                msglen |= (int(b) & 0x7F) << shift
 
962
                                if b < 0x80 {
 
963
                                        break
 
964
                                }
 
965
                        }
 
966
                        postIndex := iNdEx + msglen
 
967
                        if msglen < 0 {
 
968
                                return ErrInvalidLengthUpsidedown
 
969
                        }
 
970
                        if postIndex > l {
 
971
                                return io.ErrUnexpectedEOF
 
972
                        }
 
973
                        // don't parse stored entries
 
974
                        // m.StoredEntries = append(m.StoredEntries, &BackIndexStoreEntry{})
 
975
                        // if err := m.StoredEntries[len(m.StoredEntries)-1].Unmarshal(data[iNdEx:postIndex]); err != nil {
 
976
                        //      return err
 
977
                        // }
 
978
                        iNdEx = postIndex
 
979
                default:
 
980
                        var sizeOfWire int
 
981
                        for {
 
982
                                sizeOfWire++
 
983
                                wire >>= 7
 
984
                                if wire == 0 {
 
985
                                        break
 
986
                                }
 
987
                        }
 
988
                        iNdEx -= sizeOfWire
 
989
                        skippy, err := skipUpsidedown(data[iNdEx:])
 
990
                        if err != nil {
 
991
                                return err
 
992
                        }
 
993
                        if skippy < 0 {
 
994
                                return ErrInvalidLengthUpsidedown
 
995
                        }
 
996
                        if (iNdEx + skippy) > l {
 
997
                                return io.ErrUnexpectedEOF
 
998
                        }
 
999
                        // don't track unrecognized data
 
1000
                        //m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...)
 
1001
                        iNdEx += skippy
 
1002
                }
 
1003
        }
 
1004
 
 
1005
        return nil
 
1006
}
 
1007
 
 
1008
// visitBackIndexRowFieldTerms is designed to process a protobuf encoded
 
1009
// sub-value within the BackIndexRowValue, without creating unnecessary garbage.
 
1010
// Instead values are passed to a callback, inspected first, and only copied if
 
1011
// necessary.  Due to the fact that this borrows from generated code, it must
 
1012
// be marnually updated if the protobuf definition changes.
 
1013
//
 
1014
// This code originates from:
 
1015
// func (m *BackIndexTermsEntry) Unmarshal(data []byte) error {
 
1016
// the sections which create garbage or parse uninteresting sections
 
1017
// have been commented out.  This was done by design to allow for easier
 
1018
// merging in the future if that original function is regenerated
 
1019
func visitBackIndexRowFieldTerms(data []byte, callback backIndexFieldTermVisitor) error {
 
1020
        var theField uint32
 
1021
 
 
1022
        var hasFields [1]uint64
 
1023
        l := len(data)
 
1024
        iNdEx := 0
 
1025
        for iNdEx < l {
 
1026
                var wire uint64
 
1027
                for shift := uint(0); ; shift += 7 {
 
1028
                        if iNdEx >= l {
 
1029
                                return io.ErrUnexpectedEOF
 
1030
                        }
 
1031
                        b := data[iNdEx]
 
1032
                        iNdEx++
 
1033
                        wire |= (uint64(b) & 0x7F) << shift
 
1034
                        if b < 0x80 {
 
1035
                                break
 
1036
                        }
 
1037
                }
 
1038
                fieldNum := int32(wire >> 3)
 
1039
                wireType := int(wire & 0x7)
 
1040
                switch fieldNum {
 
1041
                case 1:
 
1042
                        if wireType != 0 {
 
1043
                                return fmt.Errorf("proto: wrong wireType = %d for field Field", wireType)
 
1044
                        }
 
1045
                        var v uint32
 
1046
                        for shift := uint(0); ; shift += 7 {
 
1047
                                if iNdEx >= l {
 
1048
                                        return io.ErrUnexpectedEOF
 
1049
                                }
 
1050
                                b := data[iNdEx]
 
1051
                                iNdEx++
 
1052
                                v |= (uint32(b) & 0x7F) << shift
 
1053
                                if b < 0x80 {
 
1054
                                        break
 
1055
                                }
 
1056
                        }
 
1057
                        // m.Field = &v
 
1058
                        theField = v
 
1059
                        hasFields[0] |= uint64(0x00000001)
 
1060
                case 2:
 
1061
                        if wireType != 2 {
 
1062
                                return fmt.Errorf("proto: wrong wireType = %d for field Terms", wireType)
 
1063
                        }
 
1064
                        var stringLen uint64
 
1065
                        for shift := uint(0); ; shift += 7 {
 
1066
                                if iNdEx >= l {
 
1067
                                        return io.ErrUnexpectedEOF
 
1068
                                }
 
1069
                                b := data[iNdEx]
 
1070
                                iNdEx++
 
1071
                                stringLen |= (uint64(b) & 0x7F) << shift
 
1072
                                if b < 0x80 {
 
1073
                                        break
 
1074
                                }
 
1075
                        }
 
1076
                        postIndex := iNdEx + int(stringLen)
 
1077
                        if postIndex > l {
 
1078
                                return io.ErrUnexpectedEOF
 
1079
                        }
 
1080
                        //m.Terms = append(m.Terms, string(data[iNdEx:postIndex]))
 
1081
                        callback(theField, data[iNdEx:postIndex])
 
1082
                        iNdEx = postIndex
 
1083
                default:
 
1084
                        var sizeOfWire int
 
1085
                        for {
 
1086
                                sizeOfWire++
 
1087
                                wire >>= 7
 
1088
                                if wire == 0 {
 
1089
                                        break
 
1090
                                }
 
1091
                        }
 
1092
                        iNdEx -= sizeOfWire
 
1093
                        skippy, err := skipUpsidedown(data[iNdEx:])
 
1094
                        if err != nil {
 
1095
                                return err
 
1096
                        }
 
1097
                        if skippy < 0 {
 
1098
                                return ErrInvalidLengthUpsidedown
 
1099
                        }
 
1100
                        if (iNdEx + skippy) > l {
 
1101
                                return io.ErrUnexpectedEOF
 
1102
                        }
 
1103
                        //m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...)
 
1104
                        iNdEx += skippy
 
1105
                }
 
1106
        }
 
1107
        // if hasFields[0]&uint64(0x00000001) == 0 {
 
1108
        //      return new(github_com_golang_protobuf_proto.RequiredNotSetError)
 
1109
        // }
 
1110
 
 
1111
        return nil
 
1112
}