blob: d042f05e2d417ef758e99bad20e0f4103a333bf9 [file] [log] [blame]
Christian Lavoieafc6d8f2011-02-20 02:39:19 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20package thrift
21
22import (
23 "container/list"
24 "reflect"
25)
26
27/**
28 * Helper class that encapsulates map metadata.
29 *
30 */
31type TMap interface {
32 KeyType() TType
33 ValueType() TType
34 Len() int
35 Set(key, value interface{})
36 Get(key interface{}) (interface{}, bool)
37 Contains(key interface{}) bool
38 Iter() <-chan TMapElem
39 KeyIter() <-chan interface{}
40 ValueIter() <-chan interface{}
41 Keys() []interface{}
42 Values() []interface{}
43 Less(other interface{}) bool
44 Equals(other interface{}) bool
45 CompareTo(other interface{}) (int, bool)
46}
47
48type TMapElem interface {
49 Key() interface{}
50 Value() interface{}
51}
52
53type tMap struct {
54 keyType TType
55 valueType TType
56 size int
57 l *list.List
58 b map[bool]interface{}
59 i08 map[byte]interface{}
60 i16 map[int16]interface{}
61 i32 map[int32]interface{}
62 i64 map[int64]interface{}
63 f64 map[float64]interface{}
64 s map[string]interface{}
65}
66
67type tMapElem struct {
68 key interface{}
69 value interface{}
70}
71
72func (p *tMapElem) Key() interface{} {
73 return p.key
74}
75
76func (p *tMapElem) Value() interface{} {
77 return p.value
78}
79
80func NewTMapElem(k, v interface{}) TMapElem {
81 return &tMapElem{key: k, value: v}
82}
83
84func NewTMap(k, v TType, s int) TMap {
85 return &tMap{keyType: k, valueType: v, size: s, l: list.New()}
86}
87
88func NewTMapDefault() TMap {
89 return NewTMap(STOP, STOP, 0)
90}
91
92func (p *tMap) KeyType() TType {
93 return p.keyType
94}
95
96func (p *tMap) ValueType() TType {
97 return p.valueType
98}
99
100func (p *tMap) Len() int {
101 if p.l.Len() != 0 {
102 return p.l.Len()
103 }
104 switch p.KeyType() {
105 case STOP, VOID:
106 return 0
107 case BOOL:
108 return len(p.b)
109 case BYTE:
110 return len(p.i08)
111 case I16:
112 return len(p.i16)
113 case I32:
114 return len(p.i32)
115 case I64:
116 return len(p.i64)
117 case DOUBLE:
118 return len(p.f64)
119 case STRING, UTF8, UTF16:
120 return len(p.s)
121 default:
122 return p.size
123 }
124 return p.size
125}
126
127func (p *tMap) Get(key interface{}) (interface{}, bool) {
128 if p.KeyType().IsEmptyType() {
129 return nil, false
130 }
131 if key == nil {
132 for elem := p.l.Front(); elem != nil; elem = elem.Next() {
133 e := elem.Value.(TMapElem)
134 k := e.Key()
135 if k == nil {
136 return e.Value(), true
137 }
138 }
139 return nil, false
140 }
141 useKey, ok := p.KeyType().CoerceData(key)
142 if !ok {
143 return nil, false
144 }
145 switch p.KeyType() {
146 case STOP, VOID:
147 // if here, then we don't have a key type yet and key is not nil
148 // so this is pretty much an empty map
149 return nil, false
150 case BOOL:
151 m := p.b
152 if m == nil {
153 return nil, false
154 }
155 if v, ok := m[useKey.(bool)]; ok {
156 return v, true
157 }
158 return nil, true
159 case BYTE:
160 m := p.i08
161 if v, ok := m[useKey.(byte)]; ok {
162 return v, true
163 }
164 return nil, false
165 case DOUBLE:
166 m := p.f64
167 if m == nil {
168 return nil, false
169 }
170 if v, ok := m[useKey.(float64)]; ok {
171 return v, true
172 }
173 return nil, false
174 case I16:
175 m := p.i16
176 if m == nil {
177 return nil, false
178 }
179 if v, ok := m[useKey.(int16)]; ok {
180 return v, true
181 }
182 return nil, false
183 case I32:
184 m := p.i32
185 if m == nil {
186 return nil, false
187 }
188 if v, ok := m[useKey.(int32)]; ok {
189 return v, true
190 }
191 return nil, false
192 case I64:
193 m := p.i64
194 if m == nil {
195 return nil, false
196 }
197 if v, ok := m[useKey.(int64)]; ok {
198 return v, true
199 }
200 return nil, false
201 case STRING, UTF8, UTF16:
202 // TODO(pomack) properly handle ENUM
203 m := p.s
204 if m == nil {
205 return nil, false
206 }
207 if v, ok := m[useKey.(string)]; ok {
208 return v, true
209 }
210 return nil, false
211 case STRUCT:
212 for elem := p.l.Front(); elem != nil; elem = elem.Next() {
213 e := elem.Value.(TMapElem)
214 k := e.Key()
215 if k == nil {
216 continue
217 }
218 structkey, ok := k.(TStruct)
219 if ok {
220 if structkey.Equals(useKey.(TStruct)) {
221 return e.Value(), true
222 }
223 continue
224 }
225 if reflect.DeepEqual(useKey, k) {
226 return e.Value(), true
227 }
228 }
229 return nil, false
230 case MAP:
231 for elem := p.l.Front(); elem != nil; elem = elem.Next() {
232 e := elem.Value.(TMapElem)
233 k := e.Key()
234 if k == nil {
235 continue
236 }
237 mapkey, ok := k.(TMap)
238 if ok {
239 if mapkey.Equals(useKey.(TMap)) {
240 return e.Value(), true
241 }
242 continue
243 }
244 if reflect.DeepEqual(useKey, k) {
245 return e.Value(), true
246 }
247 }
248 return nil, false
249 case SET:
250 for elem := p.l.Front(); elem != nil; elem = elem.Next() {
251 e := elem.Value.(TMapElem)
252 k := e.Key()
253 if k == nil {
254 continue
255 }
256 setkey, ok := k.(TSet)
257 if ok {
258 if setkey.Equals(useKey.(TSet)) {
259 return e.Value(), true
260 }
261 continue
262 }
263 if reflect.DeepEqual(useKey, k) {
264 return e.Value(), true
265 }
266 }
267 return nil, false
268 case LIST:
269 for elem := p.l.Front(); elem != nil; elem = elem.Next() {
270 e := elem.Value.(TMapElem)
271 k := e.Key()
272 if k == nil {
273 continue
274 }
275 listkey, ok := k.(TList)
276 if ok {
277 if listkey.Equals(useKey.(TList)) {
278 return e.Value(), true
279 }
280 continue
281 }
282 if reflect.DeepEqual(useKey, k) {
283 return e.Value(), true
284 }
285 }
286 return nil, false
287 default:
288 panic("Invalid Thrift element type")
289 }
290 return nil, false
291}
292
293
294func (p *tMap) Set(key, value interface{}) {
295 if p.KeyType() == STOP || p.KeyType() == VOID {
296 p.keyType = TypeFromValue(key)
297 }
298 coercedKey, ok := p.KeyType().CoerceData(key)
299 if !ok {
300 return
301 }
302 if p.ValueType() == STOP || p.ValueType() == VOID {
303 p.valueType = TypeFromValue(value)
304 }
305 coercedValue, ok := p.ValueType().CoerceData(value)
306 if !ok {
307 return
308 }
309 newElem := NewTMapElem(coercedKey, coercedValue)
310 if !p.KeyType().IsBaseType() {
311 for elem := p.l.Front(); elem != nil; elem = elem.Next() {
312 k := elem.Value.(TMapElem).Key()
313 if cmp, ok := p.KeyType().Compare(coercedKey, k); ok && cmp >= 0 {
314 if cmp == 0 {
315 p.l.InsertAfter(newElem, elem)
316 p.l.Remove(elem)
317 return
318 }
319 p.l.InsertBefore(newElem, elem)
320 return
321 }
322 }
323 p.l.PushBack(newElem)
324 return
325 }
326 if key == nil {
327 return
328 }
329 switch p.KeyType() {
330 case STOP, VOID:
331 // if here, then we don't have a key type yet and key is not nil
332 // so this is pretty much an empty map
333 return
334 case BOOL:
335 if p.b == nil {
336 p.b = make(map[bool]interface{})
337 }
338 b := coercedKey.(bool)
339 p.b[b] = value
340 case BYTE:
341 if p.i08 == nil {
342 p.i08 = make(map[byte]interface{})
343 }
344 b := coercedKey.(byte)
345 p.i08[b] = value
346 case DOUBLE:
347 if p.f64 == nil {
348 p.f64 = make(map[float64]interface{})
349 }
350 b := coercedKey.(float64)
351 p.f64[b] = value
352 case I16:
353 if p.i16 == nil {
354 p.i16 = make(map[int16]interface{})
355 }
356 b := coercedKey.(int16)
357 p.i16[b] = value
358 case I32:
359 if p.i32 == nil {
360 p.i32 = make(map[int32]interface{})
361 }
362 b := coercedKey.(int32)
363 p.i32[b] = value
364 case I64:
365 if p.i64 == nil {
366 p.i64 = make(map[int64]interface{})
367 }
368 b := coercedKey.(int64)
369 p.i64[b] = value
370 case STRING, UTF8, UTF16:
371 if p.s == nil {
372 p.s = make(map[string]interface{})
373 }
374 b := coercedKey.(string)
375 p.s[b] = value
376 case STRUCT, MAP, SET, LIST:
377 panic("Should never be here")
378 default:
379 panic("Should never be here")
380 }
381}
382
383func (p *tMap) Contains(key interface{}) bool {
384 coercedKey, ok := p.KeyType().CoerceData(key)
385 if !ok {
386 return false
387 }
388 if coercedKey == nil {
389 for elem := p.l.Front(); elem != nil; elem = elem.Next() {
390 k := elem.Value.(TMapElem).Key()
391 if k == nil {
392 return true
393 }
394 }
395 return false
396 }
397 if !ok {
398 return false
399 }
400 switch p.KeyType() {
401 case STOP:
402 // if here, then we don't have a key type yet and key is not nil
403 // so this is pretty much an empty map
404 return false
405 case VOID:
406 // if here, then we don't have a key type yet and key is not nil
407 // so this is pretty much an empty map
408 return false
409 case BOOL:
410 m := p.b
411 if m == nil {
412 return false
413 }
414 _, ok := m[coercedKey.(bool)]
415 return ok
416 case BYTE:
417 m := p.i08
418 _, ok := m[coercedKey.(byte)]
419 return ok
420 case DOUBLE:
421 m := p.f64
422 if m == nil {
423 return false
424 }
425 _, ok := m[coercedKey.(float64)]
426 return ok
427 case I16:
428 m := p.i16
429 if m == nil {
430 return false
431 }
432 _, ok := m[coercedKey.(int16)]
433 return ok
434 case I32:
435 m := p.i32
436 if m == nil {
437 return false
438 }
439 _, ok := m[coercedKey.(int32)]
440 return ok
441 case I64:
442 m := p.i64
443 if m == nil {
444 return false
445 }
446 _, ok := m[coercedKey.(int64)]
447 return ok
448 case STRING, UTF8, UTF16:
449 // TODO(pomack) properly handle ENUM
450 m := p.s
451 if m == nil {
452 return false
453 }
454 _, ok := m[coercedKey.(string)]
455 return ok
456 case STRUCT:
457 for elem := p.l.Front(); elem != nil; elem = elem.Next() {
458 e := elem.Value.(TMapElem)
459 k := e.Key()
460 if k == nil {
461 continue
462 }
463 structkey, ok := k.(TStruct)
464 if ok {
465 if structkey.Equals(coercedKey.(TStruct)) {
466 return true
467 }
468 continue
469 }
470 if reflect.DeepEqual(coercedKey, k) {
471 return true
472 }
473 }
474 return false
475 case MAP:
476 for elem := p.l.Front(); elem != nil; elem = elem.Next() {
477 e := elem.Value.(TMapElem)
478 k := e.Key()
479 if k == nil {
480 continue
481 }
482 mapkey, ok := k.(TMap)
483 if ok {
484 if mapkey.Equals(coercedKey.(TMap)) {
485 return true
486 }
487 continue
488 }
489 }
490 return false
491 case SET:
492 for elem := p.l.Front(); elem != nil; elem = elem.Next() {
493 e := elem.Value.(TMapElem)
494 k := e.Key()
495 if k == nil {
496 continue
497 }
498 setkey, ok := k.(TSet)
499 if ok {
500 if setkey.Equals(coercedKey.(TSet)) {
501 return true
502 }
503 continue
504 }
505 }
506 return false
507 case LIST:
508 for elem := p.l.Front(); elem != nil; elem = elem.Next() {
509 e := elem.Value.(TMapElem)
510 k := e.Key()
511 if k == nil {
512 continue
513 }
514 listkey, ok := k.(TList)
515 if ok {
516 if listkey.Equals(coercedKey.(TList)) {
517 return true
518 }
519 continue
520 }
521 }
522 return false
523 default:
524 panic("Invalid Thrift element type")
525 }
526 return false
527}
528
529// Iterate over all elements; driver for range
530func (p *tMap) iterate(c chan<- TMapElem) {
531 switch p.KeyType() {
532 case STOP, VOID:
533 close(c)
534 case BOOL:
535 for k, v := range p.b {
536 c <- NewTMapElem(k, v)
537 }
538 close(c)
539 case BYTE:
540 for k, v := range p.i08 {
541 c <- NewTMapElem(k, v)
542 }
543 close(c)
544 case I16:
545 for k, v := range p.i16 {
546 c <- NewTMapElem(k, v)
547 }
548 close(c)
549 case I32:
550 for k, v := range p.i32 {
551 c <- NewTMapElem(k, v)
552 }
553 close(c)
554 case I64:
555 for k, v := range p.i64 {
556 c <- NewTMapElem(k, v)
557 }
558 close(c)
559 case DOUBLE:
560 for k, v := range p.f64 {
561 c <- NewTMapElem(k, v)
562 }
563 close(c)
564 case STRING, UTF8, UTF16:
565 for k, v := range p.s {
566 c <- NewTMapElem(k, v)
567 }
568 close(c)
569 case STRUCT:
570 for v := p.l.Front(); v != nil; v = v.Next() {
571 c <- v.Value.(TMapElem)
572 }
573 close(c)
574 case LIST:
575 for v := p.l.Front(); v != nil; v = v.Next() {
576 c <- v.Value.(TMapElem)
577 }
578 close(c)
579 case SET:
580 for v := p.l.Front(); v != nil; v = v.Next() {
581 c <- v.Value.(TMapElem)
582 }
583 close(c)
584 default:
585 panic("Invalid Thrift type")
586 }
587}
588
589// Channel iterator for range.
590func (p *tMap) Iter() <-chan TMapElem {
591 c := make(chan TMapElem)
592 go p.iterate(c)
593 return c
594}
595
596// Iterate over all keys; driver for range
597func (p *tMap) iterateKeys(c chan<- interface{}) {
598 switch p.KeyType() {
599 case STOP, VOID:
600 close(c)
601 case BOOL:
602 for k, _ := range p.b {
603 c <- k
604 }
605 close(c)
606 case BYTE:
607 for k, _ := range p.i08 {
608 c <- k
609 }
610 close(c)
611 case I16:
612 for k, _ := range p.i16 {
613 c <- k
614 }
615 close(c)
616 case I32:
617 for k, _ := range p.i32 {
618 c <- k
619 }
620 close(c)
621 case I64:
622 for k, _ := range p.i64 {
623 c <- k
624 }
625 close(c)
626 case DOUBLE:
627 for k, _ := range p.f64 {
628 c <- k
629 }
630 close(c)
631 case STRING, UTF8, UTF16:
632 for k, _ := range p.s {
633 c <- k
634 }
635 close(c)
636 case STRUCT:
637 for v := p.l.Front(); v != nil; v = v.Next() {
638 c <- v.Value.(TMapElem).Key()
639 }
640 close(c)
641 case LIST:
642 for v := p.l.Front(); v != nil; v = v.Next() {
643 c <- v.Value.(TMapElem).Key()
644 }
645 close(c)
646 case SET:
647 for v := p.l.Front(); v != nil; v = v.Next() {
648 c <- v.Value.(TMapElem).Key()
649 }
650 close(c)
651 default:
652 panic("Invalid Thrift type")
653 }
654}
655
656func (p *tMap) KeyIter() <-chan interface{} {
657 c := make(chan interface{})
658 go p.iterateKeys(c)
659 return c
660}
661
662// Iterate over all values; driver for range
663func (p *tMap) iterateValues(c chan<- interface{}) {
664 switch p.KeyType() {
665 case STOP, VOID:
666 close(c)
667 case BOOL:
668 for _, v := range p.b {
669 c <- v
670 }
671 close(c)
672 case BYTE:
673 for _, v := range p.i08 {
674 c <- v
675 }
676 close(c)
677 case I16:
678 for _, v := range p.i16 {
679 c <- v
680 }
681 close(c)
682 case I32:
683 for _, v := range p.i32 {
684 c <- v
685 }
686 close(c)
687 case I64:
688 for _, v := range p.i64 {
689 c <- v
690 }
691 close(c)
692 case DOUBLE:
693 for _, v := range p.f64 {
694 c <- v
695 }
696 close(c)
697 case STRING, UTF8, UTF16:
698 for _, v := range p.s {
699 c <- v
700 }
701 close(c)
702 case STRUCT:
703 for v := p.l.Front(); v != nil; v = v.Next() {
704 c <- v.Value.(TMapElem).Value()
705 }
706 close(c)
707 case LIST:
708 for v := p.l.Front(); v != nil; v = v.Next() {
709 c <- v.Value.(TMapElem).Value()
710 }
711 close(c)
712 case SET:
713 for v := p.l.Front(); v != nil; v = v.Next() {
714 c <- v.Value.(TMapElem).Value()
715 }
716 close(c)
717 default:
718 panic("Invalid Thrift type")
719 }
720}
721
722func (p *tMap) ValueIter() <-chan interface{} {
723 c := make(chan interface{})
724 go p.iterateValues(c)
725 return c
726}
727
728
729func (p *tMap) Less(other interface{}) bool {
730 cmp, ok := p.CompareTo(other)
731 return ok && cmp > 0
732}
733
734func (p *tMap) Equals(other interface{}) bool {
735 c, cok := p.CompareTo(other)
736 return cok && c == 0
737}
738
739func (p *tMap) CompareTo(other interface{}) (int, bool) {
740 return TType(MAP).Compare(p, other)
741}
742
743func (p *tMap) Keys() []interface{} {
744 size := p.Len()
745 values := make([]interface{}, size, size)
746 i := 0
747 for k := range p.KeyIter() {
748 values[i] = k
749 i++
750 }
751 return values
752}
753
754func (p *tMap) Values() []interface{} {
755 size := p.Len()
756 values := make([]interface{}, size, size)
757 i := 0
758 for v := range p.ValueIter() {
759 values[i] = v
760 i++
761 }
762 return values
763}