| /* | 
 |  * Licensed to the Apache Software Foundation (ASF) under one | 
 |  * or more contributor license agreements. See the NOTICE file | 
 |  * distributed with this work for additional information | 
 |  * regarding copyright ownership. The ASF licenses this file | 
 |  * to you 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 thrift | 
 |  | 
 | import ( | 
 |   "container/list" | 
 |   "reflect" | 
 | ) | 
 |  | 
 | /** | 
 |  * Helper class that encapsulates map metadata. | 
 |  * | 
 |  */ | 
 | type TMap interface { | 
 |   KeyType() TType | 
 |   ValueType() TType | 
 |   Len() int | 
 |   Set(key, value interface{}) | 
 |   Get(key interface{}) (interface{}, bool) | 
 |   Contains(key interface{}) bool | 
 |   Iter() <-chan TMapElem | 
 |   KeyIter() <-chan interface{} | 
 |   ValueIter() <-chan interface{} | 
 |   Keys() []interface{} | 
 |   Values() []interface{} | 
 |   Less(other interface{}) bool | 
 |   Equals(other interface{}) bool | 
 |   CompareTo(other interface{}) (int, bool) | 
 | } | 
 |  | 
 | type TMapElem interface { | 
 |   Key() interface{} | 
 |   Value() interface{} | 
 | } | 
 |  | 
 | type tMap struct { | 
 |   keyType   TType | 
 |   valueType TType | 
 |   size      int | 
 |   l         *list.List | 
 |   b         map[bool]interface{} | 
 |   i08       map[byte]interface{} | 
 |   i16       map[int16]interface{} | 
 |   i32       map[int32]interface{} | 
 |   i64       map[int64]interface{} | 
 |   f64       map[float64]interface{} | 
 |   s         map[string]interface{} | 
 | } | 
 |  | 
 | type tMapElem struct { | 
 |   key   interface{} | 
 |   value interface{} | 
 | } | 
 |  | 
 | func (p *tMapElem) Key() interface{} { | 
 |   return p.key | 
 | } | 
 |  | 
 | func (p *tMapElem) Value() interface{} { | 
 |   return p.value | 
 | } | 
 |  | 
 | func NewTMapElem(k, v interface{}) TMapElem { | 
 |   return &tMapElem{key: k, value: v} | 
 | } | 
 |  | 
 | func NewTMap(k, v TType, s int) TMap { | 
 |   return &tMap{keyType: k, valueType: v, size: s, l: list.New()} | 
 | } | 
 |  | 
 | func NewTMapDefault() TMap { | 
 |   return NewTMap(STOP, STOP, 0) | 
 | } | 
 |  | 
 | func (p *tMap) KeyType() TType { | 
 |   return p.keyType | 
 | } | 
 |  | 
 | func (p *tMap) ValueType() TType { | 
 |   return p.valueType | 
 | } | 
 |  | 
 | func (p *tMap) Len() int { | 
 |   if p.l.Len() != 0 { | 
 |     return p.l.Len() | 
 |   } | 
 |   switch p.KeyType() { | 
 |   case STOP, VOID: | 
 |     return 0 | 
 |   case BOOL: | 
 |     return len(p.b) | 
 |   case BYTE: | 
 |     return len(p.i08) | 
 |   case I16: | 
 |     return len(p.i16) | 
 |   case I32: | 
 |     return len(p.i32) | 
 |   case I64: | 
 |     return len(p.i64) | 
 |   case DOUBLE: | 
 |     return len(p.f64) | 
 |   case STRING, UTF8, UTF16: | 
 |     return len(p.s) | 
 |   default: | 
 |     return p.size | 
 |   } | 
 |   return p.size | 
 | } | 
 |  | 
 | func (p *tMap) Get(key interface{}) (interface{}, bool) { | 
 |   if p.KeyType().IsEmptyType() { | 
 |     return nil, false | 
 |   } | 
 |   if key == nil { | 
 |     for elem := p.l.Front(); elem != nil; elem = elem.Next() { | 
 |       e := elem.Value.(TMapElem) | 
 |       k := e.Key() | 
 |       if k == nil { | 
 |         return e.Value(), true | 
 |       } | 
 |     } | 
 |     return nil, false | 
 |   } | 
 |   useKey, ok := p.KeyType().CoerceData(key) | 
 |   if !ok { | 
 |     return nil, false | 
 |   } | 
 |   switch p.KeyType() { | 
 |   case STOP, VOID: | 
 |     // if here, then we don't have a key type yet and key is not nil | 
 |     // so this is pretty much an empty map | 
 |     return nil, false | 
 |   case BOOL: | 
 |     m := p.b | 
 |     if m == nil { | 
 |       return nil, false | 
 |     } | 
 |     if v, ok := m[useKey.(bool)]; ok { | 
 |       return v, true | 
 |     } | 
 |     return nil, true | 
 |   case BYTE: | 
 |     m := p.i08 | 
 |     if v, ok := m[useKey.(byte)]; ok { | 
 |       return v, true | 
 |     } | 
 |     return nil, false | 
 |   case DOUBLE: | 
 |     m := p.f64 | 
 |     if m == nil { | 
 |       return nil, false | 
 |     } | 
 |     if v, ok := m[useKey.(float64)]; ok { | 
 |       return v, true | 
 |     } | 
 |     return nil, false | 
 |   case I16: | 
 |     m := p.i16 | 
 |     if m == nil { | 
 |       return nil, false | 
 |     } | 
 |     if v, ok := m[useKey.(int16)]; ok { | 
 |       return v, true | 
 |     } | 
 |     return nil, false | 
 |   case I32: | 
 |     m := p.i32 | 
 |     if m == nil { | 
 |       return nil, false | 
 |     } | 
 |     if v, ok := m[useKey.(int32)]; ok { | 
 |       return v, true | 
 |     } | 
 |     return nil, false | 
 |   case I64: | 
 |     m := p.i64 | 
 |     if m == nil { | 
 |       return nil, false | 
 |     } | 
 |     if v, ok := m[useKey.(int64)]; ok { | 
 |       return v, true | 
 |     } | 
 |     return nil, false | 
 |   case STRING, UTF8, UTF16: | 
 |     // TODO(pomack) properly handle ENUM | 
 |     m := p.s | 
 |     if m == nil { | 
 |       return nil, false | 
 |     } | 
 |     if v, ok := m[useKey.(string)]; ok { | 
 |       return v, true | 
 |     } | 
 |     return nil, false | 
 |   case STRUCT: | 
 |     for elem := p.l.Front(); elem != nil; elem = elem.Next() { | 
 |       e := elem.Value.(TMapElem) | 
 |       k := e.Key() | 
 |       if k == nil { | 
 |         continue | 
 |       } | 
 |       structkey, ok := k.(TStruct) | 
 |       if ok { | 
 |         if structkey.Equals(useKey.(TStruct)) { | 
 |           return e.Value(), true | 
 |         } | 
 |         continue | 
 |       } | 
 |       if reflect.DeepEqual(useKey, k) { | 
 |         return e.Value(), true | 
 |       } | 
 |     } | 
 |     return nil, false | 
 |   case MAP: | 
 |     for elem := p.l.Front(); elem != nil; elem = elem.Next() { | 
 |       e := elem.Value.(TMapElem) | 
 |       k := e.Key() | 
 |       if k == nil { | 
 |         continue | 
 |       } | 
 |       mapkey, ok := k.(TMap) | 
 |       if ok { | 
 |         if mapkey.Equals(useKey.(TMap)) { | 
 |           return e.Value(), true | 
 |         } | 
 |         continue | 
 |       } | 
 |       if reflect.DeepEqual(useKey, k) { | 
 |         return e.Value(), true | 
 |       } | 
 |     } | 
 |     return nil, false | 
 |   case SET: | 
 |     for elem := p.l.Front(); elem != nil; elem = elem.Next() { | 
 |       e := elem.Value.(TMapElem) | 
 |       k := e.Key() | 
 |       if k == nil { | 
 |         continue | 
 |       } | 
 |       setkey, ok := k.(TSet) | 
 |       if ok { | 
 |         if setkey.Equals(useKey.(TSet)) { | 
 |           return e.Value(), true | 
 |         } | 
 |         continue | 
 |       } | 
 |       if reflect.DeepEqual(useKey, k) { | 
 |         return e.Value(), true | 
 |       } | 
 |     } | 
 |     return nil, false | 
 |   case LIST: | 
 |     for elem := p.l.Front(); elem != nil; elem = elem.Next() { | 
 |       e := elem.Value.(TMapElem) | 
 |       k := e.Key() | 
 |       if k == nil { | 
 |         continue | 
 |       } | 
 |       listkey, ok := k.(TList) | 
 |       if ok { | 
 |         if listkey.Equals(useKey.(TList)) { | 
 |           return e.Value(), true | 
 |         } | 
 |         continue | 
 |       } | 
 |       if reflect.DeepEqual(useKey, k) { | 
 |         return e.Value(), true | 
 |       } | 
 |     } | 
 |     return nil, false | 
 |   default: | 
 |     panic("Invalid Thrift element type") | 
 |   } | 
 |   return nil, false | 
 | } | 
 |  | 
 |  | 
 | func (p *tMap) Set(key, value interface{}) { | 
 |   if p.KeyType() == STOP || p.KeyType() == VOID { | 
 |     p.keyType = TypeFromValue(key) | 
 |   } | 
 |   coercedKey, ok := p.KeyType().CoerceData(key) | 
 |   if !ok { | 
 |     return | 
 |   } | 
 |   if p.ValueType() == STOP || p.ValueType() == VOID { | 
 |     p.valueType = TypeFromValue(value) | 
 |   } | 
 |   coercedValue, ok := p.ValueType().CoerceData(value) | 
 |   if !ok { | 
 |     return | 
 |   } | 
 |   newElem := NewTMapElem(coercedKey, coercedValue) | 
 |   if !p.KeyType().IsBaseType() { | 
 |     for elem := p.l.Front(); elem != nil; elem = elem.Next() { | 
 |       k := elem.Value.(TMapElem).Key() | 
 |       if cmp, ok := p.KeyType().Compare(coercedKey, k); ok && cmp >= 0 { | 
 |         if cmp == 0 { | 
 |           p.l.InsertAfter(newElem, elem) | 
 |           p.l.Remove(elem) | 
 |           return | 
 |         } | 
 |         p.l.InsertBefore(newElem, elem) | 
 |         return | 
 |       } | 
 |     } | 
 |     p.l.PushBack(newElem) | 
 |     return | 
 |   } | 
 |   if key == nil { | 
 |     return | 
 |   } | 
 |   switch p.KeyType() { | 
 |   case STOP, VOID: | 
 |     // if here, then we don't have a key type yet and key is not nil | 
 |     // so this is pretty much an empty map | 
 |     return | 
 |   case BOOL: | 
 |     if p.b == nil { | 
 |       p.b = make(map[bool]interface{}) | 
 |     } | 
 |     b := coercedKey.(bool) | 
 |     p.b[b] = value | 
 |   case BYTE: | 
 |     if p.i08 == nil { | 
 |       p.i08 = make(map[byte]interface{}) | 
 |     } | 
 |     b := coercedKey.(byte) | 
 |     p.i08[b] = value | 
 |   case DOUBLE: | 
 |     if p.f64 == nil { | 
 |       p.f64 = make(map[float64]interface{}) | 
 |     } | 
 |     b := coercedKey.(float64) | 
 |     p.f64[b] = value | 
 |   case I16: | 
 |     if p.i16 == nil { | 
 |       p.i16 = make(map[int16]interface{}) | 
 |     } | 
 |     b := coercedKey.(int16) | 
 |     p.i16[b] = value | 
 |   case I32: | 
 |     if p.i32 == nil { | 
 |       p.i32 = make(map[int32]interface{}) | 
 |     } | 
 |     b := coercedKey.(int32) | 
 |     p.i32[b] = value | 
 |   case I64: | 
 |     if p.i64 == nil { | 
 |       p.i64 = make(map[int64]interface{}) | 
 |     } | 
 |     b := coercedKey.(int64) | 
 |     p.i64[b] = value | 
 |   case STRING, UTF8, UTF16: | 
 |     if p.s == nil { | 
 |       p.s = make(map[string]interface{}) | 
 |     } | 
 |     b := coercedKey.(string) | 
 |     p.s[b] = value | 
 |   case STRUCT, MAP, SET, LIST: | 
 |     panic("Should never be here") | 
 |   default: | 
 |     panic("Should never be here") | 
 |   } | 
 | } | 
 |  | 
 | func (p *tMap) Contains(key interface{}) bool { | 
 |   coercedKey, ok := p.KeyType().CoerceData(key) | 
 |   if !ok { | 
 |     return false | 
 |   } | 
 |   if coercedKey == nil { | 
 |     for elem := p.l.Front(); elem != nil; elem = elem.Next() { | 
 |       k := elem.Value.(TMapElem).Key() | 
 |       if k == nil { | 
 |         return true | 
 |       } | 
 |     } | 
 |     return false | 
 |   } | 
 |   if !ok { | 
 |     return false | 
 |   } | 
 |   switch p.KeyType() { | 
 |   case STOP: | 
 |     // if here, then we don't have a key type yet and key is not nil | 
 |     // so this is pretty much an empty map | 
 |     return false | 
 |   case VOID: | 
 |     // if here, then we don't have a key type yet and key is not nil | 
 |     // so this is pretty much an empty map | 
 |     return false | 
 |   case BOOL: | 
 |     m := p.b | 
 |     if m == nil { | 
 |       return false | 
 |     } | 
 |     _, ok := m[coercedKey.(bool)] | 
 |     return ok | 
 |   case BYTE: | 
 |     m := p.i08 | 
 |     _, ok := m[coercedKey.(byte)] | 
 |     return ok | 
 |   case DOUBLE: | 
 |     m := p.f64 | 
 |     if m == nil { | 
 |       return false | 
 |     } | 
 |     _, ok := m[coercedKey.(float64)] | 
 |     return ok | 
 |   case I16: | 
 |     m := p.i16 | 
 |     if m == nil { | 
 |       return false | 
 |     } | 
 |     _, ok := m[coercedKey.(int16)] | 
 |     return ok | 
 |   case I32: | 
 |     m := p.i32 | 
 |     if m == nil { | 
 |       return false | 
 |     } | 
 |     _, ok := m[coercedKey.(int32)] | 
 |     return ok | 
 |   case I64: | 
 |     m := p.i64 | 
 |     if m == nil { | 
 |       return false | 
 |     } | 
 |     _, ok := m[coercedKey.(int64)] | 
 |     return ok | 
 |   case STRING, UTF8, UTF16: | 
 |     // TODO(pomack) properly handle ENUM | 
 |     m := p.s | 
 |     if m == nil { | 
 |       return false | 
 |     } | 
 |     _, ok := m[coercedKey.(string)] | 
 |     return ok | 
 |   case STRUCT: | 
 |     for elem := p.l.Front(); elem != nil; elem = elem.Next() { | 
 |       e := elem.Value.(TMapElem) | 
 |       k := e.Key() | 
 |       if k == nil { | 
 |         continue | 
 |       } | 
 |       structkey, ok := k.(TStruct) | 
 |       if ok { | 
 |         if structkey.Equals(coercedKey.(TStruct)) { | 
 |           return true | 
 |         } | 
 |         continue | 
 |       } | 
 |       if reflect.DeepEqual(coercedKey, k) { | 
 |         return true | 
 |       } | 
 |     } | 
 |     return false | 
 |   case MAP: | 
 |     for elem := p.l.Front(); elem != nil; elem = elem.Next() { | 
 |       e := elem.Value.(TMapElem) | 
 |       k := e.Key() | 
 |       if k == nil { | 
 |         continue | 
 |       } | 
 |       mapkey, ok := k.(TMap) | 
 |       if ok { | 
 |         if mapkey.Equals(coercedKey.(TMap)) { | 
 |           return true | 
 |         } | 
 |         continue | 
 |       } | 
 |     } | 
 |     return false | 
 |   case SET: | 
 |     for elem := p.l.Front(); elem != nil; elem = elem.Next() { | 
 |       e := elem.Value.(TMapElem) | 
 |       k := e.Key() | 
 |       if k == nil { | 
 |         continue | 
 |       } | 
 |       setkey, ok := k.(TSet) | 
 |       if ok { | 
 |         if setkey.Equals(coercedKey.(TSet)) { | 
 |           return true | 
 |         } | 
 |         continue | 
 |       } | 
 |     } | 
 |     return false | 
 |   case LIST: | 
 |     for elem := p.l.Front(); elem != nil; elem = elem.Next() { | 
 |       e := elem.Value.(TMapElem) | 
 |       k := e.Key() | 
 |       if k == nil { | 
 |         continue | 
 |       } | 
 |       listkey, ok := k.(TList) | 
 |       if ok { | 
 |         if listkey.Equals(coercedKey.(TList)) { | 
 |           return true | 
 |         } | 
 |         continue | 
 |       } | 
 |     } | 
 |     return false | 
 |   default: | 
 |     panic("Invalid Thrift element type") | 
 |   } | 
 |   return false | 
 | } | 
 |  | 
 | // Iterate over all elements; driver for range | 
 | func (p *tMap) iterate(c chan<- TMapElem) { | 
 |   switch p.KeyType() { | 
 |   case STOP, VOID: | 
 |     close(c) | 
 |   case BOOL: | 
 |     for k, v := range p.b { | 
 |       c <- NewTMapElem(k, v) | 
 |     } | 
 |     close(c) | 
 |   case BYTE: | 
 |     for k, v := range p.i08 { | 
 |       c <- NewTMapElem(k, v) | 
 |     } | 
 |     close(c) | 
 |   case I16: | 
 |     for k, v := range p.i16 { | 
 |       c <- NewTMapElem(k, v) | 
 |     } | 
 |     close(c) | 
 |   case I32: | 
 |     for k, v := range p.i32 { | 
 |       c <- NewTMapElem(k, v) | 
 |     } | 
 |     close(c) | 
 |   case I64: | 
 |     for k, v := range p.i64 { | 
 |       c <- NewTMapElem(k, v) | 
 |     } | 
 |     close(c) | 
 |   case DOUBLE: | 
 |     for k, v := range p.f64 { | 
 |       c <- NewTMapElem(k, v) | 
 |     } | 
 |     close(c) | 
 |   case STRING, UTF8, UTF16: | 
 |     for k, v := range p.s { | 
 |       c <- NewTMapElem(k, v) | 
 |     } | 
 |     close(c) | 
 |   case STRUCT: | 
 |     for v := p.l.Front(); v != nil; v = v.Next() { | 
 |       c <- v.Value.(TMapElem) | 
 |     } | 
 |     close(c) | 
 |   case LIST: | 
 |     for v := p.l.Front(); v != nil; v = v.Next() { | 
 |       c <- v.Value.(TMapElem) | 
 |     } | 
 |     close(c) | 
 |   case SET: | 
 |     for v := p.l.Front(); v != nil; v = v.Next() { | 
 |       c <- v.Value.(TMapElem) | 
 |     } | 
 |     close(c) | 
 |   default: | 
 |     panic("Invalid Thrift type") | 
 |   } | 
 | } | 
 |  | 
 | // Channel iterator for range. | 
 | func (p *tMap) Iter() <-chan TMapElem { | 
 |   c := make(chan TMapElem) | 
 |   go p.iterate(c) | 
 |   return c | 
 | } | 
 |  | 
 | // Iterate over all keys; driver for range | 
 | func (p *tMap) iterateKeys(c chan<- interface{}) { | 
 |   switch p.KeyType() { | 
 |   case STOP, VOID: | 
 |     close(c) | 
 |   case BOOL: | 
 |     for k, _ := range p.b { | 
 |       c <- k | 
 |     } | 
 |     close(c) | 
 |   case BYTE: | 
 |     for k, _ := range p.i08 { | 
 |       c <- k | 
 |     } | 
 |     close(c) | 
 |   case I16: | 
 |     for k, _ := range p.i16 { | 
 |       c <- k | 
 |     } | 
 |     close(c) | 
 |   case I32: | 
 |     for k, _ := range p.i32 { | 
 |       c <- k | 
 |     } | 
 |     close(c) | 
 |   case I64: | 
 |     for k, _ := range p.i64 { | 
 |       c <- k | 
 |     } | 
 |     close(c) | 
 |   case DOUBLE: | 
 |     for k, _ := range p.f64 { | 
 |       c <- k | 
 |     } | 
 |     close(c) | 
 |   case STRING, UTF8, UTF16: | 
 |     for k, _ := range p.s { | 
 |       c <- k | 
 |     } | 
 |     close(c) | 
 |   case STRUCT: | 
 |     for v := p.l.Front(); v != nil; v = v.Next() { | 
 |       c <- v.Value.(TMapElem).Key() | 
 |     } | 
 |     close(c) | 
 |   case LIST: | 
 |     for v := p.l.Front(); v != nil; v = v.Next() { | 
 |       c <- v.Value.(TMapElem).Key() | 
 |     } | 
 |     close(c) | 
 |   case SET: | 
 |     for v := p.l.Front(); v != nil; v = v.Next() { | 
 |       c <- v.Value.(TMapElem).Key() | 
 |     } | 
 |     close(c) | 
 |   default: | 
 |     panic("Invalid Thrift type") | 
 |   } | 
 | } | 
 |  | 
 | func (p *tMap) KeyIter() <-chan interface{} { | 
 |   c := make(chan interface{}) | 
 |   go p.iterateKeys(c) | 
 |   return c | 
 | } | 
 |  | 
 | // Iterate over all values; driver for range | 
 | func (p *tMap) iterateValues(c chan<- interface{}) { | 
 |   switch p.KeyType() { | 
 |   case STOP, VOID: | 
 |     close(c) | 
 |   case BOOL: | 
 |     for _, v := range p.b { | 
 |       c <- v | 
 |     } | 
 |     close(c) | 
 |   case BYTE: | 
 |     for _, v := range p.i08 { | 
 |       c <- v | 
 |     } | 
 |     close(c) | 
 |   case I16: | 
 |     for _, v := range p.i16 { | 
 |       c <- v | 
 |     } | 
 |     close(c) | 
 |   case I32: | 
 |     for _, v := range p.i32 { | 
 |       c <- v | 
 |     } | 
 |     close(c) | 
 |   case I64: | 
 |     for _, v := range p.i64 { | 
 |       c <- v | 
 |     } | 
 |     close(c) | 
 |   case DOUBLE: | 
 |     for _, v := range p.f64 { | 
 |       c <- v | 
 |     } | 
 |     close(c) | 
 |   case STRING, UTF8, UTF16: | 
 |     for _, v := range p.s { | 
 |       c <- v | 
 |     } | 
 |     close(c) | 
 |   case STRUCT: | 
 |     for v := p.l.Front(); v != nil; v = v.Next() { | 
 |       c <- v.Value.(TMapElem).Value() | 
 |     } | 
 |     close(c) | 
 |   case LIST: | 
 |     for v := p.l.Front(); v != nil; v = v.Next() { | 
 |       c <- v.Value.(TMapElem).Value() | 
 |     } | 
 |     close(c) | 
 |   case SET: | 
 |     for v := p.l.Front(); v != nil; v = v.Next() { | 
 |       c <- v.Value.(TMapElem).Value() | 
 |     } | 
 |     close(c) | 
 |   default: | 
 |     panic("Invalid Thrift type") | 
 |   } | 
 | } | 
 |  | 
 | func (p *tMap) ValueIter() <-chan interface{} { | 
 |   c := make(chan interface{}) | 
 |   go p.iterateValues(c) | 
 |   return c | 
 | } | 
 |  | 
 |  | 
 | func (p *tMap) Less(other interface{}) bool { | 
 |   cmp, ok := p.CompareTo(other) | 
 |   return ok && cmp > 0 | 
 | } | 
 |  | 
 | func (p *tMap) Equals(other interface{}) bool { | 
 |   c, cok := p.CompareTo(other) | 
 |   return cok && c == 0 | 
 | } | 
 |  | 
 | func (p *tMap) CompareTo(other interface{}) (int, bool) { | 
 |   return TType(MAP).Compare(p, other) | 
 | } | 
 |  | 
 | func (p *tMap) Keys() []interface{} { | 
 |   size := p.Len() | 
 |   values := make([]interface{}, size, size) | 
 |   i := 0 | 
 |   for k := range p.KeyIter() { | 
 |     values[i] = k | 
 |     i++ | 
 |   } | 
 |   return values | 
 | } | 
 |  | 
 | func (p *tMap) Values() []interface{} { | 
 |   size := p.Len() | 
 |   values := make([]interface{}, size, size) | 
 |   i := 0 | 
 |   for v := range p.ValueIter() { | 
 |     values[i] = v | 
 |     i++ | 
 |   } | 
 |   return values | 
 | } |