forked from mirrors/tar-split
Optimize JSON decoding
This allows to avoid extra allocations on `ReadBytes` and decoding buffers. Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
parent
bece0c7009
commit
8b20f9161d
1 changed files with 5 additions and 23 deletions
|
@ -1,7 +1,6 @@
|
||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
@ -33,31 +32,15 @@ type PackUnpacker interface {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
type jsonUnpacker struct {
|
type jsonUnpacker struct {
|
||||||
r io.Reader
|
seen seenNames
|
||||||
b *bufio.Reader
|
dec *json.Decoder
|
||||||
isEOF bool
|
|
||||||
seen seenNames
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (jup *jsonUnpacker) Next() (*Entry, error) {
|
func (jup *jsonUnpacker) Next() (*Entry, error) {
|
||||||
var e Entry
|
var e Entry
|
||||||
if jup.isEOF {
|
err := jup.dec.Decode(&e)
|
||||||
// since ReadBytes() will return read bytes AND an EOF, we handle it this
|
if err != nil {
|
||||||
// round-a-bout way so we can Unmarshal the tail with relevant errors, but
|
|
||||||
// still get an io.EOF when the stream is ended.
|
|
||||||
return nil, io.EOF
|
|
||||||
}
|
|
||||||
line, err := jup.b.ReadBytes('\n')
|
|
||||||
if err != nil && err != io.EOF {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if err == io.EOF {
|
|
||||||
jup.isEOF = true
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(line, &e)
|
|
||||||
if err != nil && jup.isEOF {
|
|
||||||
// if the remainder actually _wasn't_ a remaining json structure, then just EOF
|
|
||||||
return nil, io.EOF
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for dup name
|
// check for dup name
|
||||||
|
@ -78,8 +61,7 @@ func (jup *jsonUnpacker) Next() (*Entry, error) {
|
||||||
// Each Entry read are expected to be delimited by new line.
|
// Each Entry read are expected to be delimited by new line.
|
||||||
func NewJSONUnpacker(r io.Reader) Unpacker {
|
func NewJSONUnpacker(r io.Reader) Unpacker {
|
||||||
return &jsonUnpacker{
|
return &jsonUnpacker{
|
||||||
r: r,
|
dec: json.NewDecoder(r),
|
||||||
b: bufio.NewReader(r),
|
|
||||||
seen: seenNames{},
|
seen: seenNames{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue