mapiter.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /*
  2. * Copyright 2021 ByteDance Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package encoder
  17. import (
  18. "encoding"
  19. "reflect"
  20. "sync"
  21. "unsafe"
  22. "github.com/bytedance/sonic/internal/native"
  23. "github.com/bytedance/sonic/internal/rt"
  24. )
  25. type _MapPair struct {
  26. k string // when the map key is integer, k is pointed to m
  27. v unsafe.Pointer
  28. m [32]byte
  29. }
  30. type _MapIterator struct {
  31. it rt.GoMapIterator // must be the first field
  32. kv rt.GoSlice // slice of _MapPair
  33. ki int
  34. }
  35. var (
  36. iteratorPool = sync.Pool{}
  37. iteratorPair = rt.UnpackType(reflect.TypeOf(_MapPair{}))
  38. )
  39. func init() {
  40. if unsafe.Offsetof(_MapIterator{}.it) != 0 {
  41. panic("_MapIterator.it is not the first field")
  42. }
  43. }
  44. func newIterator() *_MapIterator {
  45. if v := iteratorPool.Get(); v == nil {
  46. return new(_MapIterator)
  47. } else {
  48. return resetIterator(v.(*_MapIterator))
  49. }
  50. }
  51. func resetIterator(p *_MapIterator) *_MapIterator {
  52. p.ki = 0
  53. p.it = rt.GoMapIterator{}
  54. p.kv.Len = 0
  55. return p
  56. }
  57. func (self *_MapIterator) at(i int) *_MapPair {
  58. return (*_MapPair)(unsafe.Pointer(uintptr(self.kv.Ptr) + uintptr(i) * unsafe.Sizeof(_MapPair{})))
  59. }
  60. func (self *_MapIterator) add() (p *_MapPair) {
  61. p = self.at(self.kv.Len)
  62. self.kv.Len++
  63. return
  64. }
  65. func (self *_MapIterator) data() (p []_MapPair) {
  66. *(*rt.GoSlice)(unsafe.Pointer(&p)) = self.kv
  67. return
  68. }
  69. func (self *_MapIterator) append(t *rt.GoType, k unsafe.Pointer, v unsafe.Pointer) (err error) {
  70. p := self.add()
  71. p.v = v
  72. /* check for strings */
  73. if tk := t.Kind(); tk != reflect.String {
  74. return self.appendGeneric(p, t, tk, k)
  75. }
  76. /* fast path for strings */
  77. p.k = *(*string)(k)
  78. return nil
  79. }
  80. func (self *_MapIterator) appendGeneric(p *_MapPair, t *rt.GoType, v reflect.Kind, k unsafe.Pointer) error {
  81. switch v {
  82. case reflect.Int : p.k = rt.Mem2Str(p.m[:native.I64toa(&p.m[0], int64(*(*int)(k)))]) ; return nil
  83. case reflect.Int8 : p.k = rt.Mem2Str(p.m[:native.I64toa(&p.m[0], int64(*(*int8)(k)))]) ; return nil
  84. case reflect.Int16 : p.k = rt.Mem2Str(p.m[:native.I64toa(&p.m[0], int64(*(*int16)(k)))]) ; return nil
  85. case reflect.Int32 : p.k = rt.Mem2Str(p.m[:native.I64toa(&p.m[0], int64(*(*int32)(k)))]) ; return nil
  86. case reflect.Int64 : p.k = rt.Mem2Str(p.m[:native.I64toa(&p.m[0], *(*int64)(k))]) ; return nil
  87. case reflect.Uint : p.k = rt.Mem2Str(p.m[:native.U64toa(&p.m[0], uint64(*(*uint)(k)))]) ; return nil
  88. case reflect.Uint8 : p.k = rt.Mem2Str(p.m[:native.U64toa(&p.m[0], uint64(*(*uint8)(k)))]) ; return nil
  89. case reflect.Uint16 : p.k = rt.Mem2Str(p.m[:native.U64toa(&p.m[0], uint64(*(*uint16)(k)))]) ; return nil
  90. case reflect.Uint32 : p.k = rt.Mem2Str(p.m[:native.U64toa(&p.m[0], uint64(*(*uint32)(k)))]) ; return nil
  91. case reflect.Uint64 : p.k = rt.Mem2Str(p.m[:native.U64toa(&p.m[0], *(*uint64)(k))]) ; return nil
  92. case reflect.Uintptr : p.k = rt.Mem2Str(p.m[:native.U64toa(&p.m[0], uint64(*(*uintptr)(k)))]) ; return nil
  93. case reflect.Interface : return self.appendInterface(p, t, k)
  94. case reflect.Struct, reflect.Ptr : return self.appendConcrete(p, t, k)
  95. default : panic("unexpected map key type")
  96. }
  97. }
  98. func (self *_MapIterator) appendConcrete(p *_MapPair, t *rt.GoType, k unsafe.Pointer) (err error) {
  99. // compiler has already checked that the type implements the encoding.MarshalText interface
  100. if !t.Indirect() {
  101. k = *(*unsafe.Pointer)(k)
  102. }
  103. eface := rt.GoEface{Value: k, Type: t}.Pack()
  104. out, err := eface.(encoding.TextMarshaler).MarshalText()
  105. if err != nil {
  106. return err
  107. }
  108. p.k = rt.Mem2Str(out)
  109. return
  110. }
  111. func (self *_MapIterator) appendInterface(p *_MapPair, t *rt.GoType, k unsafe.Pointer) (err error) {
  112. if len(rt.IfaceType(t).Methods) == 0 {
  113. panic("unexpected map key type")
  114. } else if p.k, err = asText(k); err == nil {
  115. return nil
  116. } else {
  117. return
  118. }
  119. }
  120. func iteratorStop(p *_MapIterator) {
  121. iteratorPool.Put(p)
  122. }
  123. func iteratorNext(p *_MapIterator) {
  124. i := p.ki
  125. t := &p.it
  126. /* check for unordered iteration */
  127. if i < 0 {
  128. mapiternext(t)
  129. return
  130. }
  131. /* check for end of iteration */
  132. if p.ki >= p.kv.Len {
  133. t.K = nil
  134. t.V = nil
  135. return
  136. }
  137. /* update the key-value pair, and increase the pointer */
  138. t.K = unsafe.Pointer(&p.at(p.ki).k)
  139. t.V = p.at(p.ki).v
  140. p.ki++
  141. }
  142. func iteratorStart(t *rt.GoMapType, m *rt.GoMap, fv uint64) (*_MapIterator, error) {
  143. it := newIterator()
  144. mapiterinit(t, m, &it.it)
  145. /* check for key-sorting, empty map don't need sorting */
  146. if m.Count == 0 || (fv & uint64(SortMapKeys)) == 0 {
  147. it.ki = -1
  148. return it, nil
  149. }
  150. /* pre-allocate space if needed */
  151. if m.Count > it.kv.Cap {
  152. it.kv = growslice(iteratorPair, it.kv, m.Count)
  153. }
  154. /* dump all the key-value pairs */
  155. for ; it.it.K != nil; mapiternext(&it.it) {
  156. if err := it.append(t.Key, it.it.K, it.it.V); err != nil {
  157. iteratorStop(it)
  158. return nil, err
  159. }
  160. }
  161. /* sort the keys, map with only 1 item don't need sorting */
  162. if it.ki = 1; m.Count > 1 {
  163. radixQsort(it.data(), 0, maxDepth(it.kv.Len))
  164. }
  165. /* load the first pair into iterator */
  166. it.it.V = it.at(0).v
  167. it.it.K = unsafe.Pointer(&it.at(0).k)
  168. return it, nil
  169. }