summaryrefslogtreecommitdiff
path: root/vendor/github.com/bytedance/sonic/ast
diff options
context:
space:
mode:
authorLibravatar dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>2023-11-27 13:15:03 +0000
committerLibravatar GitHub <noreply@github.com>2023-11-27 13:15:03 +0000
commit66b77acb1c8b86f0be3836ccaf31683c0bfa317a (patch)
tree9a255a8ea8ef97229b6d75d17de45bdac1755be9 /vendor/github.com/bytedance/sonic/ast
parent[bugfix] Add Actor to outgoing poll vote Create; other fixes (#2384) (diff)
downloadgotosocial-66b77acb1c8b86f0be3836ccaf31683c0bfa317a.tar.xz
[chore]: Bump github.com/gin-contrib/cors from 1.4.0 to 1.5.0 (#2388)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Diffstat (limited to 'vendor/github.com/bytedance/sonic/ast')
-rw-r--r--vendor/github.com/bytedance/sonic/ast/api_amd64.go12
-rw-r--r--vendor/github.com/bytedance/sonic/ast/api_compat.go8
-rw-r--r--vendor/github.com/bytedance/sonic/ast/buffer.go329
-rw-r--r--vendor/github.com/bytedance/sonic/ast/decode.go36
-rw-r--r--vendor/github.com/bytedance/sonic/ast/encode.go66
-rw-r--r--vendor/github.com/bytedance/sonic/ast/error.go44
-rw-r--r--vendor/github.com/bytedance/sonic/ast/iterator.go75
-rw-r--r--vendor/github.com/bytedance/sonic/ast/node.go657
-rw-r--r--vendor/github.com/bytedance/sonic/ast/parser.go101
-rw-r--r--vendor/github.com/bytedance/sonic/ast/sort.go206
-rw-r--r--vendor/github.com/bytedance/sonic/ast/stubs_go120.go2
-rw-r--r--vendor/github.com/bytedance/sonic/ast/visitor.go315
12 files changed, 1151 insertions, 700 deletions
diff --git a/vendor/github.com/bytedance/sonic/ast/api_amd64.go b/vendor/github.com/bytedance/sonic/ast/api_amd64.go
index 3047f59c3..da6738efd 100644
--- a/vendor/github.com/bytedance/sonic/ast/api_amd64.go
+++ b/vendor/github.com/bytedance/sonic/ast/api_amd64.go
@@ -1,4 +1,4 @@
-// +build amd64,go1.15,!go1.21
+// +build amd64,go1.16,!go1.22
/*
* Copyright 2022 ByteDance Inc.
@@ -87,7 +87,13 @@ func encodeBase64(src []byte) string {
func (self *Parser) decodeValue() (val types.JsonState) {
sv := (*rt.GoString)(unsafe.Pointer(&self.s))
- self.p = native.Value(sv.Ptr, sv.Len, self.p, &val, 0)
+ flag := types.F_USE_NUMBER
+ if self.dbuf != nil {
+ flag = 0
+ val.Dbuf = self.dbuf
+ val.Dcap = types.MaxDigitNums
+ }
+ self.p = native.Value(sv.Ptr, sv.Len, self.p, &val, uint64(flag))
return
}
@@ -148,4 +154,4 @@ func (self *Searcher) GetByPath(path ...interface{}) (Node, error) {
return Node{}, self.parser.ExportError(err)
}
return newRawNode(self.parser.s[start:self.parser.p], t), nil
-} \ No newline at end of file
+}
diff --git a/vendor/github.com/bytedance/sonic/ast/api_compat.go b/vendor/github.com/bytedance/sonic/ast/api_compat.go
index b18b5ae8c..7b475eb61 100644
--- a/vendor/github.com/bytedance/sonic/ast/api_compat.go
+++ b/vendor/github.com/bytedance/sonic/ast/api_compat.go
@@ -1,4 +1,4 @@
-// +build !amd64 go1.21
+// +build !amd64 !go1.16 go1.22
/*
* Copyright 2022 ByteDance Inc.
@@ -27,6 +27,10 @@ import (
`github.com/bytedance/sonic/internal/rt`
)
+func init() {
+ println("WARNING: sonic only supports Go1.16~1.20 && CPU amd64, but your environment is not suitable")
+}
+
func quote(buf *[]byte, val string) {
quoteString(buf, val)
}
@@ -49,7 +53,7 @@ func encodeBase64(src []byte) string {
}
func (self *Parser) decodeValue() (val types.JsonState) {
- e, v := decodeValue(self.s, self.p)
+ e, v := decodeValue(self.s, self.p, self.dbuf == nil)
if e < 0 {
return v
}
diff --git a/vendor/github.com/bytedance/sonic/ast/buffer.go b/vendor/github.com/bytedance/sonic/ast/buffer.go
new file mode 100644
index 000000000..93f4ff47a
--- /dev/null
+++ b/vendor/github.com/bytedance/sonic/ast/buffer.go
@@ -0,0 +1,329 @@
+/**
+ * Copyright 2023 ByteDance Inc.
+ *
+ * Licensed 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 ast
+
+import (
+ `sort`
+ `unsafe`
+)
+
+type nodeChunk [_DEFAULT_NODE_CAP]Node
+
+type linkedNodes struct {
+ head nodeChunk
+ tail []*nodeChunk
+ size int
+}
+
+func (self *linkedNodes) Cap() int {
+ if self == nil {
+ return 0
+ }
+ return (len(self.tail)+1)*_DEFAULT_NODE_CAP
+}
+
+func (self *linkedNodes) Len() int {
+ if self == nil {
+ return 0
+ }
+ return self.size
+}
+
+func (self *linkedNodes) At(i int) (*Node) {
+ if self == nil {
+ return nil
+ }
+ if i >= 0 && i<self.size && i < _DEFAULT_NODE_CAP {
+ return &self.head[i]
+ } else if i >= _DEFAULT_NODE_CAP && i<self.size {
+ a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP
+ if a < len(self.tail) {
+ return &self.tail[a][b]
+ }
+ }
+ return nil
+}
+
+func (self *linkedNodes) Add(v Node) {
+ if self.size < _DEFAULT_NODE_CAP {
+ self.head[self.size] = v
+ self.size++
+ return
+ }
+
+ a, b, c := self.size/_DEFAULT_NODE_CAP-1 , self.size%_DEFAULT_NODE_CAP, cap(self.tail)
+ if a - c >= 0 {
+ c += 1 + c>>_APPEND_GROW_SHIFT
+ tmp := make([]*nodeChunk, a + 1, c)
+ copy(tmp, self.tail)
+ self.tail = tmp
+ } else if a >= len(self.tail) {
+ self.tail = self.tail[:a+1]
+ }
+
+ var n = &self.tail[a]
+ if *n == nil {
+ *n = new(nodeChunk)
+ }
+ (*n)[b] = v
+ self.size++
+}
+
+func (self *linkedNodes) ToSlice(con []Node) {
+ if len(con) < self.size {
+ return
+ }
+ i := (self.size-1)
+ a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP
+ if a < 0 {
+ copy(con, self.head[:b+1])
+ return
+ } else {
+ copy(con, self.head[:])
+ con = con[_DEFAULT_NODE_CAP:]
+ }
+
+ for i:=0; i<a; i++ {
+ copy(con, self.tail[i][:])
+ con = con[_DEFAULT_NODE_CAP:]
+ }
+ copy(con, self.tail[a][:b+1])
+}
+
+func (self *linkedNodes) FromSlice(con []Node) {
+ self.size = len(con)
+ i := self.size-1
+ a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP
+ if a < 0 {
+ copy(self.head[:b+1], con)
+ return
+ } else {
+ copy(self.head[:], con)
+ con = con[_DEFAULT_NODE_CAP:]
+ }
+
+ if cap(self.tail) <= a {
+ c := (a+1) + (a+1)>>_APPEND_GROW_SHIFT
+ self.tail = make([]*nodeChunk, a+1, c)
+ }
+ self.tail = self.tail[:a+1]
+
+ for i:=0; i<a; i++ {
+ self.tail[i] = new(nodeChunk)
+ copy(self.tail[i][:], con)
+ con = con[_DEFAULT_NODE_CAP:]
+ }
+
+ self.tail[a] = new(nodeChunk)
+ copy(self.tail[a][:b+1], con)
+}
+
+type pairChunk [_DEFAULT_NODE_CAP]Pair
+
+type linkedPairs struct {
+ head pairChunk
+ tail []*pairChunk
+ size int
+}
+
+func (self *linkedPairs) Cap() int {
+ if self == nil {
+ return 0
+ }
+ return (len(self.tail)+1)*_DEFAULT_NODE_CAP
+}
+
+func (self *linkedPairs) Len() int {
+ if self == nil {
+ return 0
+ }
+ return self.size
+}
+
+func (self *linkedPairs) At(i int) *Pair {
+ if self == nil {
+ return nil
+ }
+ if i >= 0 && i < _DEFAULT_NODE_CAP && i<self.size {
+ return &self.head[i]
+ } else if i >= _DEFAULT_NODE_CAP && i<self.size {
+ a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP
+ if a < len(self.tail) {
+ return &self.tail[a][b]
+ }
+ }
+ return nil
+}
+
+func (self *linkedPairs) Add(v Pair) {
+ if self.size < _DEFAULT_NODE_CAP {
+ self.head[self.size] = v
+ self.size++
+ return
+ }
+
+ a, b, c := self.size/_DEFAULT_NODE_CAP-1 , self.size%_DEFAULT_NODE_CAP, cap(self.tail)
+ if a - c >= 0 {
+ c += 1 + c>>_APPEND_GROW_SHIFT
+ tmp := make([]*pairChunk, a + 1, c)
+ copy(tmp, self.tail)
+ self.tail = tmp
+ } else if a >= len(self.tail) {
+ self.tail = self.tail[:a+1]
+ }
+
+ var n = &self.tail[a]
+ if *n == nil {
+ *n = new(pairChunk)
+ }
+ (*n)[b] = v
+ self.size++
+}
+
+// linear search
+func (self *linkedPairs) Get(key string) (*Pair, int) {
+ for i:=0; i<self.size; i++ {
+ if n := self.At(i); n.Key == key {
+ return n, i
+ }
+ }
+ return nil, -1
+}
+
+func (self *linkedPairs) ToSlice(con []Pair) {
+ if len(con) < self.size {
+ return
+ }
+ i := self.size-1
+ a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP
+
+ if a < 0 {
+ copy(con, self.head[:b+1])
+ return
+ } else {
+ copy(con, self.head[:])
+ con = con[_DEFAULT_NODE_CAP:]
+ }
+
+ for i:=0; i<a; i++ {
+ copy(con, self.tail[i][:])
+ con = con[_DEFAULT_NODE_CAP:]
+ }
+ copy(con, self.tail[a][:b+1])
+}
+
+func (self *linkedPairs) ToMap(con map[string]Node) {
+ for i:=0; i<self.size; i++ {
+ n := self.At(i)
+ con[n.Key] = n.Value
+ }
+}
+
+func (self *linkedPairs) FromSlice(con []Pair) {
+ self.size = len(con)
+ i := self.size-1
+ a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP
+ if a < 0 {
+ copy(self.head[:b+1], con)
+ return
+ } else {
+ copy(self.head[:], con)
+ con = con[_DEFAULT_NODE_CAP:]
+ }
+
+ if cap(self.tail) <= a {
+ c := (a+1) + (a+1)>>_APPEND_GROW_SHIFT
+ self.tail = make([]*pairChunk, a+1, c)
+ }
+ self.tail = self.tail[:a+1]
+
+ for i:=0; i<a; i++ {
+ self.tail[i] = new(pairChunk)
+ copy(self.tail[i][:], con)
+ con = con[_DEFAULT_NODE_CAP:]
+ }
+
+ self.tail[a] = new(pairChunk)
+ copy(self.tail[a][:b+1], con)
+}
+
+func (self *linkedPairs) Less(i, j int) bool {
+ return lessFrom(self.At(i).Key, self.At(j).Key, 0)
+}
+
+func (self *linkedPairs) Swap(i, j int) {
+ a, b := self.At(i), self.At(j)
+ *a, *b = *b, *a
+}
+
+func (self *linkedPairs) Sort() {
+ sort.Sort(self)
+}
+
+// Compare two strings from the pos d.
+func lessFrom(a, b string, d int) bool {
+ l := len(a)
+ if l > len(b) {
+ l = len(b)
+ }
+ for i := d; i < l; i++ {
+ if a[i] == b[i] {
+ continue
+ }
+ return a[i] < b[i]
+ }
+ return len(a) < len(b)
+}
+
+type parseObjectStack struct {
+ parser Parser
+ v linkedPairs
+}
+
+type parseArrayStack struct {
+ parser Parser
+ v linkedNodes
+}
+
+func newLazyArray(p *Parser) Node {
+ s := new(parseArrayStack)
+ s.parser = *p
+ return Node{
+ t: _V_ARRAY_LAZY,
+ p: unsafe.Pointer(s),
+ }
+}
+
+func newLazyObject(p *Parser) Node {
+ s := new(parseObjectStack)
+ s.parser = *p
+ return Node{
+ t: _V_OBJECT_LAZY,
+ p: unsafe.Pointer(s),
+ }
+}
+
+func (self *Node) getParserAndArrayStack() (*Parser, *parseArrayStack) {
+ stack := (*parseArrayStack)(self.p)
+ return &stack.parser, stack
+}
+
+func (self *Node) getParserAndObjectStack() (*Parser, *parseObjectStack) {
+ stack := (*parseObjectStack)(self.p)
+ return &stack.parser, stack
+}
+
diff --git a/vendor/github.com/bytedance/sonic/ast/decode.go b/vendor/github.com/bytedance/sonic/ast/decode.go
index 6a5f6fea3..3e08bfcb2 100644
--- a/vendor/github.com/bytedance/sonic/ast/decode.go
+++ b/vendor/github.com/bytedance/sonic/ast/decode.go
@@ -220,7 +220,7 @@ func decodeFloat64(src string, pos int) (ret int, v float64, err error) {
return ret, v, nil
}
-func decodeValue(src string, pos int) (ret int, v types.JsonState) {
+func decodeValue(src string, pos int, skipnum bool) (ret int, v types.JsonState) {
pos = skipBlank(src, pos)
if pos < 0 {
return pos, types.JsonState{Vt: types.ValueType(pos)}
@@ -256,20 +256,30 @@ func decodeValue(src string, pos int) (ret int, v types.JsonState) {
}
return ret, types.JsonState{Vt: types.V_FALSE}
case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
- var iv int64
- ret, iv, _ = decodeInt64(src, pos)
- if ret >= 0 {
- return ret, types.JsonState{Vt: types.V_INTEGER, Iv: iv, Ep: pos}
- } else if ret != -int(types.ERR_INVALID_NUMBER_FMT) {
- return ret, types.JsonState{Vt: types.ValueType(ret)}
- }
- var fv float64
- ret, fv, _ = decodeFloat64(src, pos)
- if ret >= 0 {
- return ret, types.JsonState{Vt: types.V_DOUBLE, Dv: fv, Ep: pos}
+ if skipnum {
+ ret = skipNumber(src, pos)
+ if ret >= 0 {
+ return ret, types.JsonState{Vt: types.V_DOUBLE, Iv: 0, Ep: pos}
+ } else {
+ return ret, types.JsonState{Vt: types.ValueType(ret)}
+ }
} else {
- return ret, types.JsonState{Vt: types.ValueType(ret)}
+ var iv int64
+ ret, iv, _ = decodeInt64(src, pos)
+ if ret >= 0 {
+ return ret, types.JsonState{Vt: types.V_INTEGER, Iv: iv, Ep: pos}
+ } else if ret != -int(types.ERR_INVALID_NUMBER_FMT) {
+ return ret, types.JsonState{Vt: types.ValueType(ret)}
+ }
+ var fv float64
+ ret, fv, _ = decodeFloat64(src, pos)
+ if ret >= 0 {
+ return ret, types.JsonState{Vt: types.V_DOUBLE, Dv: fv, Ep: pos}
+ } else {
+ return ret, types.JsonState{Vt: types.ValueType(ret)}
+ }
}
+
default:
return -int(types.ERR_INVALID_CHAR), types.JsonState{Vt:-types.ValueType(types.ERR_INVALID_CHAR)}
}
diff --git a/vendor/github.com/bytedance/sonic/ast/encode.go b/vendor/github.com/bytedance/sonic/ast/encode.go
index 1187e30c2..263ae5a9d 100644
--- a/vendor/github.com/bytedance/sonic/ast/encode.go
+++ b/vendor/github.com/bytedance/sonic/ast/encode.go
@@ -19,8 +19,6 @@ package ast
import (
`sync`
`unicode/utf8`
-
- `github.com/bytedance/sonic/internal/rt`
)
const (
@@ -165,18 +163,18 @@ func (self *Node) encodeFalse(buf *[]byte) error {
}
func (self *Node) encodeNumber(buf *[]byte) error {
- str := rt.StrFrom(self.p, self.v)
+ str := self.toString()
*buf = append(*buf, str...)
return nil
}
func (self *Node) encodeString(buf *[]byte) error {
- if self.v == 0 {
+ if self.l == 0 {
*buf = append(*buf, '"', '"')
return nil
}
- quote(buf, rt.StrFrom(self.p, self.v))
+ quote(buf, self.toString())
return nil
}
@@ -195,16 +193,28 @@ func (self *Node) encodeArray(buf *[]byte) error {
*buf = append(*buf, '[')
- var p = (*Node)(self.p)
- err := p.encode(buf)
- if err != nil {
- return err
+ var s = (*linkedNodes)(self.p)
+ var started bool
+ if nb > 0 {
+ n := s.At(0)
+ if n.Exists() {
+ if err := n.encode(buf); err != nil {
+ return err
+ }
+ started = true
+ }
}
+
for i := 1; i < nb; i++ {
- *buf = append(*buf, ',')
- p = p.unsafe_next()
- err := p.encode(buf)
- if err != nil {
+ n := s.At(i)
+ if !n.Exists() {
+ continue
+ }
+ if started {
+ *buf = append(*buf, ',')
+ }
+ started = true
+ if err := n.encode(buf); err != nil {
return err
}
}
@@ -240,20 +250,32 @@ func (self *Node) encodeObject(buf *[]byte) error {
*buf = append(*buf, '{')
- var p = (*Pair)(self.p)
- err := p.encode(buf)
- if err != nil {
- return err
+ var s = (*linkedPairs)(self.p)
+ var started bool
+ if nb > 0 {
+ n := s.At(0)
+ if n.Value.Exists() {
+ if err := n.encode(buf); err != nil {
+ return err
+ }
+ started = true
+ }
}
+
for i := 1; i < nb; i++ {
- *buf = append(*buf, ',')
- p = p.unsafe_next()
- err := p.encode(buf)
- if err != nil {
+ n := s.At(i)
+ if !n.Value.Exists() {
+ continue
+ }
+ if started {
+ *buf = append(*buf, ',')
+ }
+ started = true
+ if err := n.encode(buf); err != nil {
return err
}
}
*buf = append(*buf, '}')
return nil
-} \ No newline at end of file
+}
diff --git a/vendor/github.com/bytedance/sonic/ast/error.go b/vendor/github.com/bytedance/sonic/ast/error.go
index f4c441ae6..00a04468e 100644
--- a/vendor/github.com/bytedance/sonic/ast/error.go
+++ b/vendor/github.com/bytedance/sonic/ast/error.go
@@ -8,23 +8,55 @@ import (
`github.com/bytedance/sonic/internal/native/types`
)
-func (self *Parser) syntaxError(err types.ParsingError) SyntaxError {
- return SyntaxError{
- Pos : self.p,
- Src : self.s,
- Code: err,
+
+func newError(err types.ParsingError, msg string) *Node {
+ return &Node{
+ t: V_ERROR,
+ l: uint(err),
+ p: unsafe.Pointer(&msg),
}
}
+// Error returns error message if the node is invalid
+func (self Node) Error() string {
+ if self.t != V_ERROR {
+ return ""
+ } else {
+ return *(*string)(self.p)
+ }
+}
+
func newSyntaxError(err SyntaxError) *Node {
msg := err.Description()
return &Node{
t: V_ERROR,
- v: int64(err.Code),
+ l: uint(err.Code),
p: unsafe.Pointer(&msg),
}
}
+func (self *Parser) syntaxError(err types.ParsingError) SyntaxError {
+ return SyntaxError{
+ Pos : self.p,
+ Src : self.s,
+ Code: err,
+ }
+}
+
+func unwrapError(err error) *Node {
+ if se, ok := err.(*Node); ok {
+ return se
+ }else if sse, ok := err.(Node); ok {
+ return &sse
+ } else {
+ msg := err.Error()
+ return &Node{
+ t: V_ERROR,
+ p: unsafe.Pointer(&msg),
+ }
+ }
+}
+
type SyntaxError struct {
Pos int
Src string
diff --git a/vendor/github.com/bytedance/sonic/ast/iterator.go b/vendor/github.com/bytedance/sonic/ast/iterator.go
index 03a25b4e9..3c4187a9c 100644
--- a/vendor/github.com/bytedance/sonic/ast/iterator.go
+++ b/vendor/github.com/bytedance/sonic/ast/iterator.go
@@ -82,26 +82,54 @@ type ObjectIterator struct {
Iterator
}
+func (self *ListIterator) next() *Node {
+next_start:
+ if !self.HasNext() {
+ return nil
+ } else {
+ n := self.p.nodeAt(self.i)
+ self.i++
+ if !n.Exists() {
+ goto next_start
+ }
+ return n
+ }
+}
+
// Next scans through children of underlying V_ARRAY,
// copies each child to v, and returns .HasNext().
func (self *ListIterator) Next(v *Node) bool {
- if !self.HasNext() {
+ n := self.next()
+ if n == nil {
return false
+ }
+ *v = *n
+ return true
+}
+
+func (self *ObjectIterator) next() *Pair {
+next_start:
+ if !self.HasNext() {
+ return nil
} else {
- *v, self.i = *self.p.nodeAt(self.i), self.i + 1
- return true
+ n := self.p.pairAt(self.i)
+ self.i++
+ if !n.Value.Exists() {
+ goto next_start
+ }
+ return n
}
}
// Next scans through children of underlying V_OBJECT,
// copies each child to v, and returns .HasNext().
func (self *ObjectIterator) Next(p *Pair) bool {
- if !self.HasNext() {
+ n := self.next()
+ if n == nil {
return false
- } else {
- *p, self.i = *self.p.pairAt(self.i), self.i + 1
- return true
}
+ *p = *n
+ return true
}
// Sequence represents scanning path of single-layer nodes.
@@ -129,36 +157,39 @@ type Scanner func(path Sequence, node *Node) bool
//
// Especailly, if the node is not V_ARRAY or V_OBJECT,
// the node itself will be returned and Sequence.Index == -1.
+//
+// NOTICE: A unsetted node WON'T trigger sc, but its index still counts into Path.Index
func (self *Node) ForEach(sc Scanner) error {
switch self.itype() {
case types.V_ARRAY:
- ns, err := self.UnsafeArray()
+ iter, err := self.Values()
if err != nil {
return err
}
- for i := range ns {
- if !sc(Sequence{i, nil}, &ns[i]) {
- return err
+ v := iter.next()
+ for v != nil {
+ if !sc(Sequence{iter.i-1, nil}, v) {
+ return nil
}
+ v = iter.next()
}
case types.V_OBJECT:
- ns, err := self.UnsafeMap()
+ iter, err := self.Properties()
if err != nil {
return err
}
- for i := range ns {
- if !sc(Sequence{i, &ns[i].Key}, &ns[i].Value) {
- return err
+ v := iter.next()
+ for v != nil {
+ if !sc(Sequence{iter.i-1, &v.Key}, &v.Value) {
+ return nil
}
+ v = iter.next()
}
default:
+ if self.Check() != nil {
+ return self
+ }
sc(Sequence{-1, nil}, self)
}
- return self.Check()
+ return nil
}
-
-type PairSlice []Pair
-
-func (self PairSlice) Sort() {
- radixQsort(self, 0, maxDepth(len(self)))
-} \ No newline at end of file
diff --git a/vendor/github.com/bytedance/sonic/ast/node.go b/vendor/github.com/bytedance/sonic/ast/node.go
index 6b5ad8a3e..990908ddd 100644
--- a/vendor/github.com/bytedance/sonic/ast/node.go
+++ b/vendor/github.com/bytedance/sonic/ast/node.go
@@ -21,21 +21,12 @@ import (
`fmt`
`strconv`
`unsafe`
- `reflect`
`github.com/bytedance/sonic/internal/native/types`
`github.com/bytedance/sonic/internal/rt`
)
const (
- _CAP_BITS = 32
- _LEN_MASK = 1 << _CAP_BITS - 1
-
- _NODE_SIZE = unsafe.Sizeof(Node{})
- _PAIR_SIZE = unsafe.Sizeof(Pair{})
-)
-
-const (
_V_NONE types.ValueType = 0
_V_NODE_BASE types.ValueType = 1 << 5
_V_LAZY types.ValueType = 1 << 7
@@ -51,40 +42,36 @@ const (
const (
V_NONE = 0
V_ERROR = 1
- V_NULL = 2
- V_TRUE = 3
- V_FALSE = 4
- V_ARRAY = 5
- V_OBJECT = 6
- V_STRING = 7
+ V_NULL = int(types.V_NULL)
+ V_TRUE = int(types.V_TRUE)
+ V_FALSE = int(types.V_FALSE)
+ V_ARRAY = int(types.V_ARRAY)
+ V_OBJECT = int(types.V_OBJECT)
+ V_STRING = int(types.V_STRING)
V_NUMBER = int(_V_NUMBER)
V_ANY = int(_V_ANY)
)
-var (
- byteType = rt.UnpackType(reflect.TypeOf(byte(0)))
-)
-
type Node struct {
- v int64
t types.ValueType
+ l uint
p unsafe.Pointer
}
// UnmarshalJSON is just an adapter to json.Unmarshaler.
// If you want better performance, use Searcher.GetByPath() directly
func (self *Node) UnmarshalJSON(data []byte) (err error) {
- *self, err = NewSearcher(string(data)).GetByPath()
- return
+ *self = NewRaw(string(data))
+ return self.Check()
}
/** Node Type Accessor **/
// Type returns json type represented by the node
// It will be one of belows:
-// V_NONE = 0 (empty node)
+// V_NONE = 0 (empty node, key not exists)
// V_ERROR = 1 (error node)
-// V_NULL = 2 (json value `null`)
+// V_NULL = 2 (json value `null`, key exists)
// V_TRUE = 3 (json value `true`)
// V_FALSE = 4 (json value `false`)
// V_ARRAY = 5 (json value array)
@@ -102,7 +89,7 @@ func (self Node) itype() types.ValueType {
// Exists returns false only if the self is nil or empty node V_NONE
func (self *Node) Exists() bool {
- return self != nil && self.t != _V_NONE
+ return self.Valid() && self.t != _V_NONE
}
// Valid reports if self is NOT V_ERROR or nil
@@ -114,7 +101,7 @@ func (self *Node) Valid() bool {
}
// Check checks if the node itself is valid, and return:
-// - ErrNotFound If the node is nil
+// - ErrNotExist If the node is nil
// - Its underlying error If the node is V_ERROR
func (self *Node) Check() error {
if self == nil {
@@ -126,15 +113,6 @@ func (self *Node) Check() error {
}
}
-// Error returns error message if the node is invalid
-func (self Node) Error() string {
- if self.t != V_ERROR {
- return ""
- } else {
- return *(*string)(self.p)
- }
-}
-
// IsRaw returns true if node's underlying value is raw json
func (self Node) IsRaw() bool {
return self.t&_V_RAW != 0
@@ -152,11 +130,14 @@ func (self *Node) isAny() bool {
// Raw returns json representation of the node,
func (self *Node) Raw() (string, error) {
+ if self == nil {
+ return "", ErrNotExist
+ }
if !self.IsRaw() {
buf, err := self.MarshalJSON()
return rt.Mem2Str(buf), err
}
- return rt.StrFrom(self.p, self.v), nil
+ return self.toString(), nil
}
func (self *Node) checkRaw() error {
@@ -166,7 +147,7 @@ func (self *Node) checkRaw() error {
if self.IsRaw() {
self.parseRaw(false)
}
- return nil
+ return self.Check()
}
// Bool returns bool value represented by this node,
@@ -181,14 +162,14 @@ func (self *Node) Bool() (bool, error) {
case types.V_FALSE : return false, nil
case types.V_NULL : return false, nil
case _V_NUMBER :
- if i, err := numberToInt64(self); err == nil {
+ if i, err := self.toInt64(); err == nil {
return i != 0, nil
- } else if f, err := numberToFloat64(self); err == nil {
+ } else if f, err := self.toFloat64(); err == nil {
return f != 0, nil
} else {
return false, err
}
- case types.V_STRING: return strconv.ParseBool(rt.StrFrom(self.p, self.v))
+ case types.V_STRING: return strconv.ParseBool(self.toString())
case _V_ANY :
any := self.packAny()
switch v := any.(type) {
@@ -229,9 +210,9 @@ func (self *Node) Int64() (int64, error) {
}
switch self.t {
case _V_NUMBER, types.V_STRING :
- if i, err := numberToInt64(self); err == nil {
+ if i, err := self.toInt64(); err == nil {
return i, nil
- } else if f, err := numberToFloat64(self); err == nil {
+ } else if f, err := self.toFloat64(); err == nil {
return int64(f), nil
} else {
return 0, err
@@ -283,7 +264,7 @@ func (self *Node) StrictInt64() (int64, error) {
return 0, err
}
switch self.t {
- case _V_NUMBER : return numberToInt64(self)
+ case _V_NUMBER : return self.toInt64()
case _V_ANY :
any := self.packAny()
switch v := any.(type) {
@@ -325,12 +306,12 @@ func (self *Node) Number() (json.Number, error) {
return json.Number(""), err
}
switch self.t {
- case _V_NUMBER : return toNumber(self) , nil
+ case _V_NUMBER : return self.toNumber(), nil
case types.V_STRING :
- if _, err := numberToInt64(self); err == nil {
- return toNumber(self), nil
- } else if _, err := numberToFloat64(self); err == nil {
- return toNumber(self), nil
+ if _, err := self.toInt64(); err == nil {
+ return self.toNumber(), nil
+ } else if _, err := self.toFloat64(); err == nil {
+ return self.toNumber(), nil
} else {
return json.Number(""), err
}
@@ -372,7 +353,7 @@ func (self *Node) StrictNumber() (json.Number, error) {
return json.Number(""), err
}
switch self.t {
- case _V_NUMBER : return toNumber(self) , nil
+ case _V_NUMBER : return self.toNumber() , nil
case _V_ANY :
if v, ok := self.packAny().(json.Number); ok {
return v, nil
@@ -394,7 +375,7 @@ func (self *Node) String() (string, error) {
case types.V_NULL : return "" , nil
case types.V_TRUE : return "true" , nil
case types.V_FALSE : return "false", nil
- case types.V_STRING, _V_NUMBER : return rt.StrFrom(self.p, self.v), nil
+ case types.V_STRING, _V_NUMBER : return self.toString(), nil
case _V_ANY :
any := self.packAny()
switch v := any.(type) {
@@ -426,7 +407,7 @@ func (self *Node) StrictString() (string, error) {
return "", err
}
switch self.t {
- case types.V_STRING : return rt.StrFrom(self.p, self.v), nil
+ case types.V_STRING : return self.toString(), nil
case _V_ANY :
if v, ok := self.packAny().(string); ok {
return v, nil
@@ -445,7 +426,7 @@ func (self *Node) Float64() (float64, error) {
return 0.0, err
}
switch self.t {
- case _V_NUMBER, types.V_STRING : return numberToFloat64(self)
+ case _V_NUMBER, types.V_STRING : return self.toFloat64()
case types.V_TRUE : return 1.0, nil
case types.V_FALSE : return 0.0, nil
case types.V_NULL : return 0.0, nil
@@ -494,7 +475,7 @@ func (self *Node) StrictFloat64() (float64, error) {
return 0.0, err
}
switch self.t {
- case _V_NUMBER : return numberToFloat64(self)
+ case _V_NUMBER : return self.toFloat64()
case _V_ANY :
any := self.packAny()
switch v := any.(type) {
@@ -509,15 +490,14 @@ func (self *Node) StrictFloat64() (float64, error) {
/** Sequencial Value Methods **/
// Len returns children count of a array|object|string node
-// For partially loaded node, it also works but only counts the parsed children
+// WARN: For partially loaded node, it also works but only counts the parsed children
+// WARN: For ARRAY|OBJECT nodes which has been conducted `UnsetXX()`, its length WON'T change
func (self *Node) Len() (int, error) {
if err := self.checkRaw(); err != nil {
return 0, err
}
- if self.t == types.V_ARRAY || self.t == types.V_OBJECT || self.t == _V_ARRAY_LAZY || self.t == _V_OBJECT_LAZY {
- return int(self.v & _LEN_MASK), nil
- } else if self.t == types.V_STRING {
- return int(self.v), nil
+ if self.t == types.V_ARRAY || self.t == types.V_OBJECT || self.t == _V_ARRAY_LAZY || self.t == _V_OBJECT_LAZY || self.t == types.V_STRING {
+ return int(self.l), nil
} else if self.t == _V_NONE || self.t == types.V_NULL {
return 0, nil
} else {
@@ -526,7 +506,7 @@ func (self *Node) Len() (int, error) {
}
func (self Node) len() int {
- return int(self.v & _LEN_MASK)
+ return int(self.l)
}
// Cap returns malloc capacity of a array|object node for children
@@ -534,47 +514,42 @@ func (self *Node) Cap() (int, error) {
if err := self.checkRaw(); err != nil {
return 0, err
}
- if self.t == types.V_ARRAY || self.t == types.V_OBJECT || self.t == _V_ARRAY_LAZY || self.t == _V_OBJECT_LAZY {
- return int(self.v >> _CAP_BITS), nil
- } else if self.t == _V_NONE || self.t == types.V_NULL {
- return 0, nil
- } else {
- return 0, ErrUnsupportType
+ switch self.t {
+ case types.V_ARRAY: return (*linkedNodes)(self.p).Cap(), nil
+ case types.V_OBJECT: return (*linkedPairs)(self.p).Cap(), nil
+ case _V_ARRAY_LAZY: return (*parseArrayStack)(self.p).v.Cap(), nil
+ case _V_OBJECT_LAZY: return (*parseObjectStack)(self.p).v.Cap(), nil
+ case _V_NONE, types.V_NULL: return 0, nil
+ default: return 0, ErrUnsupportType
}
}
-func (self Node) cap() int {
- return int(self.v >> _CAP_BITS)
-}
-
// Set sets the node of given key under self, and reports if the key has existed.
//
// If self is V_NONE or V_NULL, it becomes V_OBJECT and sets the node at the key.
func (self *Node) Set(key string, node Node) (bool, error) {
- if self != nil && (self.t == _V_NONE || self.t == types.V_NULL) {
- *self = NewObject([]Pair{{key, node}})
- return false, nil
+ if err := self.Check(); err != nil {
+ return false, err
}
-
if err := node.Check(); err != nil {
return false, err
}
+ if self.t == _V_NONE || self.t == types.V_NULL {
+ *self = NewObject([]Pair{{key, node}})
+ return false, nil
+ }
+
p := self.Get(key)
+
if !p.Exists() {
- l := self.len()
- c := self.cap()
- if l == c {
- // TODO: maybe change append size in future
- c += _DEFAULT_NODE_CAP
- mem := unsafe_NewArray(_PAIR_TYPE, c)
- memmove(mem, self.p, _PAIR_SIZE * uintptr(l))
- self.p = mem
+ // self must be fully-loaded here
+ if self.len() == 0 {
+ *self = newObject(new(linkedPairs))
}
- v := self.pairAt(l)
- v.Key = key
- v.Value = node
- self.setCapAndLen(c, l+1)
+ s := (*linkedPairs)(self.p)
+ s.Add(Pair{key, node})
+ self.l++
return false, nil
} else if err := p.Check(); err != nil {
@@ -590,9 +565,12 @@ func (self *Node) SetAny(key string, val interface{}) (bool, error) {
return self.Set(key, NewAny(val))
}
-// Unset remove the node of given key under object parent, and reports if the key has existed.
+// Unset RESET the node of given key under object parent, and reports if the key has existed.
+// WARN: After conducting `UnsetXX()`, the node's length WON'T change
func (self *Node) Unset(key string) (bool, error) {
- self.must(types.V_OBJECT, "an object")
+ if err := self.should(types.V_OBJECT, "an object"); err != nil {
+ return false, err
+ }
p, i := self.skipKey(key)
if !p.Exists() {
return false, nil
@@ -608,10 +586,18 @@ func (self *Node) Unset(key string) (bool, error) {
//
// The index must be within self's children.
func (self *Node) SetByIndex(index int, node Node) (bool, error) {
+ if err := self.Check(); err != nil {
+ return false, err
+ }
if err := node.Check(); err != nil {
return false, err
}
+ if index == 0 && (self.t == _V_NONE || self.t == types.V_NULL) {
+ *self = NewArray([]Node{node})
+ return false, nil
+ }
+
p := self.Index(index)
if !p.Exists() {
return false, ErrNotExist
@@ -629,12 +615,20 @@ func (self *Node) SetAnyByIndex(index int, val interface{}) (bool, error) {
}
// UnsetByIndex remove the node of given index
+// WARN: After conducting `UnsetXX()`, the node's length WON'T change
func (self *Node) UnsetByIndex(index int) (bool, error) {
+ if err := self.Check(); err != nil {
+ return false, err
+ }
+
var p *Node
it := self.itype()
if it == types.V_ARRAY {
p = self.Index(index)
}else if it == types.V_OBJECT {
+ if err := self.checkRaw(); err != nil {
+ return false, err
+ }
pr := self.skipIndexPair(index)
if pr == nil {
return false, ErrNotExist
@@ -660,31 +654,28 @@ func (self *Node) UnsetByIndex(index int) (bool, error) {
//
// If self is V_NONE or V_NULL, it becomes V_ARRAY and sets the node at index 0.
func (self *Node) Add(node Node) error {
+ if err := self.Check(); err != nil {
+ return err
+ }
+
if self != nil && (self.t == _V_NONE || self.t == types.V_NULL) {
*self = NewArray([]Node{node})
return nil
}
-
if err := self.should(types.V_ARRAY, "an array"); err != nil {
return err
}
- if err := self.skipAllIndex(); err != nil {
+ s, err := self.unsafeArray()
+ if err != nil {
return err
}
- var p rt.GoSlice
- p.Cap = self.cap()
- p.Len = self.len()
- p.Ptr = self.p
-
- s := *(*[]Node)(unsafe.Pointer(&p))
- s = append(s, node)
-
- self.p = unsafe.Pointer(&s[0])
- self.setCapAndLen(cap(s), len(s))
+ s.Add(node)
+ self.l++
return nil
}
+
// SetAny wraps val with V_ANY node, and Add() the node.
func (self *Node) AddAny(val interface{}) error {
return self.Add(NewAny(val))
@@ -730,6 +721,8 @@ func (self *Node) Get(key string) *Node {
// Index indexies node at given idx,
// node type CAN be either V_OBJECT or V_ARRAY
+// WARN: After conducting `UnsetXX()`, the node's length WON'T change,
+// thus its children's indexing WON'T change too
func (self *Node) Index(idx int) *Node {
if err := self.checkRaw(); err != nil {
return unwrapError(err)
@@ -753,6 +746,8 @@ func (self *Node) Index(idx int) *Node {
// IndexPair indexies pair at given idx,
// node type MUST be either V_OBJECT
+// WARN: After conducting `UnsetXX()`, the node's length WON'T change,
+// thus its children's indexing WON'T change too
func (self *Node) IndexPair(idx int) *Pair {
if err := self.should(types.V_OBJECT, "an object"); err != nil {
return nil
@@ -837,30 +832,68 @@ func (self *Node) MapUseNode() (map[string]Node, error) {
// MapUnsafe exports the underlying pointer to its children map
// WARN: don't use it unless you know what you are doing
-func (self *Node) UnsafeMap() ([]Pair, error) {
- if err := self.should(types.V_OBJECT, "an object"); err != nil {
- return nil, err
- }
+//
+// Deprecated: this API now returns copied nodes instead of directly reference,
+// func (self *Node) UnsafeMap() ([]Pair, error) {
+// if err := self.should(types.V_OBJECT, "an object"); err != nil {
+// return nil, err
+// }
+// if err := self.skipAllKey(); err != nil {
+// return nil, err
+// }
+// return self.toGenericObjectUsePair()
+// }
+
+//go:nocheckptr
+func (self *Node) unsafeMap() (*linkedPairs, error) {
if err := self.skipAllKey(); err != nil {
return nil, err
}
- s := rt.Ptr2SlicePtr(self.p, int(self.len()), self.cap())
- return *(*[]Pair)(s), nil
+ if self.p == nil {
+ *self = newObject(new(linkedPairs))
+ }
+ return (*linkedPairs)(self.p), nil
}
// SortKeys sorts children of a V_OBJECT node in ascending key-order.
// If recurse is true, it recursively sorts children's children as long as a V_OBJECT node is found.
-func (self *Node) SortKeys(recurse bool) (err error) {
- ps, err := self.UnsafeMap()
+func (self *Node) SortKeys(recurse bool) error {
+ // check raw node first
+ if err := self.checkRaw(); err != nil {
+ return err
+ }
+ if self.itype() == types.V_OBJECT {
+ return self.sortKeys(recurse)
+ } else {
+ var err error
+ err2 := self.ForEach(func(path Sequence, node *Node) bool {
+ it := node.itype()
+ if it == types.V_ARRAY || it == types.V_OBJECT {
+ err = node.SortKeys(recurse)
+ if err != nil {
+ return false
+ }
+ }
+ return true
+ })
+ if err != nil {
+ return err
+ }
+ return err2
+ }
+}
+
+func (self *Node) sortKeys(recurse bool) (err error) {
+ ps, err := self.unsafeMap()
if err != nil {
return err
}
- PairSlice(ps).Sort()
+ ps.Sort()
if recurse {
var sc Scanner
sc = func(path Sequence, node *Node) bool {
if node.itype() == types.V_OBJECT {
- if err := node.SortKeys(recurse); err != nil {
+ if err := node.sortKeys(recurse); err != nil {
return false
}
}
@@ -871,7 +904,9 @@ func (self *Node) SortKeys(recurse bool) (err error) {
}
return true
}
- self.ForEach(sc)
+ if err := self.ForEach(sc); err != nil {
+ return err
+ }
}
return nil
}
@@ -936,15 +971,27 @@ func (self *Node) ArrayUseNode() ([]Node, error) {
// ArrayUnsafe exports the underlying pointer to its children array
// WARN: don't use it unless you know what you are doing
-func (self *Node) UnsafeArray() ([]Node, error) {
- if err := self.should(types.V_ARRAY, "an array"); err != nil {
- return nil, err
- }
+//
+// Deprecated: this API now returns copied nodes instead of directly reference,
+// which has no difference with ArrayUseNode
+// func (self *Node) UnsafeArray() ([]Node, error) {
+// if err := self.should(types.V_ARRAY, "an array"); err != nil {
+// return nil, err
+// }
+// if err := self.skipAllIndex(); err != nil {
+// return nil, err
+// }
+// return self.toGenericArrayUseNode()
+// }
+
+func (self *Node) unsafeArray() (*linkedNodes, error) {
if err := self.skipAllIndex(); err != nil {
return nil, err
}
- s := rt.Ptr2SlicePtr(self.p, self.len(), self.cap())
- return *(*[]Node)(s), nil
+ if self.p == nil {
+ *self = newArray(new(linkedNodes))
+ }
+ return (*linkedNodes)(self.p), nil
}
// Interface loads all children under all pathes from this node,
@@ -961,9 +1008,9 @@ func (self *Node) Interface() (interface{}, error) {
case types.V_FALSE : return false, nil
case types.V_ARRAY : return self.toGenericArray()
case types.V_OBJECT : return self.toGenericObject()
- case types.V_STRING : return rt.StrFrom(self.p, self.v), nil
+ case types.V_STRING : return self.toString(), nil
case _V_NUMBER :
- v, err := numberToFloat64(self)
+ v, err := self.toFloat64()
if err != nil {
return nil, err
}
@@ -1005,8 +1052,8 @@ func (self *Node) InterfaceUseNumber() (interface{}, error) {
case types.V_FALSE : return false, nil
case types.V_ARRAY : return self.toGenericArrayUseNumber()
case types.V_OBJECT : return self.toGenericObjectUseNumber()
- case types.V_STRING : return rt.StrFrom(self.p, self.v), nil
- case _V_NUMBER : return toNumber(self), nil
+ case types.V_STRING : return self.toString(), nil
+ case _V_NUMBER : return self.toNumber(), nil
case _V_ARRAY_LAZY :
if err := self.loadAllIndex(); err != nil {
return nil, err
@@ -1092,9 +1139,8 @@ func (self *Node) LoadAll() error {
// Load loads the node's children as parsed.
// After calling it, only the node itself can be used on concurrency (not include its children)
func (self *Node) Load() error {
- if self.IsRaw() {
- self.parseRaw(false)
- return self.Load()
+ if err := self.checkRaw(); err != nil {
+ return err
}
switch self.t {
@@ -1109,39 +1155,6 @@ func (self *Node) Load() error {
/**---------------------------------- Internal Helper Methods ----------------------------------**/
-var (
- _NODE_TYPE = rt.UnpackEface(Node{}).Type
- _PAIR_TYPE = rt.UnpackEface(Pair{}).Type
-)
-
-func (self *Node) setCapAndLen(cap int, len int) {
- if self.t == types.V_ARRAY || self.t == types.V_OBJECT || self.t == _V_ARRAY_LAZY || self.t == _V_OBJECT_LAZY {
- self.v = int64(len&_LEN_MASK | cap<<_CAP_BITS)
- } else {
- panic("value does not have a length")
- }
-}
-
-func (self *Node) unsafe_next() *Node {
- return (*Node)(unsafe.Pointer(uintptr(unsafe.Pointer(self)) + _NODE_SIZE))
-}
-
-func (self *Pair) unsafe_next() *Pair {
- return (*Pair)(unsafe.Pointer(uintptr(unsafe.Pointer(self)) + _PAIR_SIZE))
-}
-
-func (self *Node) must(t types.ValueType, s string) {
- if err := self.checkRaw(); err != nil {
- panic(err)
- }
- if err := self.Check(); err != nil {
- panic(err)
- }
- if self.itype() != t {
- panic("value cannot be represented as " + s)
- }
-}
-
func (self *Node) should(t types.ValueType, s string) error {
if err := self.checkRaw(); err != nil {
return err
@@ -1153,37 +1166,25 @@ func (self *Node) should(t types.ValueType, s string) error {
}
func (self *Node) nodeAt(i int) *Node {
- var p = self.p
+ var p *linkedNodes
if self.isLazy() {
_, stack := self.getParserAndArrayStack()
- p = *(*unsafe.Pointer)(unsafe.Pointer(&stack.v))
+ p = &stack.v
+ } else {
+ p = (*linkedNodes)(self.p)
}
- return (*Node)(unsafe.Pointer(uintptr(p) + uintptr(i)*_NODE_SIZE))
+ return p.At(i)
}
func (self *Node) pairAt(i int) *Pair {
- var p = self.p
+ var p *linkedPairs
if self.isLazy() {
_, stack := self.getParserAndObjectStack()
- p = *(*unsafe.Pointer)(unsafe.Pointer(&stack.v))
+ p = &stack.v
+ } else {
+ p = (*linkedPairs)(self.p)
}
- return (*Pair)(unsafe.Pointer(uintptr(p) + uintptr(i)*_PAIR_SIZE))
-}
-
-func (self *Node) getParserAndArrayStack() (*Parser, *parseArrayStack) {
- stack := (*parseArrayStack)(self.p)
- ret := (*rt.GoSlice)(unsafe.Pointer(&stack.v))
- ret.Len = self.len()
- ret.Cap = self.cap()
- return &stack.parser, stack
-}
-
-func (self *Node) getParserAndObjectStack() (*Parser, *parseObjectStack) {
- stack := (*parseObjectStack)(self.p)
- ret := (*rt.GoSlice)(unsafe.Pointer(&stack.v))
- ret.Len = self.len()
- ret.Cap = self.cap()
- return &stack.parser, stack
+ return p.At(i)
}
func (self *Node) skipAllIndex() error {
@@ -1194,7 +1195,7 @@ func (self *Node) skipAllIndex() error {
parser, stack := self.getParserAndArrayStack()
parser.skipValue = true
parser.noLazy = true
- *self, err = parser.decodeArray(stack.v)
+ *self, err = parser.decodeArray(&stack.v)
if err != 0 {
return parser.ExportError(err)
}
@@ -1209,7 +1210,7 @@ func (self *Node) skipAllKey() error {
parser, stack := self.getParserAndObjectStack()
parser.skipValue = true
parser.noLazy = true
- *self, err = parser.decodeObject(stack.v)
+ *self, err = parser.decodeObject(&stack.v)
if err != 0 {
return parser.ExportError(err)
}
@@ -1223,21 +1224,16 @@ func (self *Node) skipKey(key string) (*Node, int) {
if nb > 0 {
/* linear search */
var p *Pair
+ var i int
if lazy {
s := (*parseObjectStack)(self.p)
- p = &s.v[0]
+ p, i = s.v.Get(key)
} else {
- p = (*Pair)(self.p)
+ p, i = (*linkedPairs)(self.p).Get(key)
}
- if p.Key == key {
- return &p.Value, 0
- }
- for i := 1; i < nb; i++ {
- p = p.unsafe_next()
- if p.Key == key {
- return &p.Value, i
- }
+ if p != nil {
+ return &p.Value, i
}
}
@@ -1311,7 +1307,7 @@ func (self *Node) loadAllIndex() error {
var err types.ParsingError
parser, stack := self.getParserAndArrayStack()
parser.noLazy = true
- *self, err = parser.decodeArray(stack.v)
+ *self, err = parser.decodeArray(&stack.v)
if err != 0 {
return parser.ExportError(err)
}
@@ -1325,7 +1321,7 @@ func (self *Node) loadAllKey() error {
var err types.ParsingError
parser, stack := self.getParserAndObjectStack()
parser.noLazy = true
- *self, err = parser.decodeObject(stack.v)
+ *self, err = parser.decodeObject(&stack.v)
if err != 0 {
return parser.ExportError(err)
}
@@ -1333,58 +1329,36 @@ func (self *Node) loadAllKey() error {
}
func (self *Node) removeNode(i int) {
- nb := self.len() - 1
node := self.nodeAt(i)
- if i == nb {
- self.setCapAndLen(self.cap(), nb)
- *node = Node{}
+ if node == nil {
return
}
-
- from := self.nodeAt(i + 1)
- memmove(unsafe.Pointer(node), unsafe.Pointer(from), _NODE_SIZE * uintptr(nb - i))
-
- last := self.nodeAt(nb)
- *last = Node{}
-
- self.setCapAndLen(self.cap(), nb)
+ *node = Node{}
+ // NOTICE: for consistency with linkedNodes, we DOSEN'T reduce size here
+ // self.l--
}
func (self *Node) removePair(i int) {
- nb := self.len() - 1
- node := self.pairAt(i)
- if i == nb {
- self.setCapAndLen(self.cap(), nb)
- *node = Pair{}
+ last := self.pairAt(i)
+ if last == nil {
return
}
-
- from := self.pairAt(i + 1)
- memmove(unsafe.Pointer(node), unsafe.Pointer(from), _PAIR_SIZE * uintptr(nb - i))
-
- last := self.pairAt(nb)
*last = Pair{}
-
- self.setCapAndLen(self.cap(), nb)
+ // NOTICE: for consistency with linkedNodes, we DOSEN'T reduce size here
+ // self.l--
}
func (self *Node) toGenericArray() ([]interface{}, error) {
nb := self.len()
- ret := make([]interface{}, nb)
if nb == 0 {
- return ret, nil
+ return []interface{}{}, nil
}
-
+ ret := make([]interface{}, nb)
+
/* convert each item */
- var p = (*Node)(self.p)
- x, err := p.Interface()
- if err != nil {
- return nil, err
- }
- ret[0] = x
-
- for i := 1; i < nb; i++ {
- p = p.unsafe_next()
+ var s = (*linkedNodes)(self.p)
+ for i := 0; i < nb; i++ {
+ p := s.At(i)
x, err := p.Interface()
if err != nil {
return nil, err
@@ -1398,21 +1372,15 @@ func (self *Node) toGenericArray() ([]interface{}, error) {
func (self *Node) toGenericArrayUseNumber() ([]interface{}, error) {
nb := self.len()
- ret := make([]interface{}, nb)
if nb == 0 {
- return ret, nil
+ return []interface{}{}, nil
}
+ ret := make([]interface{}, nb)
/* convert each item */
- var p = (*Node)(self.p)
- x, err := p.InterfaceUseNumber()
- if err != nil {
- return nil, err
- }
- ret[0] = x
-
- for i := 1; i < nb; i++ {
- p = p.unsafe_next()
+ var s = (*linkedNodes)(self.p)
+ for i := 0; i < nb; i++ {
+ p := s.At(i)
x, err := p.InterfaceUseNumber()
if err != nil {
return nil, err
@@ -1426,45 +1394,28 @@ func (self *Node) toGenericArrayUseNumber() ([]interface{}, error) {
func (self *Node) toGenericArrayUseNode() ([]Node, error) {
var nb = self.len()
- var out = make([]Node, nb)
if nb == 0 {
- return out, nil
- }
-
- var p = (*Node)(self.p)
- out[0] = *p
- if err := p.Check(); err != nil {
- return nil, err
+ return []Node{}, nil
}
- for i := 1; i < nb; i++ {
- p = p.unsafe_next()
- if err := p.Check(); err != nil {
- return nil, err
- }
- out[i] = *p
- }
+ var s = (*linkedNodes)(self.p)
+ var out = make([]Node, nb)
+ s.ToSlice(out)
return out, nil
}
func (self *Node) toGenericObject() (map[string]interface{}, error) {
nb := self.len()
- ret := make(map[string]interface{}, nb)
if nb == 0 {
- return ret, nil
+ return map[string]interface{}{}, nil
}
+ ret := make(map[string]interface{}, nb)
/* convert each item */
- var p = (*Pair)(self.p)
- x, err := p.Value.Interface()
- if err != nil {
- return nil, err
- }
- ret[p.Key] = x
-
- for i := 1; i < nb; i++ {
- p = p.unsafe_next()
+ var s = (*linkedPairs)(self.p)
+ for i := 0; i < nb; i++ {
+ p := s.At(i)
x, err := p.Value.Interface()
if err != nil {
return nil, err
@@ -1479,21 +1430,15 @@ func (self *Node) toGenericObject() (map[string]interface{}, error) {
func (self *Node) toGenericObjectUseNumber() (map[string]interface{}, error) {
nb := self.len()
- ret := make(map[string]interface{}, nb)
if nb == 0 {
- return ret, nil
+ return map[string]interface{}{}, nil
}
+ ret := make(map[string]interface{}, nb)
/* convert each item */
- var p = (*Pair)(self.p)
- x, err := p.Value.InterfaceUseNumber()
- if err != nil {
- return nil, err
- }
- ret[p.Key] = x
-
- for i := 1; i < nb; i++ {
- p = p.unsafe_next()
+ var s = (*linkedPairs)(self.p)
+ for i := 0; i < nb; i++ {
+ p := s.At(i)
x, err := p.Value.InterfaceUseNumber()
if err != nil {
return nil, err
@@ -1507,24 +1452,13 @@ func (self *Node) toGenericObjectUseNumber() (map[string]interface{}, error) {
func (self *Node) toGenericObjectUseNode() (map[string]Node, error) {
var nb = self.len()
- var out = make(map[string]Node, nb)
if nb == 0 {
- return out, nil
- }
-
- var p = (*Pair)(self.p)
- out[p.Key] = p.Value
- if err := p.Value.Check(); err != nil {
- return nil, err
+ return map[string]Node{}, nil
}
- for i := 1; i < nb; i++ {
- p = p.unsafe_next()
- if err := p.Value.Check(); err != nil {
- return nil, err
- }
- out[p.Key] = p.Value
- }
+ var s = (*linkedPairs)(self.p)
+ var out = make(map[string]Node, nb)
+ s.ToMap(out)
/* all done */
return out, nil
@@ -1536,15 +1470,12 @@ var (
nullNode = Node{t: types.V_NULL}
trueNode = Node{t: types.V_TRUE}
falseNode = Node{t: types.V_FALSE}
-
- emptyArrayNode = Node{t: types.V_ARRAY}
- emptyObjectNode = Node{t: types.V_OBJECT}
)
// NewRaw creates a node of raw json.
// If the input json is invalid, NewRaw returns a error Node.
func NewRaw(json string) Node {
- parser := NewParser(json)
+ parser := NewParserObj(json)
start, err := parser.skip()
if err != 0 {
return *newError(err, err.Message())
@@ -1567,7 +1498,6 @@ func NewAny(any interface{}) Node {
default:
return Node{
t: _V_ANY,
- v: 0,
p: unsafe.Pointer(&any),
}
}
@@ -1585,7 +1515,6 @@ func NewBytes(src []byte) Node {
// NewNull creates a node of type V_NULL
func NewNull() Node {
return Node{
- v: 0,
p: nil,
t: types.V_NULL,
}
@@ -1600,7 +1529,6 @@ func NewBool(v bool) Node {
t = types.V_TRUE
}
return Node{
- v: 0,
p: nil,
t: t,
}
@@ -1610,26 +1538,30 @@ func NewBool(v bool) Node {
// v must be a decimal string complying with RFC8259
func NewNumber(v string) Node {
return Node{
- v: int64(len(v) & _LEN_MASK),
+ l: uint(len(v)),
p: rt.StrPtr(v),
t: _V_NUMBER,
}
}
-func toNumber(node *Node) json.Number {
- return json.Number(rt.StrFrom(node.p, node.v))
+func (node Node) toNumber() json.Number {
+ return json.Number(rt.StrFrom(node.p, int64(node.l)))
+}
+
+func (self Node) toString() string {
+ return rt.StrFrom(self.p, int64(self.l))
}
-func numberToFloat64(node *Node) (float64, error) {
- ret,err := toNumber(node).Float64()
+func (node Node) toFloat64() (float64, error) {
+ ret, err := node.toNumber().Float64()
if err != nil {
return 0, err
}
return ret, nil
}
-func numberToInt64(node *Node) (int64, error) {
- ret,err := toNumber(node).Int64()
+func (node Node) toInt64() (int64, error) {
+ ret,err := node.toNumber().Int64()
if err != nil {
return 0, err
}
@@ -1640,7 +1572,7 @@ func newBytes(v []byte) Node {
return Node{
t: types.V_STRING,
p: mem2ptr(v),
- v: int64(len(v) & _LEN_MASK),
+ l: uint(len(v)),
}
}
@@ -1652,103 +1584,65 @@ func NewString(v string) Node {
return Node{
t: types.V_STRING,
p: rt.StrPtr(v),
- v: int64(len(v) & _LEN_MASK),
+ l: uint(len(v)),
}
}
// NewArray creates a node of type V_ARRAY,
// using v as its underlying children
func NewArray(v []Node) Node {
+ s := new(linkedNodes)
+ s.FromSlice(v)
+ return newArray(s)
+}
+
+func newArray(v *linkedNodes) Node {
return Node{
t: types.V_ARRAY,
- v: int64(len(v)&_LEN_MASK | cap(v)<<_CAP_BITS),
- p: *(*unsafe.Pointer)(unsafe.Pointer(&v)),
+ l: uint(v.Len()),
+ p: unsafe.Pointer(v),
}
}
-func (self *Node) setArray(v []Node) {
+func (self *Node) setArray(v *linkedNodes) {
self.t = types.V_ARRAY
- self.setCapAndLen(cap(v), len(v))
- self.p = *(*unsafe.Pointer)(unsafe.Pointer(&v))
+ self.l = uint(v.Len())
+ self.p = unsafe.Pointer(v)
}
// NewObject creates a node of type V_OBJECT,
// using v as its underlying children
func NewObject(v []Pair) Node {
- return Node{
- t: types.V_OBJECT,
- v: int64(len(v)&_LEN_MASK | cap(v)<<_CAP_BITS),
- p: *(*unsafe.Pointer)(unsafe.Pointer(&v)),
- }
-}
-
-func (self *Node) setObject(v []Pair) {
- self.t = types.V_OBJECT
- self.setCapAndLen(cap(v), len(v))
- self.p = *(*unsafe.Pointer)(unsafe.Pointer(&v))
-}
-
-type parseObjectStack struct {
- parser Parser
- v []Pair
-}
-
-type parseArrayStack struct {
- parser Parser
- v []Node
-}
-
-func newLazyArray(p *Parser, v []Node) Node {
- s := new(parseArrayStack)
- s.parser = *p
- s.v = v
- return Node{
- t: _V_ARRAY_LAZY,
- v: int64(len(v)&_LEN_MASK | cap(v)<<_CAP_BITS),
- p: unsafe.Pointer(s),
- }
-}
-
-func (self *Node) setLazyArray(p *Parser, v []Node) {
- s := new(parseArrayStack)
- s.parser = *p
- s.v = v
- self.t = _V_ARRAY_LAZY
- self.setCapAndLen(cap(v), len(v))
- self.p = (unsafe.Pointer)(s)
+ s := new(linkedPairs)
+ s.FromSlice(v)
+ return newObject(s)
}
-func newLazyObject(p *Parser, v []Pair) Node {
- s := new(parseObjectStack)
- s.parser = *p
- s.v = v
+func newObject(v *linkedPairs) Node {
return Node{
- t: _V_OBJECT_LAZY,
- v: int64(len(v)&_LEN_MASK | cap(v)<<_CAP_BITS),
- p: unsafe.Pointer(s),
+ t: types.V_OBJECT,
+ l: uint(v.Len()),
+ p: unsafe.Pointer(v),
}
}
-func (self *Node) setLazyObject(p *Parser, v []Pair) {
- s := new(parseObjectStack)
- s.parser = *p
- s.v = v
- self.t = _V_OBJECT_LAZY
- self.setCapAndLen(cap(v), len(v))
- self.p = (unsafe.Pointer)(s)
+func (self *Node) setObject(v *linkedPairs) {
+ self.t = types.V_OBJECT
+ self.l = uint(v.Len())
+ self.p = unsafe.Pointer(v)
}
func newRawNode(str string, typ types.ValueType) Node {
return Node{
t: _V_RAW | typ,
p: rt.StrPtr(str),
- v: int64(len(str) & _LEN_MASK),
+ l: uint(len(str)),
}
}
func (self *Node) parseRaw(full bool) {
- raw := rt.StrFrom(self.p, self.v)
- parser := NewParser(raw)
+ raw := self.toString()
+ parser := NewParserObj(raw)
if full {
parser.noLazy = true
parser.skipValue = false
@@ -1760,14 +1654,6 @@ func (self *Node) parseRaw(full bool) {
}
}
-func newError(err types.ParsingError, msg string) *Node {
- return &Node{
- t: V_ERROR,
- v: int64(err),
- p: unsafe.Pointer(&msg),
- }
-}
-
var typeJumpTable = [256]types.ValueType{
'"' : types.V_STRING,
'-' : _V_NUMBER,
@@ -1791,18 +1677,3 @@ var typeJumpTable = [256]types.ValueType{
func switchRawType(c byte) types.ValueType {
return typeJumpTable[c]
}
-
-func unwrapError(err error) *Node {
- if se, ok := err.(*Node); ok {
- return se
- }else if sse, ok := err.(Node); ok {
- return &sse
- } else {
- msg := err.Error()
- return &Node{
- t: V_ERROR,
- v: 0,
- p: unsafe.Pointer(&msg),
- }
- }
-} \ No newline at end of file
diff --git a/vendor/github.com/bytedance/sonic/ast/parser.go b/vendor/github.com/bytedance/sonic/ast/parser.go
index 0a8e7b068..cb16f20bb 100644
--- a/vendor/github.com/bytedance/sonic/ast/parser.go
+++ b/vendor/github.com/bytedance/sonic/ast/parser.go
@@ -18,11 +18,15 @@ package ast
import (
`fmt`
+
`github.com/bytedance/sonic/internal/native/types`
`github.com/bytedance/sonic/internal/rt`
)
-const _DEFAULT_NODE_CAP int = 16
+const (
+ _DEFAULT_NODE_CAP int = 8
+ _APPEND_GROW_SHIFT = 1
+)
const (
_ERR_NOT_FOUND types.ParsingError = 33
@@ -30,7 +34,10 @@ const (
)
var (
+ // ErrNotExist means both key and value doesn't exist
ErrNotExist error = newError(_ERR_NOT_FOUND, "value not exists")
+
+ // ErrUnsupportType means API on the node is unsupported
ErrUnsupportType error = newError(_ERR_UNSUPPORT_TYPE, "unsupported type")
)
@@ -39,6 +46,7 @@ type Parser struct {
s string
noLazy bool
skipValue bool
+ dbuf *byte
}
/** Parser Private Methods **/
@@ -107,7 +115,7 @@ func (self *Parser) lspace(sp int) int {
return sp
}
-func (self *Parser) decodeArray(ret []Node) (Node, types.ParsingError) {
+func (self *Parser) decodeArray(ret *linkedNodes) (Node, types.ParsingError) {
sp := self.p
ns := len(self.s)
@@ -119,7 +127,7 @@ func (self *Parser) decodeArray(ret []Node) (Node, types.ParsingError) {
/* check for empty array */
if self.s[self.p] == ']' {
self.p++
- return emptyArrayNode, 0
+ return Node{t: types.V_ARRAY}, 0
}
/* allocate array space and parse every element */
@@ -149,7 +157,7 @@ func (self *Parser) decodeArray(ret []Node) (Node, types.ParsingError) {
}
/* add the value to result */
- ret = append(ret, val)
+ ret.Add(val)
self.p = self.lspace(self.p)
/* check for EOF */
@@ -160,17 +168,17 @@ func (self *Parser) decodeArray(ret []Node) (Node, types.ParsingError) {
/* check for the next character */
switch self.s[self.p] {
case ',' : self.p++
- case ']' : self.p++; return NewArray(ret), 0
- default:
- if val.isLazy() {
- return newLazyArray(self, ret), 0
- }
- return Node{}, types.ERR_INVALID_CHAR
+ case ']' : self.p++; return newArray(ret), 0
+ default:
+ // if val.isLazy() {
+ // return newLazyArray(self, ret), 0
+ // }
+ return Node{}, types.ERR_INVALID_CHAR
}
}
}
-func (self *Parser) decodeObject(ret []Pair) (Node, types.ParsingError) {
+func (self *Parser) decodeObject(ret *linkedPairs) (Node, types.ParsingError) {
sp := self.p
ns := len(self.s)
@@ -182,7 +190,7 @@ func (self *Parser) decodeObject(ret []Pair) (Node, types.ParsingError) {
/* check for empty object */
if self.s[self.p] == '}' {
self.p++
- return emptyObjectNode, 0
+ return Node{t: types.V_OBJECT}, 0
}
/* decode each pair */
@@ -235,7 +243,8 @@ func (self *Parser) decodeObject(ret []Pair) (Node, types.ParsingError) {
}
/* add the value to result */
- ret = append(ret, Pair{Key: key, Value: val})
+ // FIXME: ret's address may change here, thus previous referred node in ret may be invalid !!
+ ret.Add(Pair{Key: key, Value: val})
self.p = self.lspace(self.p)
/* check for EOF */
@@ -246,11 +255,11 @@ func (self *Parser) decodeObject(ret []Pair) (Node, types.ParsingError) {
/* check for the next character */
switch self.s[self.p] {
case ',' : self.p++
- case '}' : self.p++; return NewObject(ret), 0
+ case '}' : self.p++; return newObject(ret), 0
default:
- if val.isLazy() {
- return newLazyObject(self, ret), 0
- }
+ // if val.isLazy() {
+ // return newLazyObject(self, ret), 0
+ // }
return Node{}, types.ERR_INVALID_CHAR
}
}
@@ -290,15 +299,23 @@ func (self *Parser) Parse() (Node, types.ParsingError) {
case types.V_FALSE : return falseNode, 0
case types.V_STRING : return self.decodeString(val.Iv, val.Ep)
case types.V_ARRAY:
+ if p := skipBlank(self.s, self.p); p >= self.p && self.s[p] == ']' {
+ self.p = p + 1
+ return Node{t: types.V_ARRAY}, 0
+ }
if self.noLazy {
- return self.decodeArray(make([]Node, 0, _DEFAULT_NODE_CAP))
+ return self.decodeArray(new(linkedNodes))
}
- return newLazyArray(self, make([]Node, 0, _DEFAULT_NODE_CAP)), 0
+ return newLazyArray(self), 0
case types.V_OBJECT:
+ if p := skipBlank(self.s, self.p); p >= self.p && self.s[p] == '}' {
+ self.p = p + 1
+ return Node{t: types.V_OBJECT}, 0
+ }
if self.noLazy {
- return self.decodeObject(make([]Pair, 0, _DEFAULT_NODE_CAP))
+ return self.decodeObject(new(linkedPairs))
}
- return newLazyObject(self, make([]Pair, 0, _DEFAULT_NODE_CAP)), 0
+ return newLazyObject(self), 0
case types.V_DOUBLE : return NewNumber(self.s[val.Ep:self.p]), 0
case types.V_INTEGER : return NewNumber(self.s[val.Ep:self.p]), 0
default : return Node{}, types.ParsingError(-val.Vt)
@@ -429,7 +446,7 @@ func (self *Node) skipNextNode() *Node {
}
parser, stack := self.getParserAndArrayStack()
- ret := stack.v
+ ret := &stack.v
sp := parser.p
ns := len(parser.s)
@@ -458,7 +475,8 @@ func (self *Node) skipNextNode() *Node {
}
/* add the value to result */
- ret = append(ret, val)
+ ret.Add(val)
+ self.l++
parser.p = parser.lspace(parser.p)
/* check for EOF */
@@ -470,12 +488,11 @@ func (self *Node) skipNextNode() *Node {
switch parser.s[parser.p] {
case ',':
parser.p++
- self.setLazyArray(parser, ret)
- return &ret[len(ret)-1]
+ return ret.At(ret.Len()-1)
case ']':
parser.p++
self.setArray(ret)
- return &ret[len(ret)-1]
+ return ret.At(ret.Len()-1)
default:
return newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR))
}
@@ -487,7 +504,7 @@ func (self *Node) skipNextPair() (*Pair) {
}
parser, stack := self.getParserAndObjectStack()
- ret := stack.v
+ ret := &stack.v
sp := parser.p
ns := len(parser.s)
@@ -541,7 +558,8 @@ func (self *Node) skipNextPair() (*Pair) {
}
/* add the value to result */
- ret = append(ret, Pair{Key: key, Value: val})
+ ret.Add(Pair{Key: key, Value: val})
+ self.l++
parser.p = parser.lspace(parser.p)
/* check for EOF */
@@ -553,12 +571,11 @@ func (self *Node) skipNextPair() (*Pair) {
switch parser.s[parser.p] {
case ',':
parser.p++
- self.setLazyObject(parser, ret)
- return &ret[len(ret)-1]
+ return ret.At(ret.Len()-1)
case '}':
parser.p++
self.setObject(ret)
- return &ret[len(ret)-1]
+ return ret.At(ret.Len()-1)
default:
return &Pair{key, *newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR))}
}
@@ -601,10 +618,30 @@ func LoadsUseNumber(src string) (int, interface{}, error) {
}
}
+// NewParser returns pointer of new allocated parser
func NewParser(src string) *Parser {
return &Parser{s: src}
}
+// NewParser returns new allocated parser
+func NewParserObj(src string) Parser {
+ return Parser{s: src}
+}
+
+// decodeNumber controls if parser decodes the number values instead of skip them
+// WARN: once you set decodeNumber(true), please set decodeNumber(false) before you drop the parser
+// otherwise the memory CANNOT be reused
+func (self *Parser) decodeNumber(decode bool) {
+ if !decode && self.dbuf != nil {
+ types.FreeDbuf(self.dbuf)
+ self.dbuf = nil
+ return
+ }
+ if decode && self.dbuf == nil {
+ self.dbuf = types.NewDbuf()
+ }
+}
+
// ExportError converts types.ParsingError to std Error
func (self *Parser) ExportError(err types.ParsingError) error {
if err == _ERR_NOT_FOUND {
@@ -615,4 +652,4 @@ func (self *Parser) ExportError(err types.ParsingError) error {
Src : self.s,
Code: err,
}.Description())
-} \ No newline at end of file
+}
diff --git a/vendor/github.com/bytedance/sonic/ast/sort.go b/vendor/github.com/bytedance/sonic/ast/sort.go
deleted file mode 100644
index 0a9f14559..000000000
--- a/vendor/github.com/bytedance/sonic/ast/sort.go
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright 2021 ByteDance Inc.
- *
- * Licensed 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 ast
-
-// Algorithm 3-way Radix Quicksort, d means the radix.
-// Reference: https://algs4.cs.princeton.edu/51radix/Quick3string.java.html
-func radixQsort(kvs PairSlice, d, maxDepth int) {
- for len(kvs) > 11 {
- // To avoid the worst case of quickSort (time: O(n^2)), use introsort here.
- // Reference: https://en.wikipedia.org/wiki/Introsort and
- // https://github.com/golang/go/issues/467
- if maxDepth == 0 {
- heapSort(kvs, 0, len(kvs))
- return
- }
- maxDepth--
-
- p := pivot(kvs, d)
- lt, i, gt := 0, 0, len(kvs)
- for i < gt {
- c := byteAt(kvs[i].Key, d)
- if c < p {
- swap(kvs, lt, i)
- i++
- lt++
- } else if c > p {
- gt--
- swap(kvs, i, gt)
- } else {
- i++
- }
- }
-
- // kvs[0:lt] < v = kvs[lt:gt] < kvs[gt:len(kvs)]
- // Native implemention:
- // radixQsort(kvs[:lt], d, maxDepth)
- // if p > -1 {
- // radixQsort(kvs[lt:gt], d+1, maxDepth)
- // }
- // radixQsort(kvs[gt:], d, maxDepth)
- // Optimize as follows: make recursive calls only for the smaller parts.
- // Reference: https://www.geeksforgeeks.org/quicksort-tail-call-optimization-reducing-worst-case-space-log-n/
- if p == -1 {
- if lt > len(kvs) - gt {
- radixQsort(kvs[gt:], d, maxDepth)
- kvs = kvs[:lt]
- } else {
- radixQsort(kvs[:lt], d, maxDepth)
- kvs = kvs[gt:]
- }
- } else {
- ml := maxThree(lt, gt-lt, len(kvs)-gt)
- if ml == lt {
- radixQsort(kvs[lt:gt], d+1, maxDepth)
- radixQsort(kvs[gt:], d, maxDepth)
- kvs = kvs[:lt]
- } else if ml == gt-lt {
- radixQsort(kvs[:lt], d, maxDepth)
- radixQsort(kvs[gt:], d, maxDepth)
- kvs = kvs[lt:gt]
- d += 1
- } else {
- radixQsort(kvs[:lt], d, maxDepth)
- radixQsort(kvs[lt:gt], d+1, maxDepth)
- kvs = kvs[gt:]
- }
- }
- }
- insertRadixSort(kvs, d)
-}
-
-func insertRadixSort(kvs PairSlice, d int) {
- for i := 1; i < len(kvs); i++ {
- for j := i; j > 0 && lessFrom(kvs[j].Key, kvs[j-1].Key, d); j-- {
- swap(kvs, j, j-1)
- }
- }
-}
-
-func pivot(kvs PairSlice, d int) int {
- m := len(kvs) >> 1
- if len(kvs) > 40 {
- // Tukey's ``Ninther,'' median of three mediankvs of three.
- t := len(kvs) / 8
- return medianThree(
- medianThree(byteAt(kvs[0].Key, d), byteAt(kvs[t].Key, d), byteAt(kvs[2*t].Key, d)),
- medianThree(byteAt(kvs[m].Key, d), byteAt(kvs[m-t].Key, d), byteAt(kvs[m+t].Key, d)),
- medianThree(byteAt(kvs[len(kvs)-1].Key, d),
- byteAt(kvs[len(kvs)-1-t].Key, d),
- byteAt(kvs[len(kvs)-1-2*t].Key, d)))
- }
- return medianThree(byteAt(kvs[0].Key, d), byteAt(kvs[m].Key, d), byteAt(kvs[len(kvs)-1].Key, d))
-}
-
-func medianThree(i, j, k int) int {
- if i > j {
- i, j = j, i
- } // i < j
- if k < i {
- return i
- }
- if k > j {
- return j
- }
- return k
-}
-
-func maxThree(i, j, k int) int {
- max := i
- if max < j {
- max = j
- }
- if max < k {
- max = k
- }
- return max
-}
-
-// maxDepth returns a threshold at which quicksort should switch
-// to heapsort. It returnkvs 2*ceil(lg(n+1)).
-func maxDepth(n int) int {
- var depth int
- for i := n; i > 0; i >>= 1 {
- depth++
- }
- return depth * 2
-}
-
-// siftDown implements the heap property on kvs[lo:hi].
-// first is an offset into the array where the root of the heap lies.
-func siftDown(kvs PairSlice, lo, hi, first int) {
- root := lo
- for {
- child := 2*root + 1
- if child >= hi {
- break
- }
- if child+1 < hi && kvs[first+child].Key < kvs[first+child+1].Key {
- child++
- }
- if kvs[first+root].Key >= kvs[first+child].Key {
- return
- }
- swap(kvs, first+root, first+child)
- root = child
- }
-}
-
-func heapSort(kvs PairSlice, a, b int) {
- first := a
- lo := 0
- hi := b - a
-
- // Build heap with the greatest element at top.
- for i := (hi - 1) / 2; i >= 0; i-- {
- siftDown(kvs, i, hi, first)
- }
-
- // Pop elements, the largest first, into end of kvs.
- for i := hi - 1; i >= 0; i-- {
- swap(kvs, first, first+i)
- siftDown(kvs, lo, i, first)
- }
-}
-
-// Note that Pair.Key is NOT pointed to Pair.m when map key is integer after swap
-func swap(kvs PairSlice, a, b int) {
- kvs[a].Key, kvs[b].Key = kvs[b].Key, kvs[a].Key
- kvs[a].Value, kvs[b].Value = kvs[b].Value, kvs[a].Value
-}
-
-// Compare two strings from the pos d.
-func lessFrom(a, b string, d int) bool {
- l := len(a)
- if l > len(b) {
- l = len(b)
- }
- for i := d; i < l; i++ {
- if a[i] == b[i] {
- continue
- }
- return a[i] < b[i]
- }
- return len(a) < len(b)
-}
-
-func byteAt(b string, p int) int {
- if p < len(b) {
- return int(b[p])
- }
- return -1
-}
diff --git a/vendor/github.com/bytedance/sonic/ast/stubs_go120.go b/vendor/github.com/bytedance/sonic/ast/stubs_go120.go
index bd6fff680..6f830529d 100644
--- a/vendor/github.com/bytedance/sonic/ast/stubs_go120.go
+++ b/vendor/github.com/bytedance/sonic/ast/stubs_go120.go
@@ -52,4 +52,4 @@ var (
)
//go:linkname unquoteBytes encoding/json.unquoteBytes
-func unquoteBytes(s []byte) (t []byte, ok bool) \ No newline at end of file
+func unquoteBytes(s []byte) (t []byte, ok bool)
diff --git a/vendor/github.com/bytedance/sonic/ast/visitor.go b/vendor/github.com/bytedance/sonic/ast/visitor.go
new file mode 100644
index 000000000..4019c31a2
--- /dev/null
+++ b/vendor/github.com/bytedance/sonic/ast/visitor.go
@@ -0,0 +1,315 @@
+/*
+ * Copyright 2021 ByteDance Inc.
+ *
+ * Licensed 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 ast
+
+import (
+ `encoding/json`
+
+ `github.com/bytedance/sonic/internal/native/types`
+)
+
+// Visitor handles the callbacks during preorder traversal of a JSON AST.
+//
+// According to the JSON RFC8259, a JSON AST can be defined by
+// the following rules without seperator / whitespace tokens.
+//
+// JSON-AST = value
+// value = false / null / true / object / array / number / string
+// object = begin-object [ member *( member ) ] end-object
+// member = string value
+// array = begin-array [ value *( value ) ] end-array
+//
+type Visitor interface {
+
+ // OnNull handles a JSON null value.
+ OnNull() error
+
+ // OnBool handles a JSON true / false value.
+ OnBool(v bool) error
+
+ // OnString handles a JSON string value.
+ OnString(v string) error
+
+ // OnInt64 handles a JSON number value with int64 type.
+ OnInt64(v int64, n json.Number) error
+
+ // OnFloat64 handles a JSON number value with float64 type.
+ OnFloat64(v float64, n json.Number) error
+
+ // OnObjectBegin handles the beginning of a JSON object value with a
+ // suggested capacity that can be used to make your custom object container.
+ //
+ // After this point the visitor will receive a sequence of callbacks like
+ // [string, value, string, value, ......, ObjectEnd].
+ //
+ // Note:
+ // 1. This is a recursive definition which means the value can
+ // also be a JSON object / array described by a sequence of callbacks.
+ // 2. The suggested capacity will be 0 if current object is empty.
+ // 3. Currently sonic use a fixed capacity for non-empty object (keep in
+ // sync with ast.Node) which might not be very suitable. This may be
+ // improved in future version.
+ OnObjectBegin(capacity int) error
+
+ // OnObjectKey handles a JSON object key string in member.
+ OnObjectKey(key string) error
+
+ // OnObjectEnd handles the ending of a JSON object value.
+ OnObjectEnd() error
+
+ // OnArrayBegin handles the beginning of a JSON array value with a
+ // suggested capacity that can be used to make your custom array container.
+ //
+ // After this point the visitor will receive a sequence of callbacks like
+ // [value, value, value, ......, ArrayEnd].
+ //
+ // Note:
+ // 1. This is a recursive definition which means the value can
+ // also be a JSON object / array described by a sequence of callbacks.
+ // 2. The suggested capacity will be 0 if current array is empty.
+ // 3. Currently sonic use a fixed capacity for non-empty array (keep in
+ // sync with ast.Node) which might not be very suitable. This may be
+ // improved in future version.
+ OnArrayBegin(capacity int) error
+
+ // OnArrayEnd handles the ending of a JSON array value.
+ OnArrayEnd() error
+}
+
+// VisitorOptions contains all Visitor's options. The default value is an
+// empty VisitorOptions{}.
+type VisitorOptions struct {
+ // OnlyNumber indicates parser to directly return number value without
+ // conversion, then the first argument of OnInt64 / OnFloat64 will always
+ // be zero.
+ OnlyNumber bool
+}
+
+var defaultVisitorOptions = &VisitorOptions{}
+
+// Preorder decodes the whole JSON string and callbacks each AST node to visitor
+// during preorder traversal. Any visitor method with an error returned will
+// break the traversal and the given error will be directly returned. The opts
+// argument can be reused after every call.
+func Preorder(str string, visitor Visitor, opts *VisitorOptions) error {
+ if opts == nil {
+ opts = defaultVisitorOptions
+ }
+ // process VisitorOptions first to guarantee that all options will be
+ // constant during decoding and make options more readable.
+ var (
+ optDecodeNumber = !opts.OnlyNumber
+ )
+
+ tv := &traverser{
+ parser: Parser{
+ s: str,
+ noLazy: true,
+ skipValue: false,
+ },
+ visitor: visitor,
+ }
+
+ if optDecodeNumber {
+ tv.parser.decodeNumber(true)
+ }
+
+ err := tv.decodeValue()
+
+ if optDecodeNumber {
+ tv.parser.decodeNumber(false)
+ }
+ return err
+}
+
+type traverser struct {
+ parser Parser
+ visitor Visitor
+}
+
+// NOTE: keep in sync with (*Parser).Parse method.
+func (self *traverser) decodeValue() error {
+ switch val := self.parser.decodeValue(); val.Vt {
+ case types.V_EOF:
+ return types.ERR_EOF
+ case types.V_NULL:
+ return self.visitor.OnNull()
+ case types.V_TRUE:
+ return self.visitor.OnBool(true)
+ case types.V_FALSE:
+ return self.visitor.OnBool(false)
+ case types.V_STRING:
+ return self.decodeString(val.Iv, val.Ep)
+ case types.V_DOUBLE:
+ return self.visitor.OnFloat64(val.Dv,
+ json.Number(self.parser.s[val.Ep:self.parser.p]))
+ case types.V_INTEGER:
+ return self.visitor.OnInt64(val.Iv,
+ json.Number(self.parser.s[val.Ep:self.parser.p]))
+ case types.V_ARRAY:
+ return self.decodeArray()
+ case types.V_OBJECT:
+ return self.decodeObject()
+ default:
+ return types.ParsingError(-val.Vt)
+ }
+}
+
+// NOTE: keep in sync with (*Parser).decodeArray method.
+func (self *traverser) decodeArray() error {
+ sp := self.parser.p
+ ns := len(self.parser.s)
+
+ /* check for EOF */
+ self.parser.p = self.parser.lspace(sp)
+ if self.parser.p >= ns {
+ return types.ERR_EOF
+ }
+
+ /* check for empty array */
+ if self.parser.s[self.parser.p] == ']' {
+ self.parser.p++
+ if err := self.visitor.OnArrayBegin(0); err != nil {
+ return err
+ }
+ return self.visitor.OnArrayEnd()
+ }
+
+ /* allocate array space and parse every element */
+ if err := self.visitor.OnArrayBegin(_DEFAULT_NODE_CAP); err != nil {
+ return err
+ }
+ for {
+ /* decode the value */
+ if err := self.decodeValue(); err != nil {
+ return err
+ }
+ self.parser.p = self.parser.lspace(self.parser.p)
+
+ /* check for EOF */
+ if self.parser.p >= ns {
+ return types.ERR_EOF
+ }
+
+ /* check for the next character */
+ switch self.parser.s[self.parser.p] {
+ case ',':
+ self.parser.p++
+ case ']':
+ self.parser.p++
+ return self.visitor.OnArrayEnd()
+ default:
+ return types.ERR_INVALID_CHAR
+ }
+ }
+}
+
+// NOTE: keep in sync with (*Parser).decodeObject method.
+func (self *traverser) decodeObject() error {
+ sp := self.parser.p
+ ns := len(self.parser.s)
+
+ /* check for EOF */
+ self.parser.p = self.parser.lspace(sp)
+ if self.parser.p >= ns {
+ return types.ERR_EOF
+ }
+
+ /* check for empty object */
+ if self.parser.s[self.parser.p] == '}' {
+ self.parser.p++
+ if err := self.visitor.OnObjectBegin(0); err != nil {
+ return err
+ }
+ return self.visitor.OnObjectEnd()
+ }
+
+ /* allocate object space and decode each pair */
+ if err := self.visitor.OnObjectBegin(_DEFAULT_NODE_CAP); err != nil {
+ return err
+ }
+ for {
+ var njs types.JsonState
+ var err types.ParsingError
+
+ /* decode the key */
+ if njs = self.parser.decodeValue(); njs.Vt != types.V_STRING {
+ return types.ERR_INVALID_CHAR
+ }
+
+ /* extract the key */
+ idx := self.parser.p - 1
+ key := self.parser.s[njs.Iv:idx]
+
+ /* check for escape sequence */
+ if njs.Ep != -1 {
+ if key, err = unquote(key); err != 0 {
+ return err
+ }
+ }
+
+ if err := self.visitor.OnObjectKey(key); err != nil {
+ return err
+ }
+
+ /* expect a ':' delimiter */
+ if err = self.parser.delim(); err != 0 {
+ return err
+ }
+
+ /* decode the value */
+ if err := self.decodeValue(); err != nil {
+ return err
+ }
+
+ self.parser.p = self.parser.lspace(self.parser.p)
+
+ /* check for EOF */
+ if self.parser.p >= ns {
+ return types.ERR_EOF
+ }
+
+ /* check for the next character */
+ switch self.parser.s[self.parser.p] {
+ case ',':
+ self.parser.p++
+ case '}':
+ self.parser.p++
+ return self.visitor.OnObjectEnd()
+ default:
+ return types.ERR_INVALID_CHAR
+ }
+ }
+}
+
+// NOTE: keep in sync with (*Parser).decodeString method.
+func (self *traverser) decodeString(iv int64, ep int) error {
+ p := self.parser.p - 1
+ s := self.parser.s[iv:p]
+
+ /* fast path: no escape sequence */
+ if ep == -1 {
+ return self.visitor.OnString(s)
+ }
+
+ /* unquote the string */
+ out, err := unquote(s)
+ if err != 0 {
+ return err
+ }
+ return self.visitor.OnString(out)
+}