-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathindex.go
336 lines (265 loc) · 10.9 KB
/
index.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
// Copyright (c) 2014 Couchbase, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package index
import (
"bytes"
"context"
"reflect"
)
var reflectStaticSizeTermFieldDoc int
var reflectStaticSizeTermFieldVector int
func init() {
var tfd TermFieldDoc
reflectStaticSizeTermFieldDoc = int(reflect.TypeOf(tfd).Size())
var tfv TermFieldVector
reflectStaticSizeTermFieldVector = int(reflect.TypeOf(tfv).Size())
}
type Index interface {
Open() error
Close() error
Update(doc Document) error
Delete(id string) error
Batch(batch *Batch) error
SetInternal(key, val []byte) error
DeleteInternal(key []byte) error
// Reader returns a low-level accessor on the index data. Close it to
// release associated resources.
Reader() (IndexReader, error)
StatsMap() map[string]interface{}
}
// CopyIndex is an extended index that supports copying to a new location online.
// Use the CopyReader method to obtain a reader for initiating the copy operation.
type CopyIndex interface {
Index
// Obtain a copy reader for the online copy/backup operation,
// to handle necessary bookkeeping, instead of using the regular IndexReader.
CopyReader() CopyReader
}
// EventIndex is an optional interface for exposing the support for firing event
// callbacks for various events in the index.
type EventIndex interface {
// FireIndexEvent is used to fire an event callback when Index() is called,
// to notify the caller that a document has been added to the index.
FireIndexEvent()
}
type IndexReader interface {
TermFieldReader(ctx context.Context, term []byte, field string, includeFreq, includeNorm, includeTermVectors bool) (TermFieldReader, error)
// DocIDReader returns an iterator over all doc ids
// The caller must close returned instance to release associated resources.
DocIDReaderAll() (DocIDReader, error)
DocIDReaderOnly(ids []string) (DocIDReader, error)
FieldDict(field string) (FieldDict, error)
// FieldDictRange is currently defined to include the start and end terms
FieldDictRange(field string, startTerm []byte, endTerm []byte) (FieldDict, error)
FieldDictPrefix(field string, termPrefix []byte) (FieldDict, error)
Document(id string) (Document, error)
DocValueReader(fields []string) (DocValueReader, error)
Fields() ([]string, error)
GetInternal(key []byte) ([]byte, error)
DocCount() (uint64, error)
ExternalID(id IndexInternalID) (string, error)
InternalID(id string) (IndexInternalID, error)
Close() error
}
// CopyReader is an extended index reader for backup or online copy operations, replacing the regular index reader.
type CopyReader interface {
IndexReader
// CopyTo performs an online copy or backup of the index to the specified directory.
CopyTo(d Directory) error
// CloseCopyReader must be used instead of Close() to close the copy reader.
CloseCopyReader() error
}
// RegexAutomaton abstracts an automaton built using a regex pattern.
type RegexAutomaton interface {
// MatchesRegex returns true if the given string matches the regex pattern
// used to build the automaton.
MatchesRegex(string) bool
}
// IndexReaderRegexp provides functionality to work with regex-based field dictionaries.
type IndexReaderRegexp interface {
// FieldDictRegexp returns a FieldDict for terms matching the specified regex pattern
// in the dictionary of the given field.
FieldDictRegexp(field string, regex string) (FieldDict, error)
// FieldDictRegexpAutomaton returns a FieldDict and a RegexAutomaton that can be used
// to match strings against the regex pattern.
FieldDictRegexpAutomaton(field string, regex string) (FieldDict, RegexAutomaton, error)
}
// FuzzyAutomaton abstracts a Levenshtein automaton built using a term and a fuzziness value.
type FuzzyAutomaton interface {
// MatchAndDistance checks if the given string is within the fuzziness distance
// of the term used to build the automaton. It also returns the edit (Levenshtein)
// distance between the string and the term.
MatchAndDistance(term string) (bool, uint8)
}
// IndexReaderFuzzy provides functionality to work with fuzzy matching in field dictionaries.
type IndexReaderFuzzy interface {
// FieldDictFuzzy returns a FieldDict for terms that are within the specified fuzziness
// distance of the given term and match the specified prefix in the given field.
FieldDictFuzzy(field string, term string, fuzziness int, prefix string) (FieldDict, error)
// FieldDictFuzzyAutomaton returns a FieldDict and a FuzzyAutomaton that can be used
// to calculate the edit distance between the term and other strings.
FieldDictFuzzyAutomaton(field string, term string, fuzziness int, prefix string) (FieldDict, FuzzyAutomaton, error)
}
type IndexReaderContains interface {
FieldDictContains(field string) (FieldDictContains, error)
}
// SpatialIndexPlugin is an optional interface for exposing the
// support for any custom analyzer plugins that are capable of
// generating hierarchial spatial tokens for both indexing and
// query purposes from the geo location data.
type SpatialIndexPlugin interface {
GetSpatialAnalyzerPlugin(typ string) (SpatialAnalyzerPlugin, error)
}
type TermFieldVector struct {
Field string
ArrayPositions []uint64
Pos uint64
Start uint64
End uint64
}
func (tfv *TermFieldVector) Size() int {
return reflectStaticSizeTermFieldVector + sizeOfPtr +
len(tfv.Field) + len(tfv.ArrayPositions)*sizeOfUint64
}
// IndexInternalID is an opaque document identifier interal to the index impl
type IndexInternalID []byte
func (id IndexInternalID) Equals(other IndexInternalID) bool {
return id.Compare(other) == 0
}
func (id IndexInternalID) Compare(other IndexInternalID) int {
return bytes.Compare(id, other)
}
type TermFieldDoc struct {
Term string
ID IndexInternalID
Freq uint64
Norm float64
Vectors []*TermFieldVector
}
func (tfd *TermFieldDoc) Size() int {
sizeInBytes := reflectStaticSizeTermFieldDoc + sizeOfPtr +
len(tfd.Term) + len(tfd.ID)
for _, entry := range tfd.Vectors {
sizeInBytes += entry.Size()
}
return sizeInBytes
}
// Reset allows an already allocated TermFieldDoc to be reused
func (tfd *TermFieldDoc) Reset() *TermFieldDoc {
// remember the []byte used for the ID
id := tfd.ID
vectors := tfd.Vectors
// idiom to copy over from empty TermFieldDoc (0 allocations)
*tfd = TermFieldDoc{}
// reuse the []byte already allocated (and reset len to 0)
tfd.ID = id[:0]
tfd.Vectors = vectors[:0]
return tfd
}
// TermFieldReader is the interface exposing the enumeration of documents
// containing a given term in a given field. Documents are returned in byte
// 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. 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.
Advance(ID IndexInternalID, preAlloced *TermFieldDoc) (*TermFieldDoc, error)
// Count returns the number of documents contains the term in this field.
Count() uint64
Close() error
Size() int
}
type DictEntry struct {
Term string
Count uint64
EditDistance uint8
}
type FieldDict interface {
Next() (*DictEntry, error)
Close() error
Cardinality() int
BytesRead() uint64
}
type FieldDictContains interface {
Contains(key []byte) (bool, error)
BytesRead() uint64
}
// DocIDReader is the interface exposing enumeration of documents identifiers.
// Close the reader to release associated resources.
type DocIDReader interface {
// Next returns the next document internal identifier in the natural
// index order, nil when the end of the sequence is reached.
Next() (IndexInternalID, error)
// Advance resets the iteration to the first internal identifier greater than
// or equal to ID. If ID is smaller than the start of the range, the iteration
// will start there instead. If ID is greater than or equal to the end of
// the range, Next() call will return io.EOF.
Advance(ID IndexInternalID) (IndexInternalID, error)
Size() int
Close() error
}
type DocValueVisitor func(field string, term []byte)
type DocValueReader interface {
VisitDocValues(id IndexInternalID, visitor DocValueVisitor) error
BytesRead() uint64
}
// IndexBuilder is an interface supported by some index schemes
// to allow direct write-only index building
type IndexBuilder interface {
Index(doc Document) error
Close() error
}
// ThesaurusTermReader is an interface for enumerating synonyms of a term in a thesaurus.
type ThesaurusTermReader interface {
// Next returns the next synonym of the term, or an error if something goes wrong.
// Returns nil when the enumeration is complete.
Next() (string, error)
// Close releases any resources associated with the reader.
Close() error
Size() int
}
// ThesaurusEntry represents a term in the thesaurus for which synonyms are stored.
type ThesaurusEntry struct {
Term string
}
// ThesaurusKeys is an interface for enumerating terms (keys) in a thesaurus.
type ThesaurusKeys interface {
// Next returns the next key in the thesaurus, or an error if something goes wrong.
// Returns nil when the enumeration is complete.
Next() (*ThesaurusEntry, error)
// Close releases any resources associated with the reader.
Close() error
}
// ThesaurusReader is an interface for accessing a thesaurus in the index.
type ThesaurusReader interface {
IndexReader
// ThesaurusTermReader returns a reader for the synonyms of a given term in the
// specified thesaurus.
ThesaurusTermReader(ctx context.Context, name string, term []byte) (ThesaurusTermReader, error)
// ThesaurusKeys returns a reader for all terms in the specified thesaurus.
ThesaurusKeys(name string) (ThesaurusKeys, error)
// ThesaurusKeysFuzzy returns a reader for terms in the specified thesaurus that
// match the given prefix and are within the specified fuzziness distance from
// the provided term.
ThesaurusKeysFuzzy(name string, term string, fuzziness int, prefix string) (ThesaurusKeys, error)
// ThesaurusKeysRegexp returns a reader for terms in the specified thesaurus that
// match the given regular expression pattern.
ThesaurusKeysRegexp(name string, regex string) (ThesaurusKeys, error)
// ThesaurusKeysPrefix returns a reader for terms in the specified thesaurus that
// start with the given prefix.
ThesaurusKeysPrefix(name string, termPrefix []byte) (ThesaurusKeys, error)
}