forked from mirror/go-json
Optimize map operation
This commit is contained in:
parent
0be236361a
commit
02797daba4
56
encode_vm.go
56
encode_vm.go
|
@ -378,11 +378,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) (
|
||||||
store(ctxptr, code.length, uintptr(mlen))
|
store(ctxptr, code.length, uintptr(mlen))
|
||||||
store(ctxptr, code.mapIter, uintptr(iter))
|
store(ctxptr, code.mapIter, uintptr(iter))
|
||||||
if !e.unorderedMap {
|
if !e.unorderedMap {
|
||||||
pos := make([]int, 0, mlen)
|
mapCtx := newMapContext(mlen)
|
||||||
pos = append(pos, len(b))
|
mapCtx.pos = append(mapCtx.pos, len(b))
|
||||||
posPtr := unsafe.Pointer(&pos)
|
ctx.keepRefs = append(ctx.keepRefs, unsafe.Pointer(mapCtx))
|
||||||
ctx.keepRefs = append(ctx.keepRefs, posPtr)
|
store(ctxptr, code.end.mapPos, uintptr(unsafe.Pointer(mapCtx)))
|
||||||
store(ctxptr, code.end.mapPos, uintptr(posPtr))
|
|
||||||
}
|
}
|
||||||
key := mapiterkey(iter)
|
key := mapiterkey(iter)
|
||||||
store(ctxptr, code.next.idx, uintptr(key))
|
store(ctxptr, code.next.idx, uintptr(key))
|
||||||
|
@ -419,11 +418,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) (
|
||||||
key := mapiterkey(iter)
|
key := mapiterkey(iter)
|
||||||
store(ctxptr, code.next.idx, uintptr(key))
|
store(ctxptr, code.next.idx, uintptr(key))
|
||||||
if !e.unorderedMap {
|
if !e.unorderedMap {
|
||||||
pos := make([]int, 0, mlen)
|
mapCtx := newMapContext(mlen)
|
||||||
pos = append(pos, len(b))
|
mapCtx.pos = append(mapCtx.pos, len(b))
|
||||||
posPtr := unsafe.Pointer(&pos)
|
ctx.keepRefs = append(ctx.keepRefs, unsafe.Pointer(mapCtx))
|
||||||
ctx.keepRefs = append(ctx.keepRefs, posPtr)
|
store(ctxptr, code.end.mapPos, uintptr(unsafe.Pointer(mapCtx)))
|
||||||
store(ctxptr, code.end.mapPos, uintptr(posPtr))
|
|
||||||
}
|
}
|
||||||
code = code.next
|
code = code.next
|
||||||
} else {
|
} else {
|
||||||
|
@ -451,8 +449,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) (
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ptr := load(ctxptr, code.end.mapPos)
|
ptr := load(ctxptr, code.end.mapPos)
|
||||||
posPtr := (*[]int)(*(*unsafe.Pointer)(unsafe.Pointer(&ptr)))
|
mapCtx := (*encodeMapContext)(e.ptrToUnsafePtr(ptr))
|
||||||
*posPtr = append(*posPtr, len(b))
|
mapCtx.pos = append(mapCtx.pos, len(b))
|
||||||
if idx < length {
|
if idx < length {
|
||||||
ptr := load(ctxptr, code.mapIter)
|
ptr := load(ctxptr, code.mapIter)
|
||||||
iter := e.ptrToUnsafePtr(ptr)
|
iter := e.ptrToUnsafePtr(ptr)
|
||||||
|
@ -470,8 +468,8 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) (
|
||||||
b[last] = ':'
|
b[last] = ':'
|
||||||
} else {
|
} else {
|
||||||
ptr := load(ctxptr, code.end.mapPos)
|
ptr := load(ctxptr, code.end.mapPos)
|
||||||
posPtr := (*[]int)(*(*unsafe.Pointer)(unsafe.Pointer(&ptr)))
|
mapCtx := (*encodeMapContext)(e.ptrToUnsafePtr(ptr))
|
||||||
*posPtr = append(*posPtr, len(b))
|
mapCtx.pos = append(mapCtx.pos, len(b))
|
||||||
}
|
}
|
||||||
ptr := load(ctxptr, code.mapIter)
|
ptr := load(ctxptr, code.mapIter)
|
||||||
iter := e.ptrToUnsafePtr(ptr)
|
iter := e.ptrToUnsafePtr(ptr)
|
||||||
|
@ -482,14 +480,9 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) (
|
||||||
case opMapEnd:
|
case opMapEnd:
|
||||||
// this operation only used by sorted map.
|
// this operation only used by sorted map.
|
||||||
length := int(load(ctxptr, code.length))
|
length := int(load(ctxptr, code.length))
|
||||||
type mapKV struct {
|
|
||||||
key string
|
|
||||||
value string
|
|
||||||
}
|
|
||||||
kvs := make([]mapKV, 0, length)
|
|
||||||
ptr := load(ctxptr, code.mapPos)
|
ptr := load(ctxptr, code.mapPos)
|
||||||
posPtr := e.ptrToUnsafePtr(ptr)
|
mapCtx := (*encodeMapContext)(e.ptrToUnsafePtr(ptr))
|
||||||
pos := *(*[]int)(posPtr)
|
pos := mapCtx.pos
|
||||||
for i := 0; i < length; i++ {
|
for i := 0; i < length; i++ {
|
||||||
startKey := pos[i*2]
|
startKey := pos[i*2]
|
||||||
startValue := pos[i*2+1]
|
startValue := pos[i*2+1]
|
||||||
|
@ -499,25 +492,24 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) (
|
||||||
} else {
|
} else {
|
||||||
endValue = len(b)
|
endValue = len(b)
|
||||||
}
|
}
|
||||||
kvs = append(kvs, mapKV{
|
mapCtx.slice.items = append(mapCtx.slice.items, mapItem{
|
||||||
key: string(b[startKey:startValue]),
|
key: b[startKey:startValue],
|
||||||
value: string(b[startValue:endValue]),
|
value: b[startValue:endValue],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
sort.Slice(kvs, func(i, j int) bool {
|
sort.Sort(mapCtx.slice)
|
||||||
return kvs[i].key < kvs[j].key
|
buf := mapCtx.buf
|
||||||
})
|
for _, item := range mapCtx.slice.items {
|
||||||
buf := b[pos[0]:]
|
buf = append(buf, item.key...)
|
||||||
buf = buf[:0]
|
|
||||||
for _, kv := range kvs {
|
|
||||||
buf = append(buf, []byte(kv.key)...)
|
|
||||||
buf[len(buf)-1] = ':'
|
buf[len(buf)-1] = ':'
|
||||||
buf = append(buf, []byte(kv.value)...)
|
buf = append(buf, item.value...)
|
||||||
}
|
}
|
||||||
buf[len(buf)-1] = '}'
|
buf[len(buf)-1] = '}'
|
||||||
buf = append(buf, ',')
|
buf = append(buf, ',')
|
||||||
b = b[:pos[0]]
|
b = b[:pos[0]]
|
||||||
b = append(b, buf...)
|
b = append(b, buf...)
|
||||||
|
mapCtx.buf = buf
|
||||||
|
releaseMapContext(mapCtx)
|
||||||
code = code.next
|
code = code.next
|
||||||
case opStructFieldPtrAnonymousHeadRecursive:
|
case opStructFieldPtrAnonymousHeadRecursive:
|
||||||
store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
|
store(ctxptr, code.idx, e.ptrToPtr(load(ctxptr, code.idx)))
|
||||||
|
|
|
@ -460,15 +460,17 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcod
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
sort.Sort(mapCtx.slice)
|
sort.Sort(mapCtx.slice)
|
||||||
|
buf := mapCtx.buf
|
||||||
for _, item := range mapCtx.slice.items {
|
for _, item := range mapCtx.slice.items {
|
||||||
mapCtx.buf = append(mapCtx.buf, item.key...)
|
buf = append(buf, item.key...)
|
||||||
mapCtx.buf[len(mapCtx.buf)-1] = ':'
|
buf[len(buf)-1] = ':'
|
||||||
mapCtx.buf = append(mapCtx.buf, item.value...)
|
buf = append(buf, item.value...)
|
||||||
}
|
}
|
||||||
mapCtx.buf[len(mapCtx.buf)-1] = '}'
|
buf[len(buf)-1] = '}'
|
||||||
mapCtx.buf = append(mapCtx.buf, ',')
|
buf = append(buf, ',')
|
||||||
b = b[:pos[0]]
|
b = b[:pos[0]]
|
||||||
b = append(b, mapCtx.buf...)
|
b = append(b, buf...)
|
||||||
|
mapCtx.buf = buf
|
||||||
releaseMapContext(mapCtx)
|
releaseMapContext(mapCtx)
|
||||||
code = code.next
|
code = code.next
|
||||||
case opStructFieldPtrAnonymousHeadRecursive:
|
case opStructFieldPtrAnonymousHeadRecursive:
|
||||||
|
|
|
@ -405,11 +405,10 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet
|
||||||
store(ctxptr, code.mapIter, uintptr(iter))
|
store(ctxptr, code.mapIter, uintptr(iter))
|
||||||
|
|
||||||
if !e.unorderedMap {
|
if !e.unorderedMap {
|
||||||
pos := make([]int, 0, mlen)
|
mapCtx := newMapContext(mlen)
|
||||||
pos = append(pos, len(b))
|
mapCtx.pos = append(mapCtx.pos, len(b))
|
||||||
posPtr := unsafe.Pointer(&pos)
|
ctx.keepRefs = append(ctx.keepRefs, unsafe.Pointer(mapCtx))
|
||||||
ctx.keepRefs = append(ctx.keepRefs, posPtr)
|
store(ctxptr, code.end.mapPos, uintptr(unsafe.Pointer(mapCtx)))
|
||||||
store(ctxptr, code.end.mapPos, uintptr(posPtr))
|
|
||||||
} else {
|
} else {
|
||||||
b = e.encodeIndent(b, code.next.indent)
|
b = e.encodeIndent(b, code.next.indent)
|
||||||
}
|
}
|
||||||
|
@ -452,11 +451,10 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet
|
||||||
store(ctxptr, code.next.idx, uintptr(key))
|
store(ctxptr, code.next.idx, uintptr(key))
|
||||||
|
|
||||||
if !e.unorderedMap {
|
if !e.unorderedMap {
|
||||||
pos := make([]int, 0, mlen)
|
mapCtx := newMapContext(mlen)
|
||||||
pos = append(pos, len(b))
|
mapCtx.pos = append(mapCtx.pos, len(b))
|
||||||
posPtr := unsafe.Pointer(&pos)
|
ctx.keepRefs = append(ctx.keepRefs, unsafe.Pointer(mapCtx))
|
||||||
ctx.keepRefs = append(ctx.keepRefs, posPtr)
|
store(ctxptr, code.end.mapPos, uintptr(unsafe.Pointer(mapCtx)))
|
||||||
store(ctxptr, code.end.mapPos, uintptr(posPtr))
|
|
||||||
} else {
|
} else {
|
||||||
b = e.encodeIndent(b, code.next.indent)
|
b = e.encodeIndent(b, code.next.indent)
|
||||||
}
|
}
|
||||||
|
@ -490,8 +488,8 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ptr := load(ctxptr, code.end.mapPos)
|
ptr := load(ctxptr, code.end.mapPos)
|
||||||
posPtr := (*[]int)(*(*unsafe.Pointer)(unsafe.Pointer(&ptr)))
|
mapCtx := (*encodeMapContext)(e.ptrToUnsafePtr(ptr))
|
||||||
*posPtr = append(*posPtr, len(b))
|
mapCtx.pos = append(mapCtx.pos, len(b))
|
||||||
if idx < length {
|
if idx < length {
|
||||||
ptr := load(ctxptr, code.mapIter)
|
ptr := load(ctxptr, code.mapIter)
|
||||||
iter := e.ptrToUnsafePtr(ptr)
|
iter := e.ptrToUnsafePtr(ptr)
|
||||||
|
@ -508,8 +506,8 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet
|
||||||
b = append(b, ':', ' ')
|
b = append(b, ':', ' ')
|
||||||
} else {
|
} else {
|
||||||
ptr := load(ctxptr, code.end.mapPos)
|
ptr := load(ctxptr, code.end.mapPos)
|
||||||
posPtr := (*[]int)(*(*unsafe.Pointer)(unsafe.Pointer(&ptr)))
|
mapCtx := (*encodeMapContext)(e.ptrToUnsafePtr(ptr))
|
||||||
*posPtr = append(*posPtr, len(b))
|
mapCtx.pos = append(mapCtx.pos, len(b))
|
||||||
}
|
}
|
||||||
ptr := load(ctxptr, code.mapIter)
|
ptr := load(ctxptr, code.mapIter)
|
||||||
iter := e.ptrToUnsafePtr(ptr)
|
iter := e.ptrToUnsafePtr(ptr)
|
||||||
|
@ -520,13 +518,9 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet
|
||||||
case opMapEnd:
|
case opMapEnd:
|
||||||
// this operation only used by sorted map
|
// this operation only used by sorted map
|
||||||
length := int(load(ctxptr, code.length))
|
length := int(load(ctxptr, code.length))
|
||||||
type mapKV struct {
|
|
||||||
key string
|
|
||||||
value string
|
|
||||||
}
|
|
||||||
kvs := make([]mapKV, 0, length)
|
|
||||||
ptr := load(ctxptr, code.mapPos)
|
ptr := load(ctxptr, code.mapPos)
|
||||||
pos := *(*[]int)(*(*unsafe.Pointer)(unsafe.Pointer(&ptr)))
|
mapCtx := (*encodeMapContext)(e.ptrToUnsafePtr(ptr))
|
||||||
|
pos := mapCtx.pos
|
||||||
for i := 0; i < length; i++ {
|
for i := 0; i < length; i++ {
|
||||||
startKey := pos[i*2]
|
startKey := pos[i*2]
|
||||||
startValue := pos[i*2+1]
|
startValue := pos[i*2+1]
|
||||||
|
@ -536,33 +530,31 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet
|
||||||
} else {
|
} else {
|
||||||
endValue = len(b)
|
endValue = len(b)
|
||||||
}
|
}
|
||||||
kvs = append(kvs, mapKV{
|
mapCtx.slice.items = append(mapCtx.slice.items, mapItem{
|
||||||
key: string(b[startKey:startValue]),
|
key: b[startKey:startValue],
|
||||||
value: string(b[startValue:endValue]),
|
value: b[startValue:endValue],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
sort.Slice(kvs, func(i, j int) bool {
|
sort.Sort(mapCtx.slice)
|
||||||
return kvs[i].key < kvs[j].key
|
buf := mapCtx.buf
|
||||||
})
|
for _, item := range mapCtx.slice.items {
|
||||||
buf := b[pos[0]:]
|
|
||||||
buf = buf[:0]
|
|
||||||
|
|
||||||
for _, kv := range kvs {
|
|
||||||
buf = append(buf, e.prefix...)
|
buf = append(buf, e.prefix...)
|
||||||
buf = append(buf, bytes.Repeat(e.indentStr, e.baseIndent+code.indent+1)...)
|
buf = append(buf, bytes.Repeat(e.indentStr, e.baseIndent+code.indent+1)...)
|
||||||
|
buf = append(buf, item.key...)
|
||||||
buf = append(buf, []byte(kv.key)...)
|
|
||||||
buf[len(buf)-2] = ':'
|
buf[len(buf)-2] = ':'
|
||||||
buf[len(buf)-1] = ' '
|
buf[len(buf)-1] = ' '
|
||||||
buf = append(buf, []byte(kv.value)...)
|
buf = append(buf, item.value...)
|
||||||
}
|
}
|
||||||
buf = buf[:len(buf)-2]
|
buf = buf[:len(buf)-2]
|
||||||
buf = append(buf, '\n')
|
buf = append(buf, '\n')
|
||||||
buf = append(buf, e.prefix...)
|
buf = append(buf, e.prefix...)
|
||||||
buf = append(buf, bytes.Repeat(e.indentStr, e.baseIndent+code.indent)...)
|
buf = append(buf, bytes.Repeat(e.indentStr, e.baseIndent+code.indent)...)
|
||||||
buf = append(buf, '}', ',', '\n')
|
buf = append(buf, '}', ',', '\n')
|
||||||
|
|
||||||
b = b[:pos[0]]
|
b = b[:pos[0]]
|
||||||
b = append(b, buf...)
|
b = append(b, buf...)
|
||||||
|
mapCtx.buf = buf
|
||||||
|
releaseMapContext(mapCtx)
|
||||||
code = code.next
|
code = code.next
|
||||||
case opStructFieldPtrHead:
|
case opStructFieldPtrHead:
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
|
|
|
@ -405,11 +405,10 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
|
||||||
store(ctxptr, code.mapIter, uintptr(iter))
|
store(ctxptr, code.mapIter, uintptr(iter))
|
||||||
|
|
||||||
if !e.unorderedMap {
|
if !e.unorderedMap {
|
||||||
pos := make([]int, 0, mlen)
|
mapCtx := newMapContext(mlen)
|
||||||
pos = append(pos, len(b))
|
mapCtx.pos = append(mapCtx.pos, len(b))
|
||||||
posPtr := unsafe.Pointer(&pos)
|
ctx.keepRefs = append(ctx.keepRefs, unsafe.Pointer(mapCtx))
|
||||||
ctx.keepRefs = append(ctx.keepRefs, posPtr)
|
store(ctxptr, code.end.mapPos, uintptr(unsafe.Pointer(mapCtx)))
|
||||||
store(ctxptr, code.end.mapPos, uintptr(posPtr))
|
|
||||||
} else {
|
} else {
|
||||||
b = e.encodeIndent(b, code.next.indent)
|
b = e.encodeIndent(b, code.next.indent)
|
||||||
}
|
}
|
||||||
|
@ -452,11 +451,10 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
|
||||||
store(ctxptr, code.next.idx, uintptr(key))
|
store(ctxptr, code.next.idx, uintptr(key))
|
||||||
|
|
||||||
if !e.unorderedMap {
|
if !e.unorderedMap {
|
||||||
pos := make([]int, 0, mlen)
|
mapCtx := newMapContext(mlen)
|
||||||
pos = append(pos, len(b))
|
mapCtx.pos = append(mapCtx.pos, len(b))
|
||||||
posPtr := unsafe.Pointer(&pos)
|
ctx.keepRefs = append(ctx.keepRefs, unsafe.Pointer(mapCtx))
|
||||||
ctx.keepRefs = append(ctx.keepRefs, posPtr)
|
store(ctxptr, code.end.mapPos, uintptr(unsafe.Pointer(mapCtx)))
|
||||||
store(ctxptr, code.end.mapPos, uintptr(posPtr))
|
|
||||||
} else {
|
} else {
|
||||||
b = e.encodeIndent(b, code.next.indent)
|
b = e.encodeIndent(b, code.next.indent)
|
||||||
}
|
}
|
||||||
|
@ -490,8 +488,8 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ptr := load(ctxptr, code.end.mapPos)
|
ptr := load(ctxptr, code.end.mapPos)
|
||||||
posPtr := (*[]int)(*(*unsafe.Pointer)(unsafe.Pointer(&ptr)))
|
mapCtx := (*encodeMapContext)(e.ptrToUnsafePtr(ptr))
|
||||||
*posPtr = append(*posPtr, len(b))
|
mapCtx.pos = append(mapCtx.pos, len(b))
|
||||||
if idx < length {
|
if idx < length {
|
||||||
ptr := load(ctxptr, code.mapIter)
|
ptr := load(ctxptr, code.mapIter)
|
||||||
iter := e.ptrToUnsafePtr(ptr)
|
iter := e.ptrToUnsafePtr(ptr)
|
||||||
|
@ -508,8 +506,8 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
|
||||||
b = append(b, ':', ' ')
|
b = append(b, ':', ' ')
|
||||||
} else {
|
} else {
|
||||||
ptr := load(ctxptr, code.end.mapPos)
|
ptr := load(ctxptr, code.end.mapPos)
|
||||||
posPtr := (*[]int)(*(*unsafe.Pointer)(unsafe.Pointer(&ptr)))
|
mapCtx := (*encodeMapContext)(e.ptrToUnsafePtr(ptr))
|
||||||
*posPtr = append(*posPtr, len(b))
|
mapCtx.pos = append(mapCtx.pos, len(b))
|
||||||
}
|
}
|
||||||
ptr := load(ctxptr, code.mapIter)
|
ptr := load(ctxptr, code.mapIter)
|
||||||
iter := e.ptrToUnsafePtr(ptr)
|
iter := e.ptrToUnsafePtr(ptr)
|
||||||
|
@ -520,13 +518,9 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
|
||||||
case opMapEnd:
|
case opMapEnd:
|
||||||
// this operation only used by sorted map
|
// this operation only used by sorted map
|
||||||
length := int(load(ctxptr, code.length))
|
length := int(load(ctxptr, code.length))
|
||||||
type mapKV struct {
|
|
||||||
key string
|
|
||||||
value string
|
|
||||||
}
|
|
||||||
kvs := make([]mapKV, 0, length)
|
|
||||||
ptr := load(ctxptr, code.mapPos)
|
ptr := load(ctxptr, code.mapPos)
|
||||||
pos := *(*[]int)(*(*unsafe.Pointer)(unsafe.Pointer(&ptr)))
|
mapCtx := (*encodeMapContext)(e.ptrToUnsafePtr(ptr))
|
||||||
|
pos := mapCtx.pos
|
||||||
for i := 0; i < length; i++ {
|
for i := 0; i < length; i++ {
|
||||||
startKey := pos[i*2]
|
startKey := pos[i*2]
|
||||||
startValue := pos[i*2+1]
|
startValue := pos[i*2+1]
|
||||||
|
@ -536,32 +530,31 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode
|
||||||
} else {
|
} else {
|
||||||
endValue = len(b)
|
endValue = len(b)
|
||||||
}
|
}
|
||||||
kvs = append(kvs, mapKV{
|
mapCtx.slice.items = append(mapCtx.slice.items, mapItem{
|
||||||
key: string(b[startKey:startValue]),
|
key: b[startKey:startValue],
|
||||||
value: string(b[startValue:endValue]),
|
value: b[startValue:endValue],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
sort.Slice(kvs, func(i, j int) bool {
|
sort.Sort(mapCtx.slice)
|
||||||
return kvs[i].key < kvs[j].key
|
buf := mapCtx.buf
|
||||||
})
|
for _, item := range mapCtx.slice.items {
|
||||||
buf := b[pos[0]:]
|
|
||||||
buf = buf[:0]
|
|
||||||
for _, kv := range kvs {
|
|
||||||
buf = append(buf, e.prefix...)
|
buf = append(buf, e.prefix...)
|
||||||
buf = append(buf, bytes.Repeat(e.indentStr, e.baseIndent+code.indent+1)...)
|
buf = append(buf, bytes.Repeat(e.indentStr, e.baseIndent+code.indent+1)...)
|
||||||
|
buf = append(buf, item.key...)
|
||||||
buf = append(buf, []byte(kv.key)...)
|
|
||||||
buf[len(buf)-2] = ':'
|
buf[len(buf)-2] = ':'
|
||||||
buf[len(buf)-1] = ' '
|
buf[len(buf)-1] = ' '
|
||||||
buf = append(buf, []byte(kv.value)...)
|
buf = append(buf, item.value...)
|
||||||
}
|
}
|
||||||
buf = buf[:len(buf)-2]
|
buf = buf[:len(buf)-2]
|
||||||
buf = append(buf, '\n')
|
buf = append(buf, '\n')
|
||||||
buf = append(buf, e.prefix...)
|
buf = append(buf, e.prefix...)
|
||||||
buf = append(buf, bytes.Repeat(e.indentStr, e.baseIndent+code.indent)...)
|
buf = append(buf, bytes.Repeat(e.indentStr, e.baseIndent+code.indent)...)
|
||||||
buf = append(buf, '}', ',', '\n')
|
buf = append(buf, '}', ',', '\n')
|
||||||
|
|
||||||
b = b[:pos[0]]
|
b = b[:pos[0]]
|
||||||
b = append(b, buf...)
|
b = append(b, buf...)
|
||||||
|
mapCtx.buf = buf
|
||||||
|
releaseMapContext(mapCtx)
|
||||||
code = code.next
|
code = code.next
|
||||||
case opStructFieldPtrHead:
|
case opStructFieldPtrHead:
|
||||||
p := load(ctxptr, code.idx)
|
p := load(ctxptr, code.idx)
|
||||||
|
|
Loading…
Reference in New Issue