serialize.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*
  2. Copyright 2019 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package fieldpath
  14. import (
  15. "bytes"
  16. "io"
  17. "unsafe"
  18. jsoniter "github.com/json-iterator/go"
  19. )
  20. func (s *Set) ToJSON() ([]byte, error) {
  21. buf := bytes.Buffer{}
  22. err := s.ToJSONStream(&buf)
  23. if err != nil {
  24. return nil, err
  25. }
  26. return buf.Bytes(), nil
  27. }
  28. func (s *Set) ToJSONStream(w io.Writer) error {
  29. stream := writePool.BorrowStream(w)
  30. defer writePool.ReturnStream(stream)
  31. var r reusableBuilder
  32. stream.WriteObjectStart()
  33. err := s.emitContentsV1(false, stream, &r)
  34. if err != nil {
  35. return err
  36. }
  37. stream.WriteObjectEnd()
  38. return stream.Flush()
  39. }
  40. func manageMemory(stream *jsoniter.Stream) error {
  41. // Help jsoniter manage its buffers--without this, it does a bunch of
  42. // alloctaions that are not necessary. They were probably optimizing
  43. // for folks using the buffer directly.
  44. b := stream.Buffer()
  45. if len(b) > 4096 || cap(b)-len(b) < 2048 {
  46. if err := stream.Flush(); err != nil {
  47. return err
  48. }
  49. stream.SetBuffer(b[:0])
  50. }
  51. return nil
  52. }
  53. type reusableBuilder struct {
  54. bytes.Buffer
  55. }
  56. func (r *reusableBuilder) unsafeString() string {
  57. b := r.Bytes()
  58. return *(*string)(unsafe.Pointer(&b))
  59. }
  60. func (r *reusableBuilder) reset() *bytes.Buffer {
  61. r.Reset()
  62. return &r.Buffer
  63. }
  64. func (s *Set) emitContentsV1(includeSelf bool, stream *jsoniter.Stream, r *reusableBuilder) error {
  65. mi, ci := 0, 0
  66. first := true
  67. preWrite := func() {
  68. if first {
  69. first = false
  70. return
  71. }
  72. stream.WriteMore()
  73. }
  74. if includeSelf && !(len(s.Members.members) == 0 && len(s.Children.members) == 0) {
  75. preWrite()
  76. stream.WriteObjectField(".")
  77. stream.WriteEmptyObject()
  78. }
  79. for mi < len(s.Members.members) && ci < len(s.Children.members) {
  80. mpe := s.Members.members[mi]
  81. cpe := s.Children.members[ci].pathElement
  82. if c := mpe.Compare(cpe); c < 0 {
  83. preWrite()
  84. if err := serializePathElementToWriter(r.reset(), mpe); err != nil {
  85. return err
  86. }
  87. stream.WriteObjectField(r.unsafeString())
  88. stream.WriteEmptyObject()
  89. mi++
  90. } else if c > 0 {
  91. preWrite()
  92. if err := serializePathElementToWriter(r.reset(), cpe); err != nil {
  93. return err
  94. }
  95. stream.WriteObjectField(r.unsafeString())
  96. stream.WriteObjectStart()
  97. if err := s.Children.members[ci].set.emitContentsV1(false, stream, r); err != nil {
  98. return err
  99. }
  100. stream.WriteObjectEnd()
  101. ci++
  102. } else {
  103. preWrite()
  104. if err := serializePathElementToWriter(r.reset(), cpe); err != nil {
  105. return err
  106. }
  107. stream.WriteObjectField(r.unsafeString())
  108. stream.WriteObjectStart()
  109. if err := s.Children.members[ci].set.emitContentsV1(true, stream, r); err != nil {
  110. return err
  111. }
  112. stream.WriteObjectEnd()
  113. mi++
  114. ci++
  115. }
  116. }
  117. for mi < len(s.Members.members) {
  118. mpe := s.Members.members[mi]
  119. preWrite()
  120. if err := serializePathElementToWriter(r.reset(), mpe); err != nil {
  121. return err
  122. }
  123. stream.WriteObjectField(r.unsafeString())
  124. stream.WriteEmptyObject()
  125. mi++
  126. }
  127. for ci < len(s.Children.members) {
  128. cpe := s.Children.members[ci].pathElement
  129. preWrite()
  130. if err := serializePathElementToWriter(r.reset(), cpe); err != nil {
  131. return err
  132. }
  133. stream.WriteObjectField(r.unsafeString())
  134. stream.WriteObjectStart()
  135. if err := s.Children.members[ci].set.emitContentsV1(false, stream, r); err != nil {
  136. return err
  137. }
  138. stream.WriteObjectEnd()
  139. ci++
  140. }
  141. return manageMemory(stream)
  142. }
  143. // FromJSON clears s and reads a JSON formatted set structure.
  144. func (s *Set) FromJSON(r io.Reader) error {
  145. // The iterator pool is completely useless for memory management, grrr.
  146. iter := jsoniter.Parse(jsoniter.ConfigCompatibleWithStandardLibrary, r, 4096)
  147. found, _ := readIterV1(iter)
  148. if found == nil {
  149. *s = Set{}
  150. } else {
  151. *s = *found
  152. }
  153. return iter.Error
  154. }
  155. // returns true if this subtree is also (or only) a member of parent; s is nil
  156. // if there are no further children.
  157. func readIterV1(iter *jsoniter.Iterator) (children *Set, isMember bool) {
  158. iter.ReadMapCB(func(iter *jsoniter.Iterator, key string) bool {
  159. if key == "." {
  160. isMember = true
  161. iter.Skip()
  162. return true
  163. }
  164. pe, err := DeserializePathElement(key)
  165. if err == ErrUnknownPathElementType {
  166. // Ignore these-- a future version maybe knows what
  167. // they are. We drop these completely rather than try
  168. // to preserve things we don't understand.
  169. iter.Skip()
  170. return true
  171. } else if err != nil {
  172. iter.ReportError("parsing key as path element", err.Error())
  173. iter.Skip()
  174. return true
  175. }
  176. grandchildren, childIsMember := readIterV1(iter)
  177. if childIsMember {
  178. if children == nil {
  179. children = &Set{}
  180. }
  181. m := &children.Members.members
  182. // Since we expect that most of the time these will have been
  183. // serialized in the right order, we just verify that and append.
  184. appendOK := len(*m) == 0 || (*m)[len(*m)-1].Less(pe)
  185. if appendOK {
  186. *m = append(*m, pe)
  187. } else {
  188. children.Members.Insert(pe)
  189. }
  190. }
  191. if grandchildren != nil {
  192. if children == nil {
  193. children = &Set{}
  194. }
  195. // Since we expect that most of the time these will have been
  196. // serialized in the right order, we just verify that and append.
  197. m := &children.Children.members
  198. appendOK := len(*m) == 0 || (*m)[len(*m)-1].pathElement.Less(pe)
  199. if appendOK {
  200. *m = append(*m, setNode{pe, grandchildren})
  201. } else {
  202. *children.Children.Descend(pe) = *grandchildren
  203. }
  204. }
  205. return true
  206. })
  207. if children == nil {
  208. isMember = true
  209. }
  210. return children, isMember
  211. }