Skip to content

Commit ff83ea4

Browse files
committed
perf: iterative nextValueOffset in DataDecoder
1 parent f486632 commit ff83ea4

File tree

1 file changed

+26
-18
lines changed

1 file changed

+26
-18
lines changed

internal/decoder/data_decoder.go

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -424,28 +424,36 @@ func (d *DataDecoder) decodeKey(offset uint) ([]byte, uint, error) {
424424
// the one at the offset passed in. The size bits have different meanings for
425425
// different data types.
426426
func (d *DataDecoder) nextValueOffset(offset, numberToSkip uint) (uint, error) {
427-
if numberToSkip == 0 {
428-
return offset, nil
429-
}
430-
kindNum, size, offset, err := d.decodeCtrlData(offset)
431-
if err != nil {
432-
return 0, err
433-
}
434-
switch kindNum {
435-
case KindPointer:
436-
_, offset, err = d.decodePointer(size, offset)
427+
for numberToSkip > 0 {
428+
kindNum, size, newOffset, err := d.decodeCtrlData(offset)
437429
if err != nil {
438430
return 0, err
439431
}
440-
case KindMap:
441-
numberToSkip += 2 * size
442-
case KindSlice:
443-
numberToSkip += size
444-
case KindBool:
445-
default:
446-
offset += size
432+
433+
switch kindNum {
434+
case KindPointer:
435+
// A pointer value is represented by its pointer token only.
436+
// To skip it, just move past the pointer bytes; do NOT follow
437+
// the pointer target here.
438+
_, ptrEndOffset, err2 := d.decodePointer(size, newOffset)
439+
if err2 != nil {
440+
return 0, err2
441+
}
442+
newOffset = ptrEndOffset
443+
case KindMap:
444+
numberToSkip += 2 * size
445+
case KindSlice:
446+
numberToSkip += size
447+
case KindBool:
448+
// size encodes the boolean; nothing else to skip
449+
default:
450+
newOffset += size
451+
}
452+
453+
offset = newOffset
454+
numberToSkip--
447455
}
448-
return d.nextValueOffset(offset, numberToSkip-1)
456+
return offset, nil
449457
}
450458

451459
func (d *DataDecoder) sizeFromCtrlByte(

0 commit comments

Comments
 (0)