Skip to content

Commit a7048de

Browse files
committed
migrate github.com/json-iterator/go to encoding/json/v2
Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com>
1 parent 3392408 commit a7048de

File tree

6 files changed

+306
-286
lines changed

6 files changed

+306
-286
lines changed

fieldpath/serialize-pe.go

Lines changed: 58 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -17,103 +17,70 @@ limitations under the License.
1717
package fieldpath
1818

1919
import (
20+
"bytes"
2021
"errors"
2122
"fmt"
22-
"io"
2323
"strconv"
2424
"strings"
2525

26-
jsoniter "github.com/json-iterator/go"
26+
"github.com/go-json-experiment/json"
2727
"sigs.k8s.io/structured-merge-diff/v6/value"
2828
)
2929

3030
var ErrUnknownPathElementType = errors.New("unknown path element type")
3131

3232
const (
3333
// Field indicates that the content of this path element is a field's name
34-
peField = "f"
34+
peField = 'f'
3535

3636
// Value indicates that the content of this path element is a field's value
37-
peValue = "v"
37+
peValue = 'v'
3838

3939
// Index indicates that the content of this path element is an index in an array
40-
peIndex = "i"
40+
peIndex = 'i'
4141

4242
// Key indicates that the content of this path element is a key value map
43-
peKey = "k"
43+
peKey = 'k'
4444

4545
// Separator separates the type of a path element from the contents
46-
peSeparator = ":"
46+
peSeparator = ':'
4747
)
4848

4949
var (
50-
peFieldSepBytes = []byte(peField + peSeparator)
51-
peValueSepBytes = []byte(peValue + peSeparator)
52-
peIndexSepBytes = []byte(peIndex + peSeparator)
53-
peKeySepBytes = []byte(peKey + peSeparator)
54-
peSepBytes = []byte(peSeparator)
50+
peFieldSepBytes = []byte{peField, peSeparator}
51+
peValueSepBytes = []byte{peValue, peSeparator}
52+
peIndexSepBytes = []byte{peIndex, peSeparator}
53+
peKeySepBytes = []byte{peKey, peSeparator}
5554
)
5655

57-
// readJSONIter reads a Value from a JSON iterator.
58-
// DO NOT EXPORT
59-
// TODO: eliminate this https://github.com/kubernetes-sigs/structured-merge-diff/issues/202
60-
func readJSONIter(iter *jsoniter.Iterator) (value.Value, error) {
61-
v := iter.Read()
62-
if iter.Error != nil && iter.Error != io.EOF {
63-
return nil, iter.Error
64-
}
65-
return value.NewValueInterface(v), nil
66-
}
67-
68-
// writeJSONStream writes a value into a JSON stream.
69-
// DO NOT EXPORT
70-
// TODO: eliminate this https://github.com/kubernetes-sigs/structured-merge-diff/issues/202
71-
func writeJSONStream(v value.Value, stream *jsoniter.Stream) {
72-
stream.WriteVal(v.Unstructured())
73-
}
74-
7556
// DeserializePathElement parses a serialized path element
7657
func DeserializePathElement(s string) (PathElement, error) {
77-
b := []byte(s)
78-
if len(b) < 2 {
79-
return PathElement{}, errors.New("key must be 2 characters long:")
58+
if len(s) < 2 {
59+
return PathElement{}, errors.New("key must be 2 characters long")
8060
}
81-
typeSep, b := b[:2], b[2:]
82-
if typeSep[1] != peSepBytes[0] {
61+
typeSep0, typeSep1 := s[0], s[1]
62+
if typeSep1 != peSeparator {
8363
return PathElement{}, fmt.Errorf("missing colon: %v", s)
8464
}
85-
switch typeSep[0] {
65+
switch typeSep0 {
8666
case peFieldSepBytes[0]:
87-
// Slice s rather than convert b, to save on
88-
// allocations.
8967
str := s[2:]
9068
return PathElement{
9169
FieldName: &str,
9270
}, nil
9371
case peValueSepBytes[0]:
94-
iter := readPool.BorrowIterator(b)
95-
defer readPool.ReturnIterator(iter)
96-
v, err := readJSONIter(iter)
97-
if err != nil {
72+
var v any
73+
if err := json.UnmarshalRead(strings.NewReader(s[2:]), &v); err != nil {
9874
return PathElement{}, err
9975
}
100-
return PathElement{Value: &v}, nil
76+
interfaceValue := value.NewValueInterface(v)
77+
return PathElement{Value: &interfaceValue}, nil
10178
case peKeySepBytes[0]:
102-
iter := readPool.BorrowIterator(b)
103-
defer readPool.ReturnIterator(iter)
104-
fields := value.FieldList{}
105-
106-
iter.ReadObjectCB(func(iter *jsoniter.Iterator, key string) bool {
107-
v, err := readJSONIter(iter)
108-
if err != nil {
109-
iter.Error = err
110-
return false
111-
}
112-
fields = append(fields, value.Field{Name: key, Value: v})
113-
return true
114-
})
115-
fields.Sort()
116-
return PathElement{Key: &fields}, iter.Error
79+
var fields value.FieldList
80+
if err := json.UnmarshalRead(strings.NewReader(s[2:]), &fields); err != nil {
81+
return PathElement{}, err
82+
}
83+
return PathElement{Key: &fields}, nil
11784
case peIndexSepBytes[0]:
11885
i, err := strconv.Atoi(s[2:])
11986
if err != nil {
@@ -127,60 +94,58 @@ func DeserializePathElement(s string) (PathElement, error) {
12794
}
12895
}
12996

130-
var (
131-
readPool = jsoniter.NewIterator(jsoniter.ConfigCompatibleWithStandardLibrary).Pool()
132-
writePool = jsoniter.NewStream(jsoniter.ConfigCompatibleWithStandardLibrary, nil, 1024).Pool()
133-
)
134-
13597
// SerializePathElement serializes a path element
13698
func SerializePathElement(pe PathElement) (string, error) {
137-
buf := strings.Builder{}
138-
err := serializePathElementToWriter(&buf, pe)
139-
return buf.String(), err
99+
serializer := pathElementSerializer{}
100+
if err := serializer.serialize(pe); err != nil {
101+
return "", err
102+
}
103+
return serializer.builder.String(), nil
140104
}
141105

142-
func serializePathElementToWriter(w io.Writer, pe PathElement) error {
143-
stream := writePool.BorrowStream(w)
144-
defer writePool.ReturnStream(stream)
106+
type pathElementSerializer struct {
107+
builder bytes.Buffer
108+
fastValue value.FastMarshalValue
109+
}
110+
111+
func (pes *pathElementSerializer) reset() {
112+
pes.builder.Reset()
113+
pes.fastValue.Value = nil
114+
}
115+
116+
func (pes *pathElementSerializer) serialize(pe PathElement) error {
145117
switch {
146118
case pe.FieldName != nil:
147-
if _, err := stream.Write(peFieldSepBytes); err != nil {
119+
if _, err := pes.builder.Write(peFieldSepBytes); err != nil {
120+
return err
121+
}
122+
if _, err := pes.builder.WriteString(*pe.FieldName); err != nil {
148123
return err
149124
}
150-
stream.WriteRaw(*pe.FieldName)
151125
case pe.Key != nil:
152-
if _, err := stream.Write(peKeySepBytes); err != nil {
126+
if _, err := pes.builder.Write(peKeySepBytes); err != nil {
153127
return err
154128
}
155-
stream.WriteObjectStart()
156-
157-
for i, field := range *pe.Key {
158-
if i > 0 {
159-
stream.WriteMore()
160-
}
161-
stream.WriteObjectField(field.Name)
162-
writeJSONStream(field.Value, stream)
129+
if err := json.MarshalWrite(&pes.builder, pe.Key, json.Deterministic(true)); err != nil {
130+
return err
163131
}
164-
stream.WriteObjectEnd()
165132
case pe.Value != nil:
166-
if _, err := stream.Write(peValueSepBytes); err != nil {
133+
if _, err := pes.builder.Write(peValueSepBytes); err != nil {
134+
return err
135+
}
136+
pes.fastValue.Value = pe.Value
137+
if err := json.MarshalWrite(&pes.builder, &pes.fastValue, json.Deterministic(true)); err != nil {
167138
return err
168139
}
169-
writeJSONStream(*pe.Value, stream)
170140
case pe.Index != nil:
171-
if _, err := stream.Write(peIndexSepBytes); err != nil {
141+
if _, err := pes.builder.Write(peIndexSepBytes); err != nil {
142+
return err
143+
}
144+
if _, err := pes.builder.WriteString(strconv.Itoa(*pe.Index)); err != nil {
172145
return err
173146
}
174-
stream.WriteInt(*pe.Index)
175147
default:
176148
return errors.New("invalid PathElement")
177149
}
178-
b := stream.Buffer()
179-
err := stream.Flush()
180-
// Help jsoniter manage its buffers--without this, the next
181-
// use of the stream is likely to require an allocation. Look
182-
// at the jsoniter stream code to understand why. They were probably
183-
// optimizing for folks using the buffer directly.
184-
stream.SetBuffer(b[:0])
185-
return err
150+
return nil
186151
}

0 commit comments

Comments
 (0)