Avoid allocating memory in Type() method.
This commit is contained in:
13
cid.go
13
cid.go
@@ -159,7 +159,7 @@ func NewCidV1(codecType uint64, mhash mh.Multihash) Cid {
|
||||
// - version uvarint
|
||||
// - codec uvarint
|
||||
// - hash mh.Multihash
|
||||
type Cid struct{ string }
|
||||
type Cid struct{ str string }
|
||||
|
||||
var Nil = Cid{}
|
||||
|
||||
@@ -296,7 +296,7 @@ func Cast(data []byte) (Cid, error) {
|
||||
|
||||
// Version returns the Cid version.
|
||||
func (c Cid) Version() uint64 {
|
||||
if len(c.string) == 34 && c.string[0] == 18 && c.string[1] == 32 {
|
||||
if len(c.str) == 34 && c.str[0] == 18 && c.str[1] == 32 {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
@@ -307,9 +307,8 @@ func (c Cid) Type() uint64 {
|
||||
if c.Version() == 0 {
|
||||
return DagProtobuf
|
||||
}
|
||||
bytes := c.Bytes()
|
||||
_, n := binary.Uvarint(bytes)
|
||||
codec, _ := binary.Uvarint(bytes[n:])
|
||||
_, n := uvarint(c.str)
|
||||
codec, _ := uvarint(c.str[n:])
|
||||
return codec
|
||||
}
|
||||
|
||||
@@ -382,7 +381,7 @@ func (c Cid) Hash() mh.Multihash {
|
||||
// The output of bytes can be parsed back into a Cid
|
||||
// with Cast().
|
||||
func (c Cid) Bytes() []byte {
|
||||
return []byte(c.string)
|
||||
return []byte(c.str)
|
||||
}
|
||||
|
||||
// Equals checks that two Cids are the same.
|
||||
@@ -431,7 +430,7 @@ func (c Cid) MarshalJSON() ([]byte, error) {
|
||||
|
||||
// KeyString returns the binary representation of the Cid as a string
|
||||
func (c Cid) KeyString() string {
|
||||
return c.string
|
||||
return c.str
|
||||
}
|
||||
|
||||
// Loggable returns a Loggable (as defined by
|
||||
|
||||
34
varint.go
Normal file
34
varint.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package cid
|
||||
|
||||
// Version of varint function that work with a string rather than
|
||||
// []byte to avoid unnecessary allocation
|
||||
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license as given at https://golang.org/LICENSE
|
||||
|
||||
// uvarint decodes a uint64 from buf and returns that value and the
|
||||
// number of characters read (> 0). If an error occurred, the value is 0
|
||||
// and the number of bytes n is <= 0 meaning:
|
||||
//
|
||||
// n == 0: buf too small
|
||||
// n < 0: value larger than 64 bits (overflow)
|
||||
// and -n is the number of bytes read
|
||||
//
|
||||
func uvarint(buf string) (uint64, int) {
|
||||
var x uint64
|
||||
var s uint
|
||||
// we have a binary string so we can't use a range loope
|
||||
for i := 0; i < len(buf); i++ {
|
||||
b := buf[i]
|
||||
if b < 0x80 {
|
||||
if i > 9 || i == 9 && b > 1 {
|
||||
return 0, -(i + 1) // overflow
|
||||
}
|
||||
return x | uint64(b)<<s, i + 1
|
||||
}
|
||||
x |= uint64(b&0x7f) << s
|
||||
s += 7
|
||||
}
|
||||
return 0, 0
|
||||
}
|
||||
22
varint_test.go
Normal file
22
varint_test.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package cid
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUvarintRoundTrip(t *testing.T) {
|
||||
testCases := []uint64{0, 1, 2, 127, 128, 129, 255, 256, 257, 1<<63 - 1}
|
||||
for _, tc := range testCases {
|
||||
buf := make([]byte, 16)
|
||||
binary.PutUvarint(buf, tc)
|
||||
v, l1 := uvarint(string(buf))
|
||||
_, l2 := binary.Uvarint(buf)
|
||||
if tc != v {
|
||||
t.Errorf("roundtrip failed expected %d but got %d", tc, v)
|
||||
}
|
||||
if l1 != l2 {
|
||||
t.Errorf("length incorrect expected %d but got %d", l2, l1)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user