Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor to refmt #30

Merged
merged 24 commits into from
Sep 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9e7d558
feat: initial refactor to use refmt
dignifiedquire Nov 13, 2017
e14a4d9
fix copyObj
dignifiedquire Nov 13, 2017
1d048f4
no more panic todo
dignifiedquire Nov 13, 2017
3c65d0f
golint happy and some fixes
dignifiedquire Nov 13, 2017
5106752
more test cases
dignifiedquire Nov 13, 2017
699e7a0
fix examples tests using latest refmt
dignifiedquire Nov 16, 2017
4982e8a
use standard test script on travis
dignifiedquire Nov 17, 2017
e506e5e
cleanup code
dignifiedquire Nov 17, 2017
f9b953e
some cleanup
whyrusleeping Dec 11, 2017
e94e5a0
fix json input with cids
whyrusleeping Dec 12, 2017
eab8781
tests pass, but requires fix in refmt
whyrusleeping Dec 12, 2017
fcd1522
fix canonical struct encoding
whyrusleeping Dec 20, 2017
b29b7f4
fixes and updates
whyrusleeping Jan 12, 2018
573c793
update to latest cbor library syntax for sorting
dignifiedquire Jan 23, 2018
ff21104
cleanup errors and comments
dignifiedquire Jan 23, 2018
666b656
final import of refmt after fixes upstream
whyrusleeping Jan 24, 2018
31243bb
test: add failing test for nested structs
dignifiedquire Feb 19, 2018
782a191
update refmt
whyrusleeping Feb 21, 2018
679ed5f
share a pool of (un)marshallers
Stebalien Jul 17, 2018
cd13b8b
add a parallel benchmark
Stebalien Jul 17, 2018
ff48bd0
drop to NumCPU + 1 workers
Stebalien Jul 17, 2018
e5cb584
use a sync.Pool for the refmt (un)marshallers
Stebalien Jul 17, 2018
5896ec2
replace SetAtlas method with a constructor
Stebalien Jul 17, 2018
a1a7802
fix benchmarks
Stebalien Sep 7, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ sudo: false

language: go
go:
- 'tip'

install:
- go get github.com/whyrusleeping/gx
- go get github.com/whyrusleeping/gx-go
- gx install --global
- 1.9.x

before_install:
- make deps

script:
- gx test -v -race -coverprofile=coverage.txt -covermode=atomic .
- bash <(curl -s https://github.com/raw/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh)

after_success:
- bash <(curl -s https://codecov.io/bash)

Expand All @@ -20,5 +19,4 @@ cache:
- $GOPATH/src/gx

notifications:
email: false

email: false
33 changes: 33 additions & 0 deletions encoding/cloner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package encoding

import (
"sync"

refmt "github.com/polydawn/refmt"
"github.com/polydawn/refmt/obj/atlas"
)

// PooledCloner is a thread-safe pooled object cloner.
type PooledCloner struct {
pool sync.Pool
}

// NewPooledCloner returns a PooledCloner with the given atlas. Do not copy
// after use.
func NewPooledCloner(atl atlas.Atlas) PooledCloner {
return PooledCloner{
pool: sync.Pool{
New: func() interface{} {
return refmt.NewCloner(atl)
},
},
}
}

// Clone clones a into b using a cloner from the pool.
func (p *PooledCloner) Clone(a, b interface{}) error {
c := p.pool.Get().(refmt.Cloner)
err := c.Clone(a, b)
p.pool.Put(c)
return err
}
82 changes: 82 additions & 0 deletions encoding/marshaller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package encoding

import (
"bytes"
"io"
"sync"

cbor "github.com/polydawn/refmt/cbor"
"github.com/polydawn/refmt/obj/atlas"
)

type proxyWriter struct {
w io.Writer
}

func (w *proxyWriter) Write(b []byte) (int, error) {
return w.w.Write(b)
}

// Marshaller is a reusbale CBOR marshaller.
type Marshaller struct {
marshal *cbor.Marshaller
writer proxyWriter
}

// NewMarshallerAtlased constructs a new cbor Marshaller using the given atlas.
func NewMarshallerAtlased(atl atlas.Atlas) *Marshaller {
m := new(Marshaller)
m.marshal = cbor.NewMarshallerAtlased(&m.writer, atl)
return m
}

// Encode encodes the given object to the given writer.
func (m *Marshaller) Encode(obj interface{}, w io.Writer) error {
m.writer.w = w
err := m.marshal.Marshal(obj)
m.writer.w = nil
return err
}

// Marshal marshels the given object to a byte slice.
func (m *Marshaller) Marshal(obj interface{}) ([]byte, error) {
var buf bytes.Buffer
if err := m.Encode(obj, &buf); err != nil {
return nil, err
}
return buf.Bytes(), nil
}

// PooledMarshaller is a thread-safe pooled CBOR marshaller.
type PooledMarshaller struct {
pool sync.Pool
}

// NewPooledMarshaller returns a PooledMarshaller with the given atlas. Do not
// copy after use.
func NewPooledMarshaller(atl atlas.Atlas) PooledMarshaller {
return PooledMarshaller{
pool: sync.Pool{
New: func() interface{} {
return NewMarshallerAtlased(atl)
},
},
}
}

// Marshal marshals the passed object using the pool of marshallers.
func (p *PooledMarshaller) Marshal(obj interface{}) ([]byte, error) {
m := p.pool.Get().(*Marshaller)
bts, err := m.Marshal(obj)
p.pool.Put(m)
return bts, err
}

// Encode encodes the passed object to the given writer using the pool of
// marshallers.
func (p *PooledMarshaller) Encode(obj interface{}, w io.Writer) error {
m := p.pool.Get().(*Marshaller)
err := m.Encode(obj, w)
p.pool.Put(m)
return err
}
79 changes: 79 additions & 0 deletions encoding/unmarshaller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package encoding

import (
"bytes"
"io"
"sync"

cbor "github.com/polydawn/refmt/cbor"
"github.com/polydawn/refmt/obj/atlas"
)

type proxyReader struct {
r io.Reader
}

func (r *proxyReader) Read(b []byte) (int, error) {
return r.r.Read(b)
}

// Unmarshaller is a reusable CBOR unmarshaller.
type Unmarshaller struct {
unmarshal *cbor.Unmarshaller
reader proxyReader
}

// NewUnmarshallerAtlased creates a new reusable unmarshaller.
func NewUnmarshallerAtlased(atl atlas.Atlas) *Unmarshaller {
m := new(Unmarshaller)
m.unmarshal = cbor.NewUnmarshallerAtlased(&m.reader, atl)
return m
}

// Decode reads a CBOR object from the given reader and decodes it into the
// given object.
func (m *Unmarshaller) Decode(r io.Reader, obj interface{}) error {
m.reader.r = r
err := m.unmarshal.Unmarshal(obj)
m.reader.r = nil
return err
}

// Unmarshal unmarshals the given CBOR byte slice into the given object.
func (m *Unmarshaller) Unmarshal(b []byte, obj interface{}) error {
return m.Decode(bytes.NewReader(b), obj)
}

// PooledUnmarshaller is a thread-safe pooled CBOR unmarshaller.
type PooledUnmarshaller struct {
pool sync.Pool
}

// NewPooledUnmarshaller returns a PooledUnmarshaller with the given atlas. Do
// not copy after use.
func NewPooledUnmarshaller(atl atlas.Atlas) PooledUnmarshaller {
return PooledUnmarshaller{
pool: sync.Pool{
New: func() interface{} {
return NewUnmarshallerAtlased(atl)
},
},
}
}

// Decode decodes an object from the passed reader into the given object using
// the pool of unmarshallers.
func (p *PooledUnmarshaller) Decode(r io.Reader, obj interface{}) error {
u := p.pool.Get().(*Unmarshaller)
err := u.Decode(r, obj)
p.pool.Put(u)
return err
}

// Unmarshal unmarshals the passed object using the pool of unmarshallers.
func (p *PooledUnmarshaller) Unmarshal(b []byte, obj interface{}) error {
u := p.pool.Get().(*Unmarshaller)
err := u.Unmarshal(b, obj)
p.pool.Put(u)
return err
}
Loading