1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package attribute
16
17 import (
18 "encoding/json"
19 "reflect"
20 "sort"
21 "sync"
22 )
23
24 type (
25
26
27
28
29
30
31 Set struct {
32 equivalent Distinct
33 }
34
35
36
37
38 Distinct struct {
39 iface interface{}
40 }
41
42
43
44
45
46 Sortable []KeyValue
47 )
48
49 var (
50
51 keyValueType = reflect.TypeOf(KeyValue{})
52
53
54 emptySet = &Set{
55 equivalent: Distinct{
56 iface: [0]KeyValue{},
57 },
58 }
59
60
61
62 sortables = sync.Pool{
63 New: func() interface{} { return new(Sortable) },
64 }
65 )
66
67
68
69
70 func EmptySet() *Set {
71 return emptySet
72 }
73
74
75 func (d Distinct) reflectValue() reflect.Value {
76 return reflect.ValueOf(d.iface)
77 }
78
79
80 func (d Distinct) Valid() bool {
81 return d.iface != nil
82 }
83
84
85 func (l *Set) Len() int {
86 if l == nil || !l.equivalent.Valid() {
87 return 0
88 }
89 return l.equivalent.reflectValue().Len()
90 }
91
92
93 func (l *Set) Get(idx int) (KeyValue, bool) {
94 if l == nil || !l.equivalent.Valid() {
95 return KeyValue{}, false
96 }
97 value := l.equivalent.reflectValue()
98
99 if idx >= 0 && idx < value.Len() {
100
101
102 return value.Index(idx).Interface().(KeyValue), true
103 }
104
105 return KeyValue{}, false
106 }
107
108
109 func (l *Set) Value(k Key) (Value, bool) {
110 if l == nil || !l.equivalent.Valid() {
111 return Value{}, false
112 }
113 rValue := l.equivalent.reflectValue()
114 vlen := rValue.Len()
115
116 idx := sort.Search(vlen, func(idx int) bool {
117 return rValue.Index(idx).Interface().(KeyValue).Key >= k
118 })
119 if idx >= vlen {
120 return Value{}, false
121 }
122 keyValue := rValue.Index(idx).Interface().(KeyValue)
123 if k == keyValue.Key {
124 return keyValue.Value, true
125 }
126 return Value{}, false
127 }
128
129
130 func (l *Set) HasValue(k Key) bool {
131 if l == nil {
132 return false
133 }
134 _, ok := l.Value(k)
135 return ok
136 }
137
138
139 func (l *Set) Iter() Iterator {
140 return Iterator{
141 storage: l,
142 idx: -1,
143 }
144 }
145
146
147
148 func (l *Set) ToSlice() []KeyValue {
149 iter := l.Iter()
150 return iter.ToSlice()
151 }
152
153
154
155
156
157 func (l *Set) Equivalent() Distinct {
158 if l == nil || !l.equivalent.Valid() {
159 return emptySet.equivalent
160 }
161 return l.equivalent
162 }
163
164
165 func (l *Set) Equals(o *Set) bool {
166 return l.Equivalent() == o.Equivalent()
167 }
168
169
170 func (l *Set) Encoded(encoder Encoder) string {
171 if l == nil || encoder == nil {
172 return ""
173 }
174
175 return encoder.Encode(l.Iter())
176 }
177
178 func empty() Set {
179 return Set{
180 equivalent: emptySet.equivalent,
181 }
182 }
183
184
185
186
187
188
189 func NewSet(kvs ...KeyValue) Set {
190
191 if len(kvs) == 0 {
192 return empty()
193 }
194 srt := sortables.Get().(*Sortable)
195 s, _ := NewSetWithSortableFiltered(kvs, srt, nil)
196 sortables.Put(srt)
197 return s
198 }
199
200
201
202
203
204 func NewSetWithSortable(kvs []KeyValue, tmp *Sortable) Set {
205
206 if len(kvs) == 0 {
207 return empty()
208 }
209 s, _ := NewSetWithSortableFiltered(kvs, tmp, nil)
210 return s
211 }
212
213
214
215
216
217
218 func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
219
220 if len(kvs) == 0 {
221 return empty(), nil
222 }
223 srt := sortables.Get().(*Sortable)
224 s, filtered := NewSetWithSortableFiltered(kvs, srt, filter)
225 sortables.Put(srt)
226 return s, filtered
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 func NewSetWithSortableFiltered(kvs []KeyValue, tmp *Sortable, filter Filter) (Set, []KeyValue) {
253
254 if len(kvs) == 0 {
255 return empty(), nil
256 }
257
258 *tmp = kvs
259
260
261
262 sort.Stable(tmp)
263
264 *tmp = nil
265
266 position := len(kvs) - 1
267 offset := position - 1
268
269
270
271
272
273
274
275 for ; offset >= 0; offset-- {
276 if kvs[offset].Key == kvs[position].Key {
277 continue
278 }
279 position--
280 kvs[offset], kvs[position] = kvs[position], kvs[offset]
281 }
282 if filter != nil {
283 return filterSet(kvs[position:], filter)
284 }
285 return Set{
286 equivalent: computeDistinct(kvs[position:]),
287 }, nil
288 }
289
290
291
292 func filterSet(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
293 var excluded []KeyValue
294
295
296
297 distinctPosition := len(kvs)
298
299
300
301 offset := len(kvs) - 1
302 for ; offset >= 0; offset-- {
303 if filter(kvs[offset]) {
304 distinctPosition--
305 kvs[offset], kvs[distinctPosition] = kvs[distinctPosition], kvs[offset]
306 continue
307 }
308 }
309 excluded = kvs[:distinctPosition]
310
311 return Set{
312 equivalent: computeDistinct(kvs[distinctPosition:]),
313 }, excluded
314 }
315
316
317
318 func (l *Set) Filter(re Filter) (Set, []KeyValue) {
319 if re == nil {
320 return Set{
321 equivalent: l.equivalent,
322 }, nil
323 }
324
325
326
327 return filterSet(l.ToSlice(), re)
328 }
329
330
331
332
333 func computeDistinct(kvs []KeyValue) Distinct {
334 iface := computeDistinctFixed(kvs)
335 if iface == nil {
336 iface = computeDistinctReflect(kvs)
337 }
338 return Distinct{
339 iface: iface,
340 }
341 }
342
343
344
345 func computeDistinctFixed(kvs []KeyValue) interface{} {
346 switch len(kvs) {
347 case 1:
348 ptr := new([1]KeyValue)
349 copy((*ptr)[:], kvs)
350 return *ptr
351 case 2:
352 ptr := new([2]KeyValue)
353 copy((*ptr)[:], kvs)
354 return *ptr
355 case 3:
356 ptr := new([3]KeyValue)
357 copy((*ptr)[:], kvs)
358 return *ptr
359 case 4:
360 ptr := new([4]KeyValue)
361 copy((*ptr)[:], kvs)
362 return *ptr
363 case 5:
364 ptr := new([5]KeyValue)
365 copy((*ptr)[:], kvs)
366 return *ptr
367 case 6:
368 ptr := new([6]KeyValue)
369 copy((*ptr)[:], kvs)
370 return *ptr
371 case 7:
372 ptr := new([7]KeyValue)
373 copy((*ptr)[:], kvs)
374 return *ptr
375 case 8:
376 ptr := new([8]KeyValue)
377 copy((*ptr)[:], kvs)
378 return *ptr
379 case 9:
380 ptr := new([9]KeyValue)
381 copy((*ptr)[:], kvs)
382 return *ptr
383 case 10:
384 ptr := new([10]KeyValue)
385 copy((*ptr)[:], kvs)
386 return *ptr
387 default:
388 return nil
389 }
390 }
391
392
393
394 func computeDistinctReflect(kvs []KeyValue) interface{} {
395 at := reflect.New(reflect.ArrayOf(len(kvs), keyValueType)).Elem()
396 for i, keyValue := range kvs {
397 *(at.Index(i).Addr().Interface().(*KeyValue)) = keyValue
398 }
399 return at.Interface()
400 }
401
402
403 func (l *Set) MarshalJSON() ([]byte, error) {
404 return json.Marshal(l.equivalent.iface)
405 }
406
407
408 func (l Set) MarshalLog() interface{} {
409 kvs := make(map[string]string)
410 for _, kv := range l.ToSlice() {
411 kvs[string(kv.Key)] = kv.Value.Emit()
412 }
413 return kvs
414 }
415
416
417 func (l *Sortable) Len() int {
418 return len(*l)
419 }
420
421
422 func (l *Sortable) Swap(i, j int) {
423 (*l)[i], (*l)[j] = (*l)[j], (*l)[i]
424 }
425
426
427 func (l *Sortable) Less(i, j int) bool {
428 return (*l)[i].Key < (*l)[j].Key
429 }
430
View as plain text