/** * 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= _DEFAULT_NODE_CAP && i= self.size || target < 0 || target >= self.size { return } // reserve source n := *self.At(source) if source < target { // move every element (source,target] one step back for i:=source; itarget; i-- { *self.At(i) = *self.At(i-1) } } // set target *self.At(target) = n } func (self *linkedNodes) Pop() { if self == nil || self.size == 0 { return } self.Set(self.size-1, Node{}) self.size-- } func (self *linkedPairs) Pop() { if self == nil || self.size == 0 { return } self.Set(self.size-1, Pair{}) self.size-- } func (self *linkedNodes) Push(v Node) { self.Set(self.size, v) } func (self *linkedNodes) Set(i int, v Node) { if i < _DEFAULT_NODE_CAP { self.head[i] = v if self.size <= i { self.size = i+1 } return } a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP if a < 0 { self.head[b] = v } else { self.growTailLength(a+1) var n = &self.tail[a] if *n == nil { *n = new(nodeChunk) } (*n)[b] = v } if self.size <= i { self.size = i+1 } } func (self *linkedNodes) growTailLength(l int) { if l <= len(self.tail) { return } c := cap(self.tail) for c < l { c += 1 + c>>_APPEND_GROW_SHIFT } if c == cap(self.tail) { self.tail = self.tail[:l] return } tmp := make([]*nodeChunk, l, c) copy(tmp, self.tail) self.tail = tmp } 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>_APPEND_GROW_SHIFT self.tail = make([]*nodeChunk, a+1, c) } self.tail = self.tail[:a+1] for i:=0; i= 0 && i < _DEFAULT_NODE_CAP && i= _DEFAULT_NODE_CAP && i>_APPEND_GROW_SHIFT } if c == cap(self.tail) { self.tail = self.tail[:l] return } tmp := make([]*pairChunk, l, c) copy(tmp, self.tail) self.tail = tmp } // linear search func (self *linkedPairs) Get(key string) (*Pair, int) { for i:=0; i>_APPEND_GROW_SHIFT self.tail = make([]*pairChunk, a+1, c) } self.tail = self.tail[:a+1] for i:=0; i 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 }